1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16#include "CoroutineStmtBuilder.h"
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/ExprConcepts.h"
24#include "clang/AST/ExprObjC.h"
25#include "clang/AST/ExprOpenMP.h"
26#include "clang/AST/OpenMPClause.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
30#include "clang/AST/StmtOpenACC.h"
31#include "clang/AST/StmtOpenMP.h"
32#include "clang/AST/StmtSYCL.h"
33#include "clang/Basic/DiagnosticParse.h"
34#include "clang/Basic/OpenMPKinds.h"
35#include "clang/Sema/Designator.h"
36#include "clang/Sema/EnterExpressionEvaluationContext.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Ownership.h"
39#include "clang/Sema/ParsedTemplate.h"
40#include "clang/Sema/ScopeInfo.h"
41#include "clang/Sema/SemaDiagnostic.h"
42#include "clang/Sema/SemaHLSL.h"
43#include "clang/Sema/SemaInternal.h"
44#include "clang/Sema/SemaObjC.h"
45#include "clang/Sema/SemaOpenACC.h"
46#include "clang/Sema/SemaOpenMP.h"
47#include "clang/Sema/SemaPseudoObject.h"
48#include "clang/Sema/SemaSYCL.h"
49#include "clang/Sema/Template.h"
50#include "llvm/ADT/ArrayRef.h"
51#include "llvm/Support/ErrorHandling.h"
52#include <algorithm>
53#include <optional>
54
55using namespace llvm::omp;
56
57namespace clang {
58using namespace sema;
59
60// This helper class is used to facilitate pack expansion during tree transform.
61struct UnexpandedInfo {
62 SourceLocation Ellipsis;
63 UnsignedOrNone OrigNumExpansions = std::nullopt;
64
65 bool Expand = false;
66 bool RetainExpansion = false;
67 UnsignedOrNone NumExpansions = std::nullopt;
68 bool ExpandUnderForgetSubstitions = false;
69};
70
71/// A semantic tree transformation that allows one to transform one
72/// abstract syntax tree into another.
73///
74/// A new tree transformation is defined by creating a new subclass \c X of
75/// \c TreeTransform<X> and then overriding certain operations to provide
76/// behavior specific to that transformation. For example, template
77/// instantiation is implemented as a tree transformation where the
78/// transformation of TemplateTypeParmType nodes involves substituting the
79/// template arguments for their corresponding template parameters; a similar
80/// transformation is performed for non-type template parameters and
81/// template template parameters.
82///
83/// This tree-transformation template uses static polymorphism to allow
84/// subclasses to customize any of its operations. Thus, a subclass can
85/// override any of the transformation or rebuild operators by providing an
86/// operation with the same signature as the default implementation. The
87/// overriding function should not be virtual.
88///
89/// Semantic tree transformations are split into two stages, either of which
90/// can be replaced by a subclass. The "transform" step transforms an AST node
91/// or the parts of an AST node using the various transformation functions,
92/// then passes the pieces on to the "rebuild" step, which constructs a new AST
93/// node of the appropriate kind from the pieces. The default transformation
94/// routines recursively transform the operands to composite AST nodes (e.g.,
95/// the pointee type of a PointerType node) and, if any of those operand nodes
96/// were changed by the transformation, invokes the rebuild operation to create
97/// a new AST node.
98///
99/// Subclasses can customize the transformation at various levels. The
100/// most coarse-grained transformations involve replacing TransformType(),
101/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
102/// TransformTemplateName(), or TransformTemplateArgument() with entirely
103/// new implementations.
104///
105/// For more fine-grained transformations, subclasses can replace any of the
106/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
107/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
108/// replacing TransformTemplateTypeParmType() allows template instantiation
109/// to substitute template arguments for their corresponding template
110/// parameters. Additionally, subclasses can override the \c RebuildXXX
111/// functions to control how AST nodes are rebuilt when their operands change.
112/// By default, \c TreeTransform will invoke semantic analysis to rebuild
113/// AST nodes. However, certain other tree transformations (e.g, cloning) may
114/// be able to use more efficient rebuild steps.
115///
116/// There are a handful of other functions that can be overridden, allowing one
117/// to avoid traversing nodes that don't need any transformation
118/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
119/// operands have not changed (\c AlwaysRebuild()), and customize the
120/// default locations and entity names used for type-checking
121/// (\c getBaseLocation(), \c getBaseEntity()).
122template<typename Derived>
123class TreeTransform {
124 /// Private RAII object that helps us forget and then re-remember
125 /// the template argument corresponding to a partially-substituted parameter
126 /// pack.
127 class ForgetPartiallySubstitutedPackRAII {
128 Derived &Self;
129 TemplateArgument Old;
130 // Set the pack expansion index to -1 to avoid pack substitution and
131 // indicate that parameter packs should be instantiated as themselves.
132 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
133
134 public:
135 ForgetPartiallySubstitutedPackRAII(Derived &Self)
136 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
137 Old = Self.ForgetPartiallySubstitutedPack();
138 }
139
140 ~ForgetPartiallySubstitutedPackRAII() {
141 Self.RememberPartiallySubstitutedPack(Old);
142 }
143 ForgetPartiallySubstitutedPackRAII(
144 const ForgetPartiallySubstitutedPackRAII &) = delete;
145 ForgetPartiallySubstitutedPackRAII &
146 operator=(const ForgetPartiallySubstitutedPackRAII &) = delete;
147 };
148
149protected:
150 Sema &SemaRef;
151
152 /// The set of local declarations that have been transformed, for
153 /// cases where we are forced to build new declarations within the transformer
154 /// rather than in the subclass (e.g., lambda closure types).
155 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
156
157public:
158 /// Initializes a new tree transformer.
159 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
160
161 /// Retrieves a reference to the derived class.
162 Derived &getDerived() { return static_cast<Derived&>(*this); }
163
164 /// Retrieves a reference to the derived class.
165 const Derived &getDerived() const {
166 return static_cast<const Derived&>(*this);
167 }
168
169 static inline ExprResult Owned(Expr *E) { return E; }
170 static inline StmtResult Owned(Stmt *S) { return S; }
171
172 /// Retrieves a reference to the semantic analysis object used for
173 /// this tree transform.
174 Sema &getSema() const { return SemaRef; }
175
176 /// Whether the transformation should always rebuild AST nodes, even
177 /// if none of the children have changed.
178 ///
179 /// Subclasses may override this function to specify when the transformation
180 /// should rebuild all AST nodes.
181 ///
182 /// We must always rebuild all AST nodes when performing variadic template
183 /// pack expansion, in order to avoid violating the AST invariant that each
184 /// statement node appears at most once in its containing declaration.
185 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
186
187 /// Whether the transformation is forming an expression or statement that
188 /// replaces the original. In this case, we'll reuse mangling numbers from
189 /// existing lambdas.
190 bool ReplacingOriginal() { return false; }
191
192 /// Wether CXXConstructExpr can be skipped when they are implicit.
193 /// They will be reconstructed when used if needed.
194 /// This is useful when the user that cause rebuilding of the
195 /// CXXConstructExpr is outside of the expression at which the TreeTransform
196 /// started.
197 bool AllowSkippingCXXConstructExpr() { return true; }
198
199 /// Returns the location of the entity being transformed, if that
200 /// information was not available elsewhere in the AST.
201 ///
202 /// By default, returns no source-location information. Subclasses can
203 /// provide an alternative implementation that provides better location
204 /// information.
205 SourceLocation getBaseLocation() { return SourceLocation(); }
206
207 /// Returns the name of the entity being transformed, if that
208 /// information was not available elsewhere in the AST.
209 ///
210 /// By default, returns an empty name. Subclasses can provide an alternative
211 /// implementation with a more precise name.
212 DeclarationName getBaseEntity() { return DeclarationName(); }
213
214 /// Sets the "base" location and entity when that
215 /// information is known based on another transformation.
216 ///
217 /// By default, the source location and entity are ignored. Subclasses can
218 /// override this function to provide a customized implementation.
219 void setBase(SourceLocation Loc, DeclarationName Entity) { }
220
221 /// RAII object that temporarily sets the base location and entity
222 /// used for reporting diagnostics in types.
223 class TemporaryBase {
224 TreeTransform &Self;
225 SourceLocation OldLocation;
226 DeclarationName OldEntity;
227
228 public:
229 TemporaryBase(TreeTransform &Self, SourceLocation Location,
230 DeclarationName Entity) : Self(Self) {
231 OldLocation = Self.getDerived().getBaseLocation();
232 OldEntity = Self.getDerived().getBaseEntity();
233
234 if (Location.isValid())
235 Self.getDerived().setBase(Location, Entity);
236 }
237
238 ~TemporaryBase() {
239 Self.getDerived().setBase(OldLocation, OldEntity);
240 }
241 TemporaryBase(const TemporaryBase &) = delete;
242 TemporaryBase &operator=(const TemporaryBase &) = delete;
243 };
244
245 /// Determine whether the given type \p T has already been
246 /// transformed.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine
249 /// to short-circuit evaluation when it is known that a given type will
250 /// not change. For example, template instantiation need not traverse
251 /// non-dependent types.
252 bool AlreadyTransformed(QualType T) {
253 return T.isNull();
254 }
255
256 /// Transform a template parameter depth level.
257 ///
258 /// During a transformation that transforms template parameters, this maps
259 /// an old template parameter depth to a new depth.
260 unsigned TransformTemplateDepth(unsigned Depth) {
261 return Depth;
262 }
263
264 /// Determine whether the given call argument should be dropped, e.g.,
265 /// because it is a default argument.
266 ///
267 /// Subclasses can provide an alternative implementation of this routine to
268 /// determine which kinds of call arguments get dropped. By default,
269 /// CXXDefaultArgument nodes are dropped (prior to transformation).
270 bool DropCallArgument(Expr *E) {
271 return E->isDefaultArgument();
272 }
273
274 /// Determine whether we should expand a pack expansion with the
275 /// given set of parameter packs into separate arguments by repeatedly
276 /// transforming the pattern.
277 ///
278 /// By default, the transformer never tries to expand pack expansions.
279 /// Subclasses can override this routine to provide different behavior.
280 ///
281 /// \param EllipsisLoc The location of the ellipsis that identifies the
282 /// pack expansion.
283 ///
284 /// \param PatternRange The source range that covers the entire pattern of
285 /// the pack expansion.
286 ///
287 /// \param Unexpanded The set of unexpanded parameter packs within the
288 /// pattern.
289 ///
290 /// \param ShouldExpand Will be set to \c true if the transformer should
291 /// expand the corresponding pack expansions into separate arguments. When
292 /// set, \c NumExpansions must also be set.
293 ///
294 /// \param RetainExpansion Whether the caller should add an unexpanded
295 /// pack expansion after all of the expanded arguments. This is used
296 /// when extending explicitly-specified template argument packs per
297 /// C++0x [temp.arg.explicit]p9.
298 ///
299 /// \param NumExpansions The number of separate arguments that will be in
300 /// the expanded form of the corresponding pack expansion. This is both an
301 /// input and an output parameter, which can be set by the caller if the
302 /// number of expansions is known a priori (e.g., due to a prior substitution)
303 /// and will be set by the callee when the number of expansions is known.
304 /// The callee must set this value when \c ShouldExpand is \c true; it may
305 /// set this value in other cases.
306 ///
307 /// \returns true if an error occurred (e.g., because the parameter packs
308 /// are to be instantiated with arguments of different lengths), false
309 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
310 /// must be set.
311 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
312 SourceRange PatternRange,
313 ArrayRef<UnexpandedParameterPack> Unexpanded,
314 bool FailOnPackProducingTemplates,
315 bool &ShouldExpand, bool &RetainExpansion,
316 UnsignedOrNone &NumExpansions) {
317 ShouldExpand = false;
318 return false;
319 }
320
321 /// "Forget" about the partially-substituted pack template argument,
322 /// when performing an instantiation that must preserve the parameter pack
323 /// use.
324 ///
325 /// This routine is meant to be overridden by the template instantiator.
326 TemplateArgument ForgetPartiallySubstitutedPack() {
327 return TemplateArgument();
328 }
329
330 /// "Remember" the partially-substituted pack template argument
331 /// after performing an instantiation that must preserve the parameter pack
332 /// use.
333 ///
334 /// This routine is meant to be overridden by the template instantiator.
335 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
336
337 /// "Forget" the template substitution to allow transforming the AST without
338 /// any template instantiations. This is used to expand template packs when
339 /// their size is not known in advance (e.g. for builtins that produce type
340 /// packs).
341 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
342 void RememberSubstitution(MultiLevelTemplateArgumentList) {}
343
344private:
345 struct ForgetSubstitutionRAII {
346 Derived &Self;
347 MultiLevelTemplateArgumentList Old;
348
349 public:
350 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
351 Old = Self.ForgetSubstitution();
352 }
353
354 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
355 };
356
357public:
358 /// Note to the derived class when a function parameter pack is
359 /// being expanded.
360 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
361
362 /// Transforms the given type into another type.
363 ///
364 /// By default, this routine transforms a type by creating a
365 /// TypeSourceInfo for it and delegating to the appropriate
366 /// function. This is expensive, but we don't mind, because
367 /// this method is deprecated anyway; all users should be
368 /// switched to storing TypeSourceInfos.
369 ///
370 /// \returns the transformed type.
371 QualType TransformType(QualType T);
372
373 /// Transforms the given type-with-location into a new
374 /// type-with-location.
375 ///
376 /// By default, this routine transforms a type by delegating to the
377 /// appropriate TransformXXXType to build a new type. Subclasses
378 /// may override this function (to take over all type
379 /// transformations) or some set of the TransformXXXType functions
380 /// to alter the transformation.
381 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);
382
383 /// Transform the given type-with-location into a new
384 /// type, collecting location information in the given builder
385 /// as necessary.
386 ///
387 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
388
389 /// Transform a type that is permitted to produce a
390 /// DeducedTemplateSpecializationType.
391 ///
392 /// This is used in the (relatively rare) contexts where it is acceptable
393 /// for transformation to produce a class template type with deduced
394 /// template arguments.
395 /// @{
396 QualType TransformTypeWithDeducedTST(QualType T);
397 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);
398 /// @}
399
400 /// The reason why the value of a statement is not discarded, if any.
401 enum class StmtDiscardKind {
402 Discarded,
403 NotDiscarded,
404 StmtExprResult,
405 };
406
407 /// Transform the given statement.
408 ///
409 /// By default, this routine transforms a statement by delegating to the
410 /// appropriate TransformXXXStmt function to transform a specific kind of
411 /// statement or the TransformExpr() function to transform an expression.
412 /// Subclasses may override this function to transform statements using some
413 /// other mechanism.
414 ///
415 /// \returns the transformed statement.
416 StmtResult TransformStmt(Stmt *S,
417 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
418
419 /// Transform the given statement.
420 ///
421 /// By default, this routine transforms a statement by delegating to the
422 /// appropriate TransformOMPXXXClause function to transform a specific kind
423 /// of clause. Subclasses may override this function to transform statements
424 /// using some other mechanism.
425 ///
426 /// \returns the transformed OpenMP clause.
427 OMPClause *TransformOMPClause(OMPClause *S);
428
429 /// Transform the given attribute.
430 ///
431 /// By default, this routine transforms a statement by delegating to the
432 /// appropriate TransformXXXAttr function to transform a specific kind
433 /// of attribute. Subclasses may override this function to transform
434 /// attributed statements/types using some other mechanism.
435 ///
436 /// \returns the transformed attribute
437 const Attr *TransformAttr(const Attr *S);
438
439 // Transform the given statement attribute.
440 //
441 // Delegates to the appropriate TransformXXXAttr function to transform a
442 // specific kind of statement attribute. Unlike the non-statement taking
443 // version of this, this implements all attributes, not just pragmas.
444 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
445 const Attr *A);
446
447 // Transform the specified attribute.
448 //
449 // Subclasses should override the transformation of attributes with a pragma
450 // spelling to transform expressions stored within the attribute.
451 //
452 // \returns the transformed attribute.
453#define ATTR(X) \
454 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
455#include "clang/Basic/AttrList.inc"
456
457 // Transform the specified attribute.
458 //
459 // Subclasses should override the transformation of attributes to do
460 // transformation and checking of statement attributes. By default, this
461 // delegates to the non-statement taking version.
462 //
463 // \returns the transformed attribute.
464#define ATTR(X) \
465 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
466 const X##Attr *A) { \
467 return getDerived().Transform##X##Attr(A); \
468 }
469#include "clang/Basic/AttrList.inc"
470
471 /// Transform the given expression.
472 ///
473 /// By default, this routine transforms an expression by delegating to the
474 /// appropriate TransformXXXExpr function to build a new expression.
475 /// Subclasses may override this function to transform expressions using some
476 /// other mechanism.
477 ///
478 /// \returns the transformed expression.
479 ExprResult TransformExpr(Expr *E);
480
481 /// Transform the given initializer.
482 ///
483 /// By default, this routine transforms an initializer by stripping off the
484 /// semantic nodes added by initialization, then passing the result to
485 /// TransformExpr or TransformExprs.
486 ///
487 /// \returns the transformed initializer.
488 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
489
490 /// Transform the given list of expressions.
491 ///
492 /// This routine transforms a list of expressions by invoking
493 /// \c TransformExpr() for each subexpression. However, it also provides
494 /// support for variadic templates by expanding any pack expansions (if the
495 /// derived class permits such expansion) along the way. When pack expansions
496 /// are present, the number of outputs may not equal the number of inputs.
497 ///
498 /// \param Inputs The set of expressions to be transformed.
499 ///
500 /// \param NumInputs The number of expressions in \c Inputs.
501 ///
502 /// \param IsCall If \c true, then this transform is being performed on
503 /// function-call arguments, and any arguments that should be dropped, will
504 /// be.
505 ///
506 /// \param Outputs The transformed input expressions will be added to this
507 /// vector.
508 ///
509 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
510 /// due to transformation.
511 ///
512 /// \returns true if an error occurred, false otherwise.
513 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
514 SmallVectorImpl<Expr *> &Outputs,
515 bool *ArgChanged = nullptr);
516
517 /// Transform the given declaration, which is referenced from a type
518 /// or expression.
519 ///
520 /// By default, acts as the identity function on declarations, unless the
521 /// transformer has had to transform the declaration itself. Subclasses
522 /// may override this function to provide alternate behavior.
523 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
524 llvm::DenseMap<Decl *, Decl *>::iterator Known
525 = TransformedLocalDecls.find(Val: D);
526 if (Known != TransformedLocalDecls.end())
527 return Known->second;
528
529 return D;
530 }
531
532 /// Transform the specified condition.
533 ///
534 /// By default, this transforms the variable and expression and rebuilds
535 /// the condition.
536 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
537 Expr *Expr,
538 Sema::ConditionKind Kind);
539
540 /// Transform the attributes associated with the given declaration and
541 /// place them on the new declaration.
542 ///
543 /// By default, this operation does nothing. Subclasses may override this
544 /// behavior to transform attributes.
545 void transformAttrs(Decl *Old, Decl *New) { }
546
547 /// Note that a local declaration has been transformed by this
548 /// transformer.
549 ///
550 /// Local declarations are typically transformed via a call to
551 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
552 /// the transformer itself has to transform the declarations. This routine
553 /// can be overridden by a subclass that keeps track of such mappings.
554 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
555 assert(New.size() == 1 &&
556 "must override transformedLocalDecl if performing pack expansion");
557 TransformedLocalDecls[Old] = New.front();
558 }
559
560 /// Transform the definition of the given declaration.
561 ///
562 /// By default, invokes TransformDecl() to transform the declaration.
563 /// Subclasses may override this function to provide alternate behavior.
564 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
565 return getDerived().TransformDecl(Loc, D);
566 }
567
568 /// Transform the given declaration, which was the first part of a
569 /// nested-name-specifier in a member access expression.
570 ///
571 /// This specific declaration transformation only applies to the first
572 /// identifier in a nested-name-specifier of a member access expression, e.g.,
573 /// the \c T in \c x->T::member
574 ///
575 /// By default, invokes TransformDecl() to transform the declaration.
576 /// Subclasses may override this function to provide alternate behavior.
577 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
578 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
579 }
580
581 /// Transform the set of declarations in an OverloadExpr.
582 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
583 LookupResult &R);
584
585 /// Transform the given nested-name-specifier with source-location
586 /// information.
587 ///
588 /// By default, transforms all of the types and declarations within the
589 /// nested-name-specifier. Subclasses may override this function to provide
590 /// alternate behavior.
591 NestedNameSpecifierLoc
592 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
593 QualType ObjectType = QualType(),
594 NamedDecl *FirstQualifierInScope = nullptr);
595
596 /// Transform the given declaration name.
597 ///
598 /// By default, transforms the types of conversion function, constructor,
599 /// and destructor names and then (if needed) rebuilds the declaration name.
600 /// Identifiers and selectors are returned unmodified. Subclasses may
601 /// override this function to provide alternate behavior.
602 DeclarationNameInfo
603 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
604
605 bool TransformRequiresExprRequirements(
606 ArrayRef<concepts::Requirement *> Reqs,
607 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
608 concepts::TypeRequirement *
609 TransformTypeRequirement(concepts::TypeRequirement *Req);
610 concepts::ExprRequirement *
611 TransformExprRequirement(concepts::ExprRequirement *Req);
612 concepts::NestedRequirement *
613 TransformNestedRequirement(concepts::NestedRequirement *Req);
614
615 /// Transform the given template name.
616 ///
617 /// \param SS The nested-name-specifier that qualifies the template
618 /// name. This nested-name-specifier must already have been transformed.
619 ///
620 /// \param Name The template name to transform.
621 ///
622 /// \param NameLoc The source location of the template name.
623 ///
624 /// \param ObjectType If we're translating a template name within a member
625 /// access expression, this is the type of the object whose member template
626 /// is being referenced.
627 ///
628 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
629 /// also refers to a name within the current (lexical) scope, this is the
630 /// declaration it refers to.
631 ///
632 /// By default, transforms the template name by transforming the declarations
633 /// and nested-name-specifiers that occur within the template name.
634 /// Subclasses may override this function to provide alternate behavior.
635 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
636 SourceLocation TemplateKWLoc,
637 TemplateName Name, SourceLocation NameLoc,
638 QualType ObjectType = QualType(),
639 NamedDecl *FirstQualifierInScope = nullptr,
640 bool AllowInjectedClassName = false);
641
642 TemplateName TransformConceptTemplateName(TemplateName Name,
643 SourceLocation NameLoc);
644
645 /// Transform the given template argument.
646 ///
647 /// By default, this operation transforms the type, expression, or
648 /// declaration stored within the template argument and constructs a
649 /// new template argument from the transformed result. Subclasses may
650 /// override this function to provide alternate behavior.
651 ///
652 /// Returns true if there was an error.
653 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
654 TemplateArgumentLoc &Output,
655 bool Uneval = false);
656
657 TemplateArgument TransformNamedTemplateTemplateArgument(
658 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
659 TemplateName Name, SourceLocation NameLoc);
660
661 /// Transform the given set of template arguments.
662 ///
663 /// By default, this operation transforms all of the template arguments
664 /// in the input set using \c TransformTemplateArgument(), and appends
665 /// the transformed arguments to the output list.
666 ///
667 /// Note that this overload of \c TransformTemplateArguments() is merely
668 /// a convenience function. Subclasses that wish to override this behavior
669 /// should override the iterator-based member template version.
670 ///
671 /// \param Inputs The set of template arguments to be transformed.
672 ///
673 /// \param NumInputs The number of template arguments in \p Inputs.
674 ///
675 /// \param Outputs The set of transformed template arguments output by this
676 /// routine.
677 ///
678 /// Returns true if an error occurred.
679 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
680 unsigned NumInputs,
681 TemplateArgumentListInfo &Outputs,
682 bool Uneval = false) {
683 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
684 Uneval);
685 }
686
687 /// Transform the given set of template arguments.
688 ///
689 /// By default, this operation transforms all of the template arguments
690 /// in the input set using \c TransformTemplateArgument(), and appends
691 /// the transformed arguments to the output list.
692 ///
693 /// \param First An iterator to the first template argument.
694 ///
695 /// \param Last An iterator one step past the last template argument.
696 ///
697 /// \param Outputs The set of transformed template arguments output by this
698 /// routine.
699 ///
700 /// Returns true if an error occurred.
701 template<typename InputIterator>
702 bool TransformTemplateArguments(InputIterator First,
703 InputIterator Last,
704 TemplateArgumentListInfo &Outputs,
705 bool Uneval = false);
706
707 template <typename InputIterator>
708 bool TransformConceptTemplateArguments(InputIterator First,
709 InputIterator Last,
710 TemplateArgumentListInfo &Outputs,
711 bool Uneval = false);
712
713 /// Checks if the argument pack from \p In will need to be expanded and does
714 /// the necessary prework.
715 /// Whether the expansion is needed is captured in Info.Expand.
716 ///
717 /// - When the expansion is required, \p Out will be a template pattern that
718 /// would need to be expanded.
719 /// - When the expansion must not happen, \p Out will be a pack that must be
720 /// returned to the outputs directly.
721 ///
722 /// \return true iff the error occurred
723 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
724 TemplateArgumentLoc &Out, UnexpandedInfo &Info);
725
726 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
727 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
728 TemplateArgumentLoc &ArgLoc);
729
730 /// Fakes up a TypeSourceInfo for a type.
731 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
732 return SemaRef.Context.getTrivialTypeSourceInfo(T,
733 Loc: getDerived().getBaseLocation());
734 }
735
736#define ABSTRACT_TYPELOC(CLASS, PARENT)
737#define TYPELOC(CLASS, PARENT) \
738 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
739#include "clang/AST/TypeLocNodes.def"
740
741 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
742 TemplateTypeParmTypeLoc TL,
743 bool SuppressObjCLifetime);
744 QualType
745 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
746 SubstTemplateTypeParmPackTypeLoc TL,
747 bool SuppressObjCLifetime);
748
749 template<typename Fn>
750 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
751 FunctionProtoTypeLoc TL,
752 CXXRecordDecl *ThisContext,
753 Qualifiers ThisTypeQuals,
754 Fn TransformExceptionSpec);
755
756 bool TransformExceptionSpec(SourceLocation Loc,
757 FunctionProtoType::ExceptionSpecInfo &ESI,
758 SmallVectorImpl<QualType> &Exceptions,
759 bool &Changed);
760
761 StmtResult TransformSEHHandler(Stmt *Handler);
762
763 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
764 TemplateSpecializationTypeLoc TL,
765 QualType ObjectType,
766 NamedDecl *FirstQualifierInScope,
767 bool AllowInjectedClassName);
768
769 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
770
771 /// Transforms the parameters of a function type into the
772 /// given vectors.
773 ///
774 /// The result vectors should be kept in sync; null entries in the
775 /// variables vector are acceptable.
776 ///
777 /// LastParamTransformed, if non-null, will be set to the index of the last
778 /// parameter on which transformation was started. In the event of an error,
779 /// this will contain the parameter which failed to instantiate.
780 ///
781 /// Return true on error.
782 bool TransformFunctionTypeParams(
783 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
784 const QualType *ParamTypes,
785 const FunctionProtoType::ExtParameterInfo *ParamInfos,
786 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
787 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
788
789 bool TransformFunctionTypeParams(
790 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
791 const QualType *ParamTypes,
792 const FunctionProtoType::ExtParameterInfo *ParamInfos,
793 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
794 Sema::ExtParameterInfoBuilder &PInfos) {
795 return getDerived().TransformFunctionTypeParams(
796 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
797 }
798
799 /// Transforms the parameters of a requires expresison into the given vectors.
800 ///
801 /// The result vectors should be kept in sync; null entries in the
802 /// variables vector are acceptable.
803 ///
804 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
805 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
806 /// which are cases where transformation shouldn't continue.
807 ExprResult TransformRequiresTypeParams(
808 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
809 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
810 SmallVectorImpl<QualType> &PTypes,
811 SmallVectorImpl<ParmVarDecl *> &TransParams,
812 Sema::ExtParameterInfoBuilder &PInfos) {
813 if (getDerived().TransformFunctionTypeParams(
814 KWLoc, Params, /*ParamTypes=*/nullptr,
815 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
816 return ExprError();
817
818 return ExprResult{};
819 }
820
821 /// Transforms a single function-type parameter. Return null
822 /// on error.
823 ///
824 /// \param indexAdjustment - A number to add to the parameter's
825 /// scope index; can be negative
826 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
827 int indexAdjustment,
828 UnsignedOrNone NumExpansions,
829 bool ExpectParameterPack);
830
831 /// Transform the body of a lambda-expression.
832 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
833 /// Alternative implementation of TransformLambdaBody that skips transforming
834 /// the body.
835 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
836
837 CXXRecordDecl::LambdaDependencyKind
838 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
839 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
840 LSI->Lambda->getLambdaDependencyKind());
841 }
842
843 ExprResult TransformLambdaConstraint(Expr *AC) { return AC; }
844
845 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
846
847 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
848 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
849
850 TemplateParameterList *TransformTemplateParameterList(
851 TemplateParameterList *TPL) {
852 return TPL;
853 }
854
855 ExprResult TransformAddressOfOperand(Expr *E);
856
857 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
858 bool IsAddressOfOperand,
859 TypeSourceInfo **RecoveryTSI);
860
861 ExprResult TransformParenDependentScopeDeclRefExpr(
862 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
863 TypeSourceInfo **RecoveryTSI);
864
865 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
866 bool IsAddressOfOperand);
867
868 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
869
870 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
871
872// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
873// amount of stack usage with clang.
874#define STMT(Node, Parent) \
875 LLVM_ATTRIBUTE_NOINLINE \
876 StmtResult Transform##Node(Node *S);
877#define VALUESTMT(Node, Parent) \
878 LLVM_ATTRIBUTE_NOINLINE \
879 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
880#define EXPR(Node, Parent) \
881 LLVM_ATTRIBUTE_NOINLINE \
882 ExprResult Transform##Node(Node *E);
883#define ABSTRACT_STMT(Stmt)
884#include "clang/AST/StmtNodes.inc"
885
886#define GEN_CLANG_CLAUSE_CLASS
887#define CLAUSE_CLASS(Enum, Str, Class) \
888 LLVM_ATTRIBUTE_NOINLINE \
889 OMPClause *Transform##Class(Class *S);
890#include "llvm/Frontend/OpenMP/OMP.inc"
891
892 /// Build a new qualified type given its unqualified type and type location.
893 ///
894 /// By default, this routine adds type qualifiers only to types that can
895 /// have qualifiers, and silently suppresses those qualifiers that are not
896 /// permitted. Subclasses may override this routine to provide different
897 /// behavior.
898 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
899
900 /// Build a new pointer type given its pointee type.
901 ///
902 /// By default, performs semantic analysis when building the pointer type.
903 /// Subclasses may override this routine to provide different behavior.
904 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
905
906 /// Build a new block pointer type given its pointee type.
907 ///
908 /// By default, performs semantic analysis when building the block pointer
909 /// type. Subclasses may override this routine to provide different behavior.
910 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
911
912 /// Build a new reference type given the type it references.
913 ///
914 /// By default, performs semantic analysis when building the
915 /// reference type. Subclasses may override this routine to provide
916 /// different behavior.
917 ///
918 /// \param LValue whether the type was written with an lvalue sigil
919 /// or an rvalue sigil.
920 QualType RebuildReferenceType(QualType ReferentType,
921 bool LValue,
922 SourceLocation Sigil);
923
924 /// Build a new member pointer type given the pointee type and the
925 /// qualifier it refers into.
926 ///
927 /// By default, performs semantic analysis when building the member pointer
928 /// type. Subclasses may override this routine to provide different behavior.
929 QualType RebuildMemberPointerType(QualType PointeeType,
930 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
931 SourceLocation Sigil);
932
933 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
934 SourceLocation ProtocolLAngleLoc,
935 ArrayRef<ObjCProtocolDecl *> Protocols,
936 ArrayRef<SourceLocation> ProtocolLocs,
937 SourceLocation ProtocolRAngleLoc);
938
939 /// Build an Objective-C object type.
940 ///
941 /// By default, performs semantic analysis when building the object type.
942 /// Subclasses may override this routine to provide different behavior.
943 QualType RebuildObjCObjectType(QualType BaseType,
944 SourceLocation Loc,
945 SourceLocation TypeArgsLAngleLoc,
946 ArrayRef<TypeSourceInfo *> TypeArgs,
947 SourceLocation TypeArgsRAngleLoc,
948 SourceLocation ProtocolLAngleLoc,
949 ArrayRef<ObjCProtocolDecl *> Protocols,
950 ArrayRef<SourceLocation> ProtocolLocs,
951 SourceLocation ProtocolRAngleLoc);
952
953 /// Build a new Objective-C object pointer type given the pointee type.
954 ///
955 /// By default, directly builds the pointer type, with no additional semantic
956 /// analysis.
957 QualType RebuildObjCObjectPointerType(QualType PointeeType,
958 SourceLocation Star);
959
960 /// Build a new array type given the element type, size
961 /// modifier, size of the array (if known), size expression, and index type
962 /// qualifiers.
963 ///
964 /// By default, performs semantic analysis when building the array type.
965 /// Subclasses may override this routine to provide different behavior.
966 /// Also by default, all of the other Rebuild*Array
967 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
968 const llvm::APInt *Size, Expr *SizeExpr,
969 unsigned IndexTypeQuals, SourceRange BracketsRange);
970
971 /// Build a new constant array type given the element type, size
972 /// modifier, (known) size of the array, and index type qualifiers.
973 ///
974 /// By default, performs semantic analysis when building the array type.
975 /// Subclasses may override this routine to provide different behavior.
976 QualType RebuildConstantArrayType(QualType ElementType,
977 ArraySizeModifier SizeMod,
978 const llvm::APInt &Size, Expr *SizeExpr,
979 unsigned IndexTypeQuals,
980 SourceRange BracketsRange);
981
982 /// Build a new incomplete array type given the element type, size
983 /// modifier, and index type qualifiers.
984 ///
985 /// By default, performs semantic analysis when building the array type.
986 /// Subclasses may override this routine to provide different behavior.
987 QualType RebuildIncompleteArrayType(QualType ElementType,
988 ArraySizeModifier SizeMod,
989 unsigned IndexTypeQuals,
990 SourceRange BracketsRange);
991
992 /// Build a new variable-length array type given the element type,
993 /// size modifier, size expression, and index type qualifiers.
994 ///
995 /// By default, performs semantic analysis when building the array type.
996 /// Subclasses may override this routine to provide different behavior.
997 QualType RebuildVariableArrayType(QualType ElementType,
998 ArraySizeModifier SizeMod, Expr *SizeExpr,
999 unsigned IndexTypeQuals,
1000 SourceRange BracketsRange);
1001
1002 /// Build a new dependent-sized array type given the element type,
1003 /// size modifier, size expression, and index type qualifiers.
1004 ///
1005 /// By default, performs semantic analysis when building the array type.
1006 /// Subclasses may override this routine to provide different behavior.
1007 QualType RebuildDependentSizedArrayType(QualType ElementType,
1008 ArraySizeModifier SizeMod,
1009 Expr *SizeExpr,
1010 unsigned IndexTypeQuals,
1011 SourceRange BracketsRange);
1012
1013 /// Build a new vector type given the element type and
1014 /// number of elements.
1015 ///
1016 /// By default, performs semantic analysis when building the vector type.
1017 /// Subclasses may override this routine to provide different behavior.
1018 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1019 VectorKind VecKind);
1020
1021 /// Build a new potentially dependently-sized extended vector type
1022 /// given the element type and number of elements.
1023 ///
1024 /// By default, performs semantic analysis when building the vector type.
1025 /// Subclasses may override this routine to provide different behavior.
1026 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1027 SourceLocation AttributeLoc, VectorKind);
1028
1029 /// Build a new extended vector type given the element type and
1030 /// number of elements.
1031 ///
1032 /// By default, performs semantic analysis when building the vector type.
1033 /// Subclasses may override this routine to provide different behavior.
1034 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1035 SourceLocation AttributeLoc);
1036
1037 /// Build a new potentially dependently-sized extended vector type
1038 /// given the element type and number of elements.
1039 ///
1040 /// By default, performs semantic analysis when building the vector type.
1041 /// Subclasses may override this routine to provide different behavior.
1042 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1043 Expr *SizeExpr,
1044 SourceLocation AttributeLoc);
1045
1046 /// Build a new matrix type given the element type and dimensions.
1047 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1048 unsigned NumColumns);
1049
1050 /// Build a new matrix type given the type and dependently-defined
1051 /// dimensions.
1052 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1053 Expr *ColumnExpr,
1054 SourceLocation AttributeLoc);
1055
1056 /// Build a new DependentAddressSpaceType or return the pointee
1057 /// type variable with the correct address space (retrieved from
1058 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1059 /// where the address space remains dependent.
1060 ///
1061 /// By default, performs semantic analysis when building the type with address
1062 /// space applied. Subclasses may override this routine to provide different
1063 /// behavior.
1064 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1065 Expr *AddrSpaceExpr,
1066 SourceLocation AttributeLoc);
1067
1068 /// Build a new function type.
1069 ///
1070 /// By default, performs semantic analysis when building the function type.
1071 /// Subclasses may override this routine to provide different behavior.
1072 QualType RebuildFunctionProtoType(QualType T,
1073 MutableArrayRef<QualType> ParamTypes,
1074 const FunctionProtoType::ExtProtoInfo &EPI);
1075
1076 /// Build a new unprototyped function type.
1077 QualType RebuildFunctionNoProtoType(QualType ResultType);
1078
1079 /// Rebuild an unresolved typename type, given the decl that
1080 /// the UnresolvedUsingTypenameDecl was transformed to.
1081 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1082 NestedNameSpecifier Qualifier,
1083 SourceLocation NameLoc, Decl *D);
1084
1085 /// Build a new type found via an alias.
1086 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1087 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1088 QualType UnderlyingType) {
1089 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1090 }
1091
1092 /// Build a new typedef type.
1093 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1094 NestedNameSpecifier Qualifier,
1095 TypedefNameDecl *Typedef) {
1096 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1097 }
1098
1099 /// Build a new MacroDefined type.
1100 QualType RebuildMacroQualifiedType(QualType T,
1101 const IdentifierInfo *MacroII) {
1102 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1103 }
1104
1105 /// Build a new class/struct/union/enum type.
1106 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1107 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1108 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1109 /*OwnsTag=*/OwnsTag: false);
1110 }
1111 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1112 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1113 }
1114
1115 /// Build a new typeof(expr) type.
1116 ///
1117 /// By default, performs semantic analysis when building the typeof type.
1118 /// Subclasses may override this routine to provide different behavior.
1119 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1120 TypeOfKind Kind);
1121
1122 /// Build a new typeof(type) type.
1123 ///
1124 /// By default, builds a new TypeOfType with the given underlying type.
1125 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1126
1127 /// Build a new unary transform type.
1128 QualType RebuildUnaryTransformType(QualType BaseType,
1129 UnaryTransformType::UTTKind UKind,
1130 SourceLocation Loc);
1131
1132 /// Build a new C++11 decltype type.
1133 ///
1134 /// By default, performs semantic analysis when building the decltype type.
1135 /// Subclasses may override this routine to provide different behavior.
1136 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1137
1138 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1139 SourceLocation Loc,
1140 SourceLocation EllipsisLoc,
1141 bool FullySubstituted,
1142 ArrayRef<QualType> Expansions = {});
1143
1144 /// Build a new C++11 auto type.
1145 ///
1146 /// By default, builds a new AutoType with the given deduced type.
1147 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1148 AutoTypeKeyword Keyword,
1149 TemplateName TypeConstraintConcept,
1150 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1151 return SemaRef.Context.getAutoType(
1152 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1153 }
1154
1155 /// By default, builds a new DeducedTemplateSpecializationType with the given
1156 /// deduced type.
1157 QualType RebuildDeducedTemplateSpecializationType(
1158 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1159 TemplateName Template) {
1160 return SemaRef.Context.getDeducedTemplateSpecializationType(
1161 DK, DeducedAsType, Keyword, Template);
1162 }
1163
1164 /// Build a new template specialization type.
1165 ///
1166 /// By default, performs semantic analysis when building the template
1167 /// specialization type. Subclasses may override this routine to provide
1168 /// different behavior.
1169 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1170 TemplateName Template,
1171 SourceLocation TemplateLoc,
1172 TemplateArgumentListInfo &Args);
1173
1174 /// Build a new parenthesized type.
1175 ///
1176 /// By default, builds a new ParenType type from the inner type.
1177 /// Subclasses may override this routine to provide different behavior.
1178 QualType RebuildParenType(QualType InnerType) {
1179 return SemaRef.BuildParenType(T: InnerType);
1180 }
1181
1182 /// Build a new typename type that refers to an identifier.
1183 ///
1184 /// By default, performs semantic analysis when building the typename type
1185 /// (or elaborated type). Subclasses may override this routine to provide
1186 /// different behavior.
1187 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1188 SourceLocation KeywordLoc,
1189 NestedNameSpecifierLoc QualifierLoc,
1190 const IdentifierInfo *Id,
1191 SourceLocation IdLoc,
1192 bool DeducedTSTContext) {
1193 CXXScopeSpec SS;
1194 SS.Adopt(Other: QualifierLoc);
1195
1196 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1197 // If the name is still dependent, just build a new dependent name type.
1198 if (!SemaRef.computeDeclContext(SS))
1199 return SemaRef.Context.getDependentNameType(Keyword,
1200 NNS: QualifierLoc.getNestedNameSpecifier(),
1201 Name: Id);
1202 }
1203
1204 if (Keyword == ElaboratedTypeKeyword::None ||
1205 Keyword == ElaboratedTypeKeyword::Typename) {
1206 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1207 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1208 }
1209
1210 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1211
1212 // We had a dependent elaborated-type-specifier that has been transformed
1213 // into a non-dependent elaborated-type-specifier. Find the tag we're
1214 // referring to.
1215 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1216 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1217 if (!DC)
1218 return QualType();
1219
1220 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1221 return QualType();
1222
1223 TagDecl *Tag = nullptr;
1224 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1225 switch (Result.getResultKind()) {
1226 case LookupResultKind::NotFound:
1227 case LookupResultKind::NotFoundInCurrentInstantiation:
1228 break;
1229
1230 case LookupResultKind::Found:
1231 Tag = Result.getAsSingle<TagDecl>();
1232 break;
1233
1234 case LookupResultKind::FoundOverloaded:
1235 case LookupResultKind::FoundUnresolvedValue:
1236 llvm_unreachable("Tag lookup cannot find non-tags");
1237
1238 case LookupResultKind::Ambiguous:
1239 // Let the LookupResult structure handle ambiguities.
1240 return QualType();
1241 }
1242
1243 if (!Tag) {
1244 // Check where the name exists but isn't a tag type and use that to emit
1245 // better diagnostics.
1246 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1247 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1248 switch (Result.getResultKind()) {
1249 case LookupResultKind::Found:
1250 case LookupResultKind::FoundOverloaded:
1251 case LookupResultKind::FoundUnresolvedValue: {
1252 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1253 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1254 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1255 << SomeDecl << NTK << Kind;
1256 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1257 break;
1258 }
1259 default:
1260 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1261 << Kind << Id << DC << QualifierLoc.getSourceRange();
1262 break;
1263 }
1264 return QualType();
1265 }
1266 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1267 NewTagLoc: IdLoc, Name: Id)) {
1268 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1269 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1270 return QualType();
1271 }
1272 return getDerived().RebuildTagType(
1273 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1274 }
1275
1276 /// Build a new pack expansion type.
1277 ///
1278 /// By default, builds a new PackExpansionType type from the given pattern.
1279 /// Subclasses may override this routine to provide different behavior.
1280 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1281 SourceLocation EllipsisLoc,
1282 UnsignedOrNone NumExpansions) {
1283 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1284 NumExpansions);
1285 }
1286
1287 /// Build a new atomic type given its value type.
1288 ///
1289 /// By default, performs semantic analysis when building the atomic type.
1290 /// Subclasses may override this routine to provide different behavior.
1291 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1292
1293 /// Build a new pipe type given its value type.
1294 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1295 bool isReadPipe);
1296
1297 /// Build a bit-precise int given its value type.
1298 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1299 SourceLocation Loc);
1300
1301 /// Build a dependent bit-precise int given its value type.
1302 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1303 SourceLocation Loc);
1304
1305 /// Build a new template name given a nested name specifier, a flag
1306 /// indicating whether the "template" keyword was provided, and the template
1307 /// that the template name refers to.
1308 ///
1309 /// By default, builds the new template name directly. Subclasses may override
1310 /// this routine to provide different behavior.
1311 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1312 TemplateName Name);
1313
1314 /// Build a new template name given a nested name specifier and the
1315 /// name that is referred to as a template.
1316 ///
1317 /// By default, performs semantic analysis to determine whether the name can
1318 /// be resolved to a specific template, then builds the appropriate kind of
1319 /// template name. Subclasses may override this routine to provide different
1320 /// behavior.
1321 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1322 SourceLocation TemplateKWLoc,
1323 const IdentifierInfo &Name,
1324 SourceLocation NameLoc, QualType ObjectType,
1325 bool AllowInjectedClassName);
1326
1327 /// Build a new template name given a nested name specifier and the
1328 /// overloaded operator name that is referred to as a template.
1329 ///
1330 /// By default, performs semantic analysis to determine whether the name can
1331 /// be resolved to a specific template, then builds the appropriate kind of
1332 /// template name. Subclasses may override this routine to provide different
1333 /// behavior.
1334 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1335 SourceLocation TemplateKWLoc,
1336 OverloadedOperatorKind Operator,
1337 SourceLocation NameLoc, QualType ObjectType,
1338 bool AllowInjectedClassName);
1339
1340 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1341 SourceLocation TemplateKWLoc,
1342 IdentifierOrOverloadedOperator IO,
1343 SourceLocation NameLoc, QualType ObjectType,
1344 bool AllowInjectedClassName);
1345
1346 /// Build a new template name given a template template parameter pack
1347 /// and the
1348 ///
1349 /// By default, performs semantic analysis to determine whether the name can
1350 /// be resolved to a specific template, then builds the appropriate kind of
1351 /// template name. Subclasses may override this routine to provide different
1352 /// behavior.
1353 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1354 Decl *AssociatedDecl, unsigned Index,
1355 bool Final) {
1356 return getSema().Context.getSubstTemplateTemplateParmPack(
1357 ArgPack, AssociatedDecl, Index, Final);
1358 }
1359
1360 /// Build a new pack-index-template-name ([temp.names]).
1361 ///
1362 /// By default, performs semantic analysis to build the new template name.
1363 /// Subclasses may override this routine to provide different behavior.
1364 TemplateName
1365 RebuildPackIndexingTemplateName(TemplateName Pattern, Expr *IndexExpr,
1366 bool FullySubstituted,
1367 ArrayRef<TemplateName> Expansions = {}) {
1368 return getSema().BuildPackIndexingTemplateName(
1369 Pattern, IndexExpr, FullySubstituted, Expansions);
1370 }
1371
1372 /// Build a new compound statement.
1373 ///
1374 /// By default, performs semantic analysis to build the new statement.
1375 /// Subclasses may override this routine to provide different behavior.
1376 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1377 MultiStmtArg Statements,
1378 SourceLocation RBraceLoc,
1379 bool IsStmtExpr) {
1380 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1381 IsStmtExpr);
1382 }
1383
1384 /// Build a new case statement.
1385 ///
1386 /// By default, performs semantic analysis to build the new statement.
1387 /// Subclasses may override this routine to provide different behavior.
1388 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1389 Expr *LHS,
1390 SourceLocation EllipsisLoc,
1391 Expr *RHS,
1392 SourceLocation ColonLoc) {
1393 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1394 ColonLoc);
1395 }
1396
1397 /// Attach the body to a new case statement.
1398 ///
1399 /// By default, performs semantic analysis to build the new statement.
1400 /// Subclasses may override this routine to provide different behavior.
1401 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1402 getSema().ActOnCaseStmtBody(S, Body);
1403 return S;
1404 }
1405
1406 /// Build a new default statement.
1407 ///
1408 /// By default, performs semantic analysis to build the new statement.
1409 /// Subclasses may override this routine to provide different behavior.
1410 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1411 SourceLocation ColonLoc,
1412 Stmt *SubStmt) {
1413 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1414 /*CurScope=*/nullptr);
1415 }
1416
1417 /// Build a new label statement.
1418 ///
1419 /// By default, performs semantic analysis to build the new statement.
1420 /// Subclasses may override this routine to provide different behavior.
1421 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1422 SourceLocation ColonLoc, Stmt *SubStmt) {
1423 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1424 }
1425
1426 /// Build a new attributed statement.
1427 ///
1428 /// By default, performs semantic analysis to build the new statement.
1429 /// Subclasses may override this routine to provide different behavior.
1430 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1431 ArrayRef<const Attr *> Attrs,
1432 Stmt *SubStmt) {
1433 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1434 return StmtError();
1435 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1436 }
1437
1438 /// Build a new "if" statement.
1439 ///
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1442 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1443 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1444 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1445 SourceLocation ElseLoc, Stmt *Else) {
1446 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1447 Then, ElseLoc, Else);
1448 }
1449
1450 /// Start building a new switch statement.
1451 ///
1452 /// By default, performs semantic analysis to build the new statement.
1453 /// Subclasses may override this routine to provide different behavior.
1454 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1455 SourceLocation LParenLoc, Stmt *Init,
1456 Sema::ConditionResult Cond,
1457 SourceLocation RParenLoc) {
1458 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1459 RParenLoc);
1460 }
1461
1462 /// Attach the body to the switch statement.
1463 ///
1464 /// By default, performs semantic analysis to build the new statement.
1465 /// Subclasses may override this routine to provide different behavior.
1466 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1467 Stmt *Switch, Stmt *Body) {
1468 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1469 }
1470
1471 /// Build a new while statement.
1472 ///
1473 /// By default, performs semantic analysis to build the new statement.
1474 /// Subclasses may override this routine to provide different behavior.
1475 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1476 Sema::ConditionResult Cond,
1477 SourceLocation RParenLoc, Stmt *Body) {
1478 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1479 }
1480
1481 /// Build a new do-while statement.
1482 ///
1483 /// By default, performs semantic analysis to build the new statement.
1484 /// Subclasses may override this routine to provide different behavior.
1485 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1486 SourceLocation WhileLoc, SourceLocation LParenLoc,
1487 Expr *Cond, SourceLocation RParenLoc) {
1488 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1489 Cond, RParenLoc);
1490 }
1491
1492 /// Build a new for statement.
1493 ///
1494 /// By default, performs semantic analysis to build the new statement.
1495 /// Subclasses may override this routine to provide different behavior.
1496 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1497 Stmt *Init, Sema::ConditionResult Cond,
1498 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1499 Stmt *Body) {
1500 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1501 Inc, RParenLoc, Body);
1502 }
1503
1504 /// Build a new goto statement.
1505 ///
1506 /// By default, performs semantic analysis to build the new statement.
1507 /// Subclasses may override this routine to provide different behavior.
1508 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1509 LabelDecl *Label) {
1510 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1511 }
1512
1513 /// Build a new indirect goto statement.
1514 ///
1515 /// By default, performs semantic analysis to build the new statement.
1516 /// Subclasses may override this routine to provide different behavior.
1517 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1518 SourceLocation StarLoc,
1519 Expr *Target) {
1520 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1521 }
1522
1523 /// Build a new return statement.
1524 ///
1525 /// By default, performs semantic analysis to build the new statement.
1526 /// Subclasses may override this routine to provide different behavior.
1527 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1528 return getSema().BuildReturnStmt(ReturnLoc, Result);
1529 }
1530
1531 /// Build a new declaration statement.
1532 ///
1533 /// By default, performs semantic analysis to build the new statement.
1534 /// Subclasses may override this routine to provide different behavior.
1535 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1536 SourceLocation StartLoc, SourceLocation EndLoc) {
1537 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1538 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1539 }
1540
1541 /// Build a new inline asm statement.
1542 ///
1543 /// By default, performs semantic analysis to build the new statement.
1544 /// Subclasses may override this routine to provide different behavior.
1545 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1546 bool IsVolatile, unsigned NumOutputs,
1547 unsigned NumInputs, IdentifierInfo **Names,
1548 MultiExprArg Constraints, MultiExprArg Exprs,
1549 Expr *AsmString, MultiExprArg Clobbers,
1550 unsigned NumLabels,
1551 SourceLocation RParenLoc) {
1552 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1553 NumInputs, Names, Constraints, Exprs,
1554 AsmString, Clobbers, NumLabels, RParenLoc);
1555 }
1556
1557 /// Build a new MS style inline asm statement.
1558 ///
1559 /// By default, performs semantic analysis to build the new statement.
1560 /// Subclasses may override this routine to provide different behavior.
1561 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1562 ArrayRef<Token> AsmToks,
1563 StringRef AsmString,
1564 unsigned NumOutputs, unsigned NumInputs,
1565 ArrayRef<StringRef> Constraints,
1566 ArrayRef<StringRef> Clobbers,
1567 ArrayRef<Expr*> Exprs,
1568 SourceLocation EndLoc) {
1569 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1570 NumOutputs, NumInputs,
1571 Constraints, Clobbers, Exprs, EndLoc);
1572 }
1573
1574 /// Build a new co_return statement.
1575 ///
1576 /// By default, performs semantic analysis to build the new statement.
1577 /// Subclasses may override this routine to provide different behavior.
1578 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1579 bool IsImplicit) {
1580 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1581 }
1582
1583 /// Build a new co_await expression.
1584 ///
1585 /// By default, performs semantic analysis to build the new expression.
1586 /// Subclasses may override this routine to provide different behavior.
1587 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1588 UnresolvedLookupExpr *OpCoawaitLookup,
1589 bool IsImplicit) {
1590 // This function rebuilds a coawait-expr given its operator.
1591 // For an explicit coawait-expr, the rebuild involves the full set
1592 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1593 // including calling await_transform().
1594 // For an implicit coawait-expr, we need to rebuild the "operator
1595 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1596 // This mirrors how the implicit CoawaitExpr is originally created
1597 // in Sema::ActOnCoroutineBodyStart().
1598 if (IsImplicit) {
1599 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1600 CoawaitLoc, Operand, OpCoawaitLookup);
1601 if (Suspend.isInvalid())
1602 return ExprError();
1603 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1604 Suspend.get(), true);
1605 }
1606
1607 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1608 OpCoawaitLookup);
1609 }
1610
1611 /// Build a new co_await expression.
1612 ///
1613 /// By default, performs semantic analysis to build the new expression.
1614 /// Subclasses may override this routine to provide different behavior.
1615 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1616 Expr *Result,
1617 UnresolvedLookupExpr *Lookup) {
1618 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1619 }
1620
1621 /// Build a new co_yield expression.
1622 ///
1623 /// By default, performs semantic analysis to build the new expression.
1624 /// Subclasses may override this routine to provide different behavior.
1625 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1626 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1627 }
1628
1629 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1630 return getSema().BuildCoroutineBodyStmt(Args);
1631 }
1632
1633 /// Build a new Objective-C \@try statement.
1634 ///
1635 /// By default, performs semantic analysis to build the new statement.
1636 /// Subclasses may override this routine to provide different behavior.
1637 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1638 Stmt *TryBody,
1639 MultiStmtArg CatchStmts,
1640 Stmt *Finally) {
1641 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1642 Finally);
1643 }
1644
1645 /// Rebuild an Objective-C exception declaration.
1646 ///
1647 /// By default, performs semantic analysis to build the new declaration.
1648 /// Subclasses may override this routine to provide different behavior.
1649 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1650 TypeSourceInfo *TInfo, QualType T) {
1651 return getSema().ObjC().BuildObjCExceptionDecl(
1652 TInfo, T, ExceptionDecl->getInnerLocStart(),
1653 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1654 }
1655
1656 /// Build a new Objective-C \@catch statement.
1657 ///
1658 /// By default, performs semantic analysis to build the new statement.
1659 /// Subclasses may override this routine to provide different behavior.
1660 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1661 SourceLocation RParenLoc,
1662 VarDecl *Var,
1663 Stmt *Body) {
1664 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1665 }
1666
1667 /// Build a new Objective-C \@finally statement.
1668 ///
1669 /// By default, performs semantic analysis to build the new statement.
1670 /// Subclasses may override this routine to provide different behavior.
1671 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1672 Stmt *Body) {
1673 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1674 }
1675
1676 /// Build a new Objective-C \@throw statement.
1677 ///
1678 /// By default, performs semantic analysis to build the new statement.
1679 /// Subclasses may override this routine to provide different behavior.
1680 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1681 Expr *Operand) {
1682 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1683 }
1684
1685 /// Build a new OpenMP Canonical loop.
1686 ///
1687 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1688 /// OMPCanonicalLoop.
1689 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1690 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1691 }
1692
1693 /// Build a new OpenMP executable directive.
1694 ///
1695 /// By default, performs semantic analysis to build the new statement.
1696 /// Subclasses may override this routine to provide different behavior.
1697 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1698 DeclarationNameInfo DirName,
1699 OpenMPDirectiveKind CancelRegion,
1700 ArrayRef<OMPClause *> Clauses,
1701 Stmt *AStmt, SourceLocation StartLoc,
1702 SourceLocation EndLoc) {
1703
1704 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1705 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1706 }
1707
1708 /// Build a new OpenMP informational directive.
1709 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1710 DeclarationNameInfo DirName,
1711 ArrayRef<OMPClause *> Clauses,
1712 Stmt *AStmt,
1713 SourceLocation StartLoc,
1714 SourceLocation EndLoc) {
1715
1716 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1717 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1718 }
1719
1720 /// Build a new OpenMP 'if' clause.
1721 ///
1722 /// By default, performs semantic analysis to build the new OpenMP clause.
1723 /// Subclasses may override this routine to provide different behavior.
1724 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1725 Expr *Condition, SourceLocation StartLoc,
1726 SourceLocation LParenLoc,
1727 SourceLocation NameModifierLoc,
1728 SourceLocation ColonLoc,
1729 SourceLocation EndLoc) {
1730 return getSema().OpenMP().ActOnOpenMPIfClause(
1731 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1732 EndLoc);
1733 }
1734
1735 /// Build a new OpenMP 'final' clause.
1736 ///
1737 /// By default, performs semantic analysis to build the new OpenMP clause.
1738 /// Subclasses may override this routine to provide different behavior.
1739 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1740 SourceLocation LParenLoc,
1741 SourceLocation EndLoc) {
1742 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1743 LParenLoc, EndLoc);
1744 }
1745
1746 /// Build a new OpenMP 'num_threads' clause.
1747 ///
1748 /// By default, performs semantic analysis to build the new OpenMP clause.
1749 /// Subclasses may override this routine to provide different behavior.
1750 OMPClause *RebuildOMPNumThreadsClause(
1751 ArrayRef<Expr *> VarList,
1752 OpenMPNumThreadsClauseModifier PrescriptivenessModifier,
1753 SourceLocation PrescriptivenessModifierLoc,
1754 OpenMPNumThreadsClauseModifier DimsModifier, Expr *DimsModifierExpr,
1755 SourceLocation DimsModifierLoc, SourceLocation StartLoc,
1756 SourceLocation LParenLoc, SourceLocation EndLoc) {
1757 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1758 VarList, PrescriptivenessModifier, PrescriptivenessModifierLoc,
1759 DimsModifier, DimsModifierExpr, DimsModifierLoc, StartLoc, LParenLoc,
1760 EndLoc);
1761 }
1762
1763 /// Build a new OpenMP 'safelen' clause.
1764 ///
1765 /// By default, performs semantic analysis to build the new OpenMP clause.
1766 /// Subclasses may override this routine to provide different behavior.
1767 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1768 SourceLocation LParenLoc,
1769 SourceLocation EndLoc) {
1770 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1771 EndLoc);
1772 }
1773
1774 /// Build a new OpenMP 'simdlen' clause.
1775 ///
1776 /// By default, performs semantic analysis to build the new OpenMP clause.
1777 /// Subclasses may override this routine to provide different behavior.
1778 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1779 SourceLocation LParenLoc,
1780 SourceLocation EndLoc) {
1781 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1782 EndLoc);
1783 }
1784
1785 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1786 SourceLocation StartLoc,
1787 SourceLocation LParenLoc,
1788 SourceLocation EndLoc) {
1789 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1790 EndLoc);
1791 }
1792
1793 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1794 SourceLocation StartLoc,
1795 SourceLocation LParenLoc,
1796 SourceLocation EndLoc,
1797 std::optional<unsigned> FillIdx,
1798 SourceLocation FillLoc) {
1799 unsigned FillCount = FillIdx ? 1 : 0;
1800 return getSema().OpenMP().ActOnOpenMPCountsClause(
1801 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1802 }
1803
1804 /// Build a new OpenMP 'permutation' clause.
1805 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1806 SourceLocation StartLoc,
1807 SourceLocation LParenLoc,
1808 SourceLocation EndLoc) {
1809 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1810 LParenLoc, EndLoc);
1811 }
1812
1813 /// Build a new OpenMP 'full' clause.
1814 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1815 SourceLocation EndLoc) {
1816 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1817 }
1818
1819 /// Build a new OpenMP 'partial' clause.
1820 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1821 SourceLocation LParenLoc,
1822 SourceLocation EndLoc) {
1823 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1824 LParenLoc, EndLoc);
1825 }
1826
1827 OMPClause *
1828 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1829 SourceLocation LParenLoc, SourceLocation FirstLoc,
1830 SourceLocation CountLoc, SourceLocation EndLoc) {
1831 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1832 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1833 }
1834
1835 /// Build a new OpenMP 'allocator' clause.
1836 ///
1837 /// By default, performs semantic analysis to build the new OpenMP clause.
1838 /// Subclasses may override this routine to provide different behavior.
1839 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1840 SourceLocation LParenLoc,
1841 SourceLocation EndLoc) {
1842 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1843 EndLoc);
1844 }
1845
1846 /// Build a new OpenMP 'collapse' clause.
1847 ///
1848 /// By default, performs semantic analysis to build the new OpenMP clause.
1849 /// Subclasses may override this routine to provide different behavior.
1850 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1851 SourceLocation LParenLoc,
1852 SourceLocation EndLoc) {
1853 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1854 LParenLoc, EndLoc);
1855 }
1856
1857 /// Build a new OpenMP 'default' clause.
1858 ///
1859 /// By default, performs semantic analysis to build the new OpenMP clause.
1860 /// Subclasses may override this routine to provide different behavior.
1861 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1862 OpenMPDefaultClauseVariableCategory VCKind,
1863 SourceLocation VCLoc,
1864 SourceLocation StartLoc,
1865 SourceLocation LParenLoc,
1866 SourceLocation EndLoc) {
1867 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1868 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1869 }
1870
1871 /// Build a new OpenMP 'proc_bind' clause.
1872 ///
1873 /// By default, performs semantic analysis to build the new OpenMP clause.
1874 /// Subclasses may override this routine to provide different behavior.
1875 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1876 SourceLocation KindKwLoc,
1877 SourceLocation StartLoc,
1878 SourceLocation LParenLoc,
1879 SourceLocation EndLoc) {
1880 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1881 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1882 }
1883 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1884 SourceLocation StartLoc,
1885 SourceLocation LParenLoc,
1886 SourceLocation EndLoc) {
1887 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1888 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1889 }
1890
1891 /// Build a new OpenMP 'schedule' clause.
1892 ///
1893 /// By default, performs semantic analysis to build the new OpenMP clause.
1894 /// Subclasses may override this routine to provide different behavior.
1895 OMPClause *RebuildOMPScheduleClause(
1896 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1897 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1898 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1899 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1900 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1901 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1902 CommaLoc, EndLoc);
1903 }
1904
1905 /// Build a new OpenMP 'ordered' clause.
1906 ///
1907 /// By default, performs semantic analysis to build the new OpenMP clause.
1908 /// Subclasses may override this routine to provide different behavior.
1909 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1910 SourceLocation EndLoc,
1911 SourceLocation LParenLoc, Expr *Num) {
1912 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1913 LParenLoc, Num);
1914 }
1915
1916 /// Build a new OpenMP 'nowait' clause.
1917 ///
1918 /// By default, performs semantic analysis to build the new OpenMP clause.
1919 /// Subclasses may override this routine to provide different behavior.
1920 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1921 SourceLocation LParenLoc,
1922 SourceLocation EndLoc) {
1923 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1924 LParenLoc, Condition);
1925 }
1926
1927 /// Build a new OpenMP 'private' clause.
1928 ///
1929 /// By default, performs semantic analysis to build the new OpenMP clause.
1930 /// Subclasses may override this routine to provide different behavior.
1931 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1932 SourceLocation StartLoc,
1933 SourceLocation LParenLoc,
1934 SourceLocation EndLoc) {
1935 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1936 LParenLoc, EndLoc);
1937 }
1938
1939 /// Build a new OpenMP 'firstprivate' clause.
1940 ///
1941 /// By default, performs semantic analysis to build the new OpenMP clause.
1942 /// Subclasses may override this routine to provide different behavior.
1943 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1944 SourceLocation StartLoc,
1945 SourceLocation LParenLoc,
1946 SourceLocation EndLoc) {
1947 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1948 LParenLoc, EndLoc);
1949 }
1950
1951 /// Build a new OpenMP 'lastprivate' clause.
1952 ///
1953 /// By default, performs semantic analysis to build the new OpenMP clause.
1954 /// Subclasses may override this routine to provide different behavior.
1955 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1956 OpenMPLastprivateModifier LPKind,
1957 SourceLocation LPKindLoc,
1958 SourceLocation ColonLoc,
1959 SourceLocation StartLoc,
1960 SourceLocation LParenLoc,
1961 SourceLocation EndLoc) {
1962 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1963 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1964 }
1965
1966 /// Build a new OpenMP 'shared' clause.
1967 ///
1968 /// By default, performs semantic analysis to build the new OpenMP clause.
1969 /// Subclasses may override this routine to provide different behavior.
1970 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1971 SourceLocation StartLoc,
1972 SourceLocation LParenLoc,
1973 SourceLocation EndLoc) {
1974 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1975 LParenLoc, EndLoc);
1976 }
1977
1978 /// Build a new OpenMP 'reduction' clause.
1979 ///
1980 /// By default, performs semantic analysis to build the new statement.
1981 /// Subclasses may override this routine to provide different behavior.
1982 OMPClause *RebuildOMPReductionClause(
1983 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1984 OpenMPOriginalSharingModifier OriginalSharingModifier,
1985 SourceLocation StartLoc, SourceLocation LParenLoc,
1986 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1987 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1988 const DeclarationNameInfo &ReductionId,
1989 ArrayRef<Expr *> UnresolvedReductions) {
1990 return getSema().OpenMP().ActOnOpenMPReductionClause(
1991 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1992 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1993 UnresolvedReductions);
1994 }
1995
1996 /// Build a new OpenMP 'task_reduction' clause.
1997 ///
1998 /// By default, performs semantic analysis to build the new statement.
1999 /// Subclasses may override this routine to provide different behavior.
2000 OMPClause *RebuildOMPTaskReductionClause(
2001 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2002 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
2003 CXXScopeSpec &ReductionIdScopeSpec,
2004 const DeclarationNameInfo &ReductionId,
2005 ArrayRef<Expr *> UnresolvedReductions) {
2006 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
2007 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2008 ReductionId, UnresolvedReductions);
2009 }
2010
2011 /// Build a new OpenMP 'in_reduction' clause.
2012 ///
2013 /// By default, performs semantic analysis to build the new statement.
2014 /// Subclasses may override this routine to provide different behavior.
2015 OMPClause *
2016 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2017 SourceLocation LParenLoc, SourceLocation ColonLoc,
2018 SourceLocation EndLoc,
2019 CXXScopeSpec &ReductionIdScopeSpec,
2020 const DeclarationNameInfo &ReductionId,
2021 ArrayRef<Expr *> UnresolvedReductions) {
2022 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2023 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2024 ReductionId, UnresolvedReductions);
2025 }
2026
2027 /// Build a new OpenMP 'linear' clause.
2028 ///
2029 /// By default, performs semantic analysis to build the new OpenMP clause.
2030 /// Subclasses may override this routine to provide different behavior.
2031 OMPClause *RebuildOMPLinearClause(
2032 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2033 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2034 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2035 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2036 return getSema().OpenMP().ActOnOpenMPLinearClause(
2037 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2038 StepModifierLoc, EndLoc);
2039 }
2040
2041 /// Build a new OpenMP 'aligned' clause.
2042 ///
2043 /// By default, performs semantic analysis to build the new OpenMP clause.
2044 /// Subclasses may override this routine to provide different behavior.
2045 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2046 SourceLocation StartLoc,
2047 SourceLocation LParenLoc,
2048 SourceLocation ColonLoc,
2049 SourceLocation EndLoc) {
2050 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2051 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2052 }
2053
2054 /// Build a new OpenMP 'copyin' clause.
2055 ///
2056 /// By default, performs semantic analysis to build the new OpenMP clause.
2057 /// Subclasses may override this routine to provide different behavior.
2058 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2059 SourceLocation StartLoc,
2060 SourceLocation LParenLoc,
2061 SourceLocation EndLoc) {
2062 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2063 LParenLoc, EndLoc);
2064 }
2065
2066 /// Build a new OpenMP 'copyprivate' clause.
2067 ///
2068 /// By default, performs semantic analysis to build the new OpenMP clause.
2069 /// Subclasses may override this routine to provide different behavior.
2070 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2071 SourceLocation StartLoc,
2072 SourceLocation LParenLoc,
2073 SourceLocation EndLoc) {
2074 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2075 LParenLoc, EndLoc);
2076 }
2077
2078 /// Build a new OpenMP 'flush' pseudo clause.
2079 ///
2080 /// By default, performs semantic analysis to build the new OpenMP clause.
2081 /// Subclasses may override this routine to provide different behavior.
2082 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2083 SourceLocation StartLoc,
2084 SourceLocation LParenLoc,
2085 SourceLocation EndLoc) {
2086 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2087 LParenLoc, EndLoc);
2088 }
2089
2090 /// Build a new OpenMP 'depobj' pseudo clause.
2091 ///
2092 /// By default, performs semantic analysis to build the new OpenMP clause.
2093 /// Subclasses may override this routine to provide different behavior.
2094 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2095 SourceLocation LParenLoc,
2096 SourceLocation EndLoc) {
2097 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2098 LParenLoc, EndLoc);
2099 }
2100
2101 /// Build a new OpenMP 'depend' pseudo clause.
2102 ///
2103 /// By default, performs semantic analysis to build the new OpenMP clause.
2104 /// Subclasses may override this routine to provide different behavior.
2105 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2106 Expr *DepModifier, ArrayRef<Expr *> VarList,
2107 SourceLocation StartLoc,
2108 SourceLocation LParenLoc,
2109 SourceLocation EndLoc) {
2110 return getSema().OpenMP().ActOnOpenMPDependClause(
2111 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2112 }
2113
2114 /// Build a new OpenMP 'device' clause.
2115 ///
2116 /// By default, performs semantic analysis to build the new statement.
2117 /// Subclasses may override this routine to provide different behavior.
2118 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2119 Expr *Device, SourceLocation StartLoc,
2120 SourceLocation LParenLoc,
2121 SourceLocation ModifierLoc,
2122 SourceLocation EndLoc) {
2123 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2124 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2125 }
2126
2127 /// Build a new OpenMP 'map' clause.
2128 ///
2129 /// By default, performs semantic analysis to build the new OpenMP clause.
2130 /// Subclasses may override this routine to provide different behavior.
2131 OMPClause *RebuildOMPMapClause(
2132 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2133 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2134 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2135 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2136 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2137 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2138 return getSema().OpenMP().ActOnOpenMPMapClause(
2139 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2140 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2141 ColonLoc, VarList, Locs,
2142 /*NoDiagnose=*/false, UnresolvedMappers);
2143 }
2144
2145 /// Build a new OpenMP 'allocate' clause.
2146 ///
2147 /// By default, performs semantic analysis to build the new OpenMP clause.
2148 /// Subclasses may override this routine to provide different behavior.
2149 OMPClause *
2150 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2151 OpenMPAllocateClauseModifier FirstModifier,
2152 SourceLocation FirstModifierLoc,
2153 OpenMPAllocateClauseModifier SecondModifier,
2154 SourceLocation SecondModifierLoc,
2155 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2156 SourceLocation LParenLoc, SourceLocation ColonLoc,
2157 SourceLocation EndLoc) {
2158 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2159 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2160 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2161 }
2162
2163 /// Build a new OpenMP 'num_teams' clause.
2164 ///
2165 /// By default, performs semantic analysis to build the new statement.
2166 /// Subclasses may override this routine to provide different behavior.
2167 OMPClause *RebuildOMPNumTeamsClause(
2168 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2169 Expr *ModifierExpr, SourceLocation ModifierLoc,
2170 OpenMPNumTeamsClauseModifier ModifierExtra, Expr *ModifierExtraExpr,
2171 SourceLocation ModifierExtraLoc, SourceLocation StartLoc,
2172 SourceLocation LParenLoc, SourceLocation EndLoc) {
2173 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2174 VarList, Modifier, ModifierExpr, ModifierLoc, ModifierExtra,
2175 ModifierExtraExpr, ModifierExtraLoc, StartLoc, LParenLoc, EndLoc);
2176 }
2177
2178 /// Build a new OpenMP 'thread_limit' clause.
2179 ///
2180 /// By default, performs semantic analysis to build the new statement.
2181 /// Subclasses may override this routine to provide different behavior.
2182 OMPClause *RebuildOMPThreadLimitClause(
2183 ArrayRef<Expr *> VarList, OpenMPThreadLimitClauseModifier Modifier,
2184 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2185 SourceLocation LParenLoc, SourceLocation EndLoc) {
2186 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2187 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2188 EndLoc);
2189 }
2190
2191 /// Build a new OpenMP 'priority' clause.
2192 ///
2193 /// By default, performs semantic analysis to build the new statement.
2194 /// Subclasses may override this routine to provide different behavior.
2195 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2196 SourceLocation LParenLoc,
2197 SourceLocation EndLoc) {
2198 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2199 LParenLoc, EndLoc);
2200 }
2201
2202 /// Build a new OpenMP 'grainsize' clause.
2203 ///
2204 /// By default, performs semantic analysis to build the new statement.
2205 /// Subclasses may override this routine to provide different behavior.
2206 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2207 Expr *Device, SourceLocation StartLoc,
2208 SourceLocation LParenLoc,
2209 SourceLocation ModifierLoc,
2210 SourceLocation EndLoc) {
2211 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2212 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2213 }
2214
2215 /// Build a new OpenMP 'num_tasks' clause.
2216 ///
2217 /// By default, performs semantic analysis to build the new statement.
2218 /// Subclasses may override this routine to provide different behavior.
2219 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2220 Expr *NumTasks, SourceLocation StartLoc,
2221 SourceLocation LParenLoc,
2222 SourceLocation ModifierLoc,
2223 SourceLocation EndLoc) {
2224 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2225 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2226 }
2227
2228 /// Build a new OpenMP 'hint' clause.
2229 ///
2230 /// By default, performs semantic analysis to build the new statement.
2231 /// Subclasses may override this routine to provide different behavior.
2232 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2233 SourceLocation LParenLoc,
2234 SourceLocation EndLoc) {
2235 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2236 EndLoc);
2237 }
2238
2239 /// Build a new OpenMP 'detach' clause.
2240 ///
2241 /// By default, performs semantic analysis to build the new statement.
2242 /// Subclasses may override this routine to provide different behavior.
2243 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2244 SourceLocation LParenLoc,
2245 SourceLocation EndLoc) {
2246 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2247 EndLoc);
2248 }
2249
2250 /// Build a new OpenMP 'dist_schedule' clause.
2251 ///
2252 /// By default, performs semantic analysis to build the new OpenMP clause.
2253 /// Subclasses may override this routine to provide different behavior.
2254 OMPClause *
2255 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2256 Expr *ChunkSize, SourceLocation StartLoc,
2257 SourceLocation LParenLoc, SourceLocation KindLoc,
2258 SourceLocation CommaLoc, SourceLocation EndLoc) {
2259 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2260 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2261 }
2262
2263 /// Build a new OpenMP 'to' clause.
2264 ///
2265 /// By default, performs semantic analysis to build the new statement.
2266 /// Subclasses may override this routine to provide different behavior.
2267 OMPClause *
2268 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2269 ArrayRef<SourceLocation> MotionModifiersLoc,
2270 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2271 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2272 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2273 ArrayRef<Expr *> UnresolvedMappers) {
2274 return getSema().OpenMP().ActOnOpenMPToClause(
2275 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2276 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2277 UnresolvedMappers);
2278 }
2279
2280 /// Build a new OpenMP 'from' clause.
2281 ///
2282 /// By default, performs semantic analysis to build the new statement.
2283 /// Subclasses may override this routine to provide different behavior.
2284 OMPClause *
2285 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2286 ArrayRef<SourceLocation> MotionModifiersLoc,
2287 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2288 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2289 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2290 ArrayRef<Expr *> UnresolvedMappers) {
2291 return getSema().OpenMP().ActOnOpenMPFromClause(
2292 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2293 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2294 UnresolvedMappers);
2295 }
2296
2297 /// Build a new OpenMP 'use_device_ptr' clause.
2298 ///
2299 /// By default, performs semantic analysis to build the new OpenMP clause.
2300 /// Subclasses may override this routine to provide different behavior.
2301 OMPClause *RebuildOMPUseDevicePtrClause(
2302 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2303 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2304 SourceLocation FallbackModifierLoc) {
2305 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2306 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2307 }
2308
2309 /// Build a new OpenMP 'use_device_addr' clause.
2310 ///
2311 /// By default, performs semantic analysis to build the new OpenMP clause.
2312 /// Subclasses may override this routine to provide different behavior.
2313 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2314 const OMPVarListLocTy &Locs) {
2315 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2316 }
2317
2318 /// Build a new OpenMP 'is_device_ptr' clause.
2319 ///
2320 /// By default, performs semantic analysis to build the new OpenMP clause.
2321 /// Subclasses may override this routine to provide different behavior.
2322 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2323 const OMPVarListLocTy &Locs) {
2324 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2325 }
2326
2327 /// Build a new OpenMP 'has_device_addr' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
2331 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2332 const OMPVarListLocTy &Locs) {
2333 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2334 }
2335
2336 /// Build a new OpenMP 'defaultmap' clause.
2337 ///
2338 /// By default, performs semantic analysis to build the new OpenMP clause.
2339 /// Subclasses may override this routine to provide different behavior.
2340 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2341 OpenMPDefaultmapClauseKind Kind,
2342 SourceLocation StartLoc,
2343 SourceLocation LParenLoc,
2344 SourceLocation MLoc,
2345 SourceLocation KindLoc,
2346 SourceLocation EndLoc) {
2347 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2348 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2349 }
2350
2351 /// Build a new OpenMP 'nontemporal' clause.
2352 ///
2353 /// By default, performs semantic analysis to build the new OpenMP clause.
2354 /// Subclasses may override this routine to provide different behavior.
2355 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2356 SourceLocation StartLoc,
2357 SourceLocation LParenLoc,
2358 SourceLocation EndLoc) {
2359 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2360 LParenLoc, EndLoc);
2361 }
2362
2363 /// Build a new OpenMP 'inclusive' clause.
2364 ///
2365 /// By default, performs semantic analysis to build the new OpenMP clause.
2366 /// Subclasses may override this routine to provide different behavior.
2367 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2368 SourceLocation StartLoc,
2369 SourceLocation LParenLoc,
2370 SourceLocation EndLoc) {
2371 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2372 LParenLoc, EndLoc);
2373 }
2374
2375 /// Build a new OpenMP 'exclusive' clause.
2376 ///
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
2379 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2380 SourceLocation StartLoc,
2381 SourceLocation LParenLoc,
2382 SourceLocation EndLoc) {
2383 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2384 LParenLoc, EndLoc);
2385 }
2386
2387 /// Build a new OpenMP 'uses_allocators' clause.
2388 ///
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
2391 OMPClause *RebuildOMPUsesAllocatorsClause(
2392 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2393 SourceLocation LParenLoc, SourceLocation EndLoc) {
2394 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2395 StartLoc, LParenLoc, EndLoc, Data);
2396 }
2397
2398 /// Build a new OpenMP 'affinity' clause.
2399 ///
2400 /// By default, performs semantic analysis to build the new OpenMP clause.
2401 /// Subclasses may override this routine to provide different behavior.
2402 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2403 SourceLocation LParenLoc,
2404 SourceLocation ColonLoc,
2405 SourceLocation EndLoc, Expr *Modifier,
2406 ArrayRef<Expr *> Locators) {
2407 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2408 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2409 }
2410
2411 /// Build a new OpenMP 'order' clause.
2412 ///
2413 /// By default, performs semantic analysis to build the new OpenMP clause.
2414 /// Subclasses may override this routine to provide different behavior.
2415 OMPClause *RebuildOMPOrderClause(
2416 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2417 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2418 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2419 return getSema().OpenMP().ActOnOpenMPOrderClause(
2420 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2421 }
2422
2423 /// Build a new OpenMP 'init' clause.
2424 ///
2425 /// By default, performs semantic analysis to build the new OpenMP clause.
2426 /// Subclasses may override this routine to provide different behavior.
2427 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2428 SourceLocation StartLoc,
2429 SourceLocation LParenLoc,
2430 SourceLocation VarLoc,
2431 SourceLocation EndLoc) {
2432 return getSema().OpenMP().ActOnOpenMPInitClause(
2433 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2434 }
2435
2436 /// Build a new OpenMP 'use' clause.
2437 ///
2438 /// By default, performs semantic analysis to build the new OpenMP clause.
2439 /// Subclasses may override this routine to provide different behavior.
2440 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2441 SourceLocation LParenLoc,
2442 SourceLocation VarLoc, SourceLocation EndLoc) {
2443 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2444 LParenLoc, VarLoc, EndLoc);
2445 }
2446
2447 /// Build a new OpenMP 'destroy' clause.
2448 ///
2449 /// By default, performs semantic analysis to build the new OpenMP clause.
2450 /// Subclasses may override this routine to provide different behavior.
2451 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2452 SourceLocation LParenLoc,
2453 SourceLocation VarLoc,
2454 SourceLocation EndLoc) {
2455 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2456 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2457 }
2458
2459 /// Build a new OpenMP 'novariants' clause.
2460 ///
2461 /// By default, performs semantic analysis to build the new OpenMP clause.
2462 /// Subclasses may override this routine to provide different behavior.
2463 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2464 SourceLocation StartLoc,
2465 SourceLocation LParenLoc,
2466 SourceLocation EndLoc) {
2467 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2468 LParenLoc, EndLoc);
2469 }
2470
2471 /// Build a new OpenMP 'nocontext' clause.
2472 ///
2473 /// By default, performs semantic analysis to build the new OpenMP clause.
2474 /// Subclasses may override this routine to provide different behavior.
2475 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2476 SourceLocation LParenLoc,
2477 SourceLocation EndLoc) {
2478 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2479 LParenLoc, EndLoc);
2480 }
2481
2482 /// Build a new OpenMP 'filter' clause.
2483 ///
2484 /// By default, performs semantic analysis to build the new OpenMP clause.
2485 /// Subclasses may override this routine to provide different behavior.
2486 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2487 SourceLocation LParenLoc,
2488 SourceLocation EndLoc) {
2489 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2490 LParenLoc, EndLoc);
2491 }
2492
2493 /// Build a new OpenMP 'bind' clause.
2494 ///
2495 /// By default, performs semantic analysis to build the new OpenMP clause.
2496 /// Subclasses may override this routine to provide different behavior.
2497 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2498 SourceLocation KindLoc,
2499 SourceLocation StartLoc,
2500 SourceLocation LParenLoc,
2501 SourceLocation EndLoc) {
2502 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2503 LParenLoc, EndLoc);
2504 }
2505
2506 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2507 ///
2508 /// By default, performs semantic analysis to build the new OpenMP clause.
2509 /// Subclasses may override this routine to provide different behavior.
2510 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2511 SourceLocation LParenLoc,
2512 SourceLocation EndLoc) {
2513 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2514 LParenLoc, EndLoc);
2515 }
2516
2517 /// Build a new OpenMP 'dyn_groupprivate' clause.
2518 ///
2519 /// By default, performs semantic analysis to build the new OpenMP clause.
2520 /// Subclasses may override this routine to provide different behavior.
2521 OMPClause *RebuildOMPDynGroupprivateClause(
2522 OpenMPDynGroupprivateClauseModifier M1,
2523 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2524 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2525 SourceLocation M2Loc, SourceLocation EndLoc) {
2526 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2527 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2528 }
2529
2530 /// Build a new OpenMP 'ompx_attribute' clause.
2531 ///
2532 /// By default, performs semantic analysis to build the new OpenMP clause.
2533 /// Subclasses may override this routine to provide different behavior.
2534 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2535 SourceLocation StartLoc,
2536 SourceLocation LParenLoc,
2537 SourceLocation EndLoc) {
2538 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2539 LParenLoc, EndLoc);
2540 }
2541
2542 /// Build a new OpenMP 'ompx_bare' clause.
2543 ///
2544 /// By default, performs semantic analysis to build the new OpenMP clause.
2545 /// Subclasses may override this routine to provide different behavior.
2546 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2547 SourceLocation EndLoc) {
2548 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2549 }
2550
2551 /// Build a new OpenMP 'align' clause.
2552 ///
2553 /// By default, performs semantic analysis to build the new OpenMP clause.
2554 /// Subclasses may override this routine to provide different behavior.
2555 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2556 SourceLocation LParenLoc,
2557 SourceLocation EndLoc) {
2558 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2559 EndLoc);
2560 }
2561
2562 /// Build a new OpenMP 'at' clause.
2563 ///
2564 /// By default, performs semantic analysis to build the new OpenMP clause.
2565 /// Subclasses may override this routine to provide different behavior.
2566 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2567 SourceLocation StartLoc,
2568 SourceLocation LParenLoc,
2569 SourceLocation EndLoc) {
2570 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2571 LParenLoc, EndLoc);
2572 }
2573
2574 /// Build a new OpenMP 'severity' clause.
2575 ///
2576 /// By default, performs semantic analysis to build the new OpenMP clause.
2577 /// Subclasses may override this routine to provide different behavior.
2578 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2579 SourceLocation KwLoc,
2580 SourceLocation StartLoc,
2581 SourceLocation LParenLoc,
2582 SourceLocation EndLoc) {
2583 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2584 LParenLoc, EndLoc);
2585 }
2586
2587 /// Build a new OpenMP 'message' clause.
2588 ///
2589 /// By default, performs semantic analysis to build the new OpenMP clause.
2590 /// Subclasses may override this routine to provide different behavior.
2591 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2592 SourceLocation LParenLoc,
2593 SourceLocation EndLoc) {
2594 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2595 EndLoc);
2596 }
2597
2598 /// Build a new OpenMP 'doacross' clause.
2599 ///
2600 /// By default, performs semantic analysis to build the new OpenMP clause.
2601 /// Subclasses may override this routine to provide different behavior.
2602 OMPClause *
2603 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2604 SourceLocation DepLoc, SourceLocation ColonLoc,
2605 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2606 SourceLocation LParenLoc, SourceLocation EndLoc) {
2607 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2608 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2609 }
2610
2611 /// Build a new OpenMP 'holds' clause.
2612 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2613 SourceLocation LParenLoc,
2614 SourceLocation EndLoc) {
2615 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2616 EndLoc);
2617 }
2618
2619 /// Rebuild the operand to an Objective-C \@synchronized statement.
2620 ///
2621 /// By default, performs semantic analysis to build the new statement.
2622 /// Subclasses may override this routine to provide different behavior.
2623 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2624 Expr *object) {
2625 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2626 }
2627
2628 /// Build a new Objective-C \@synchronized statement.
2629 ///
2630 /// By default, performs semantic analysis to build the new statement.
2631 /// Subclasses may override this routine to provide different behavior.
2632 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2633 Expr *Object, Stmt *Body) {
2634 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2635 }
2636
2637 /// Build a new Objective-C \@autoreleasepool statement.
2638 ///
2639 /// By default, performs semantic analysis to build the new statement.
2640 /// Subclasses may override this routine to provide different behavior.
2641 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2642 Stmt *Body) {
2643 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2644 }
2645
2646 /// Build a new Objective-C fast enumeration statement.
2647 ///
2648 /// By default, performs semantic analysis to build the new statement.
2649 /// Subclasses may override this routine to provide different behavior.
2650 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2651 Stmt *Element,
2652 Expr *Collection,
2653 SourceLocation RParenLoc,
2654 Stmt *Body) {
2655 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2656 ForLoc, Element, Collection, RParenLoc);
2657 if (ForEachStmt.isInvalid())
2658 return StmtError();
2659
2660 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2661 Body);
2662 }
2663
2664 /// Build a new C++ exception declaration.
2665 ///
2666 /// By default, performs semantic analysis to build the new decaration.
2667 /// Subclasses may override this routine to provide different behavior.
2668 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2669 TypeSourceInfo *Declarator,
2670 SourceLocation StartLoc,
2671 SourceLocation IdLoc,
2672 IdentifierInfo *Id) {
2673 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2674 StartLoc, IdLoc, Id);
2675 if (Var)
2676 getSema().CurContext->addDecl(Var);
2677 return Var;
2678 }
2679
2680 /// Build a new C++ catch statement.
2681 ///
2682 /// By default, performs semantic analysis to build the new statement.
2683 /// Subclasses may override this routine to provide different behavior.
2684 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2685 VarDecl *ExceptionDecl,
2686 Stmt *Handler) {
2687 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2688 Handler));
2689 }
2690
2691 /// Build a new C++ try statement.
2692 ///
2693 /// By default, performs semantic analysis to build the new statement.
2694 /// Subclasses may override this routine to provide different behavior.
2695 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2696 ArrayRef<Stmt *> Handlers) {
2697 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2698 }
2699
2700 /// Build a new C++0x range-based for statement.
2701 ///
2702 /// By default, performs semantic analysis to build the new statement.
2703 /// Subclasses may override this routine to provide different behavior.
2704 StmtResult RebuildCXXForRangeStmt(
2705 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2706 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2707 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2708 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2709 // If we've just learned that the range is actually an Objective-C
2710 // collection, treat this as an Objective-C fast enumeration loop.
2711 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2712 if (RangeStmt->isSingleDecl()) {
2713 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2714 if (RangeVar->isInvalidDecl())
2715 return StmtError();
2716
2717 Expr *RangeExpr = RangeVar->getInit();
2718 if (!RangeExpr->isTypeDependent() &&
2719 RangeExpr->getType()->isObjCObjectPointerType()) {
2720 // FIXME: Support init-statements in Objective-C++20 ranged for
2721 // statement.
2722 if (Init) {
2723 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2724 DiagID: diag::err_objc_for_range_init_stmt)
2725 << Init->getSourceRange();
2726 }
2727 return getSema().ObjC().ActOnObjCForCollectionStmt(
2728 ForLoc, LoopVar, RangeExpr, RParenLoc);
2729 }
2730 }
2731 }
2732 }
2733
2734 return getSema().BuildCXXForRangeStmt(
2735 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2736 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2737 }
2738
2739 /// Build a new C++0x range-based for statement.
2740 ///
2741 /// By default, performs semantic analysis to build the new statement.
2742 /// Subclasses may override this routine to provide different behavior.
2743 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2744 bool IsIfExists,
2745 NestedNameSpecifierLoc QualifierLoc,
2746 DeclarationNameInfo NameInfo,
2747 Stmt *Nested) {
2748 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2749 QualifierLoc, NameInfo, Nested);
2750 }
2751
2752 /// Attach body to a C++0x range-based for statement.
2753 ///
2754 /// By default, performs semantic analysis to finish the new statement.
2755 /// Subclasses may override this routine to provide different behavior.
2756 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2757 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2758 }
2759
2760 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2761 Stmt *TryBlock, Stmt *Handler) {
2762 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2763 }
2764
2765 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2766 Stmt *Block) {
2767 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2768 }
2769
2770 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2771 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2772 }
2773
2774 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2775 SourceLocation LParen,
2776 SourceLocation RParen,
2777 TypeSourceInfo *TSI) {
2778 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2779 TSI);
2780 }
2781
2782 /// Build a new predefined expression.
2783 ///
2784 /// By default, performs semantic analysis to build the new expression.
2785 /// Subclasses may override this routine to provide different behavior.
2786 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2787 return getSema().BuildPredefinedExpr(Loc, IK);
2788 }
2789
2790 /// Build a new expression that references a declaration.
2791 ///
2792 /// By default, performs semantic analysis to build the new expression.
2793 /// Subclasses may override this routine to provide different behavior.
2794 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2795 LookupResult &R,
2796 bool RequiresADL) {
2797 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2798 }
2799
2800
2801 /// Build a new expression that references a declaration.
2802 ///
2803 /// By default, performs semantic analysis to build the new expression.
2804 /// Subclasses may override this routine to provide different behavior.
2805 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2806 ValueDecl *VD,
2807 const DeclarationNameInfo &NameInfo,
2808 NamedDecl *Found,
2809 TemplateArgumentListInfo *TemplateArgs) {
2810 CXXScopeSpec SS;
2811 SS.Adopt(Other: QualifierLoc);
2812 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2813 TemplateArgs);
2814 }
2815
2816 /// Build a new expression in parentheses.
2817 ///
2818 /// By default, performs semantic analysis to build the new expression.
2819 /// Subclasses may override this routine to provide different behavior.
2820 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2821 SourceLocation RParen) {
2822 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2823 }
2824
2825 /// Build a new pseudo-destructor expression.
2826 ///
2827 /// By default, performs semantic analysis to build the new expression.
2828 /// Subclasses may override this routine to provide different behavior.
2829 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2830 SourceLocation OperatorLoc,
2831 bool isArrow,
2832 CXXScopeSpec &SS,
2833 TypeSourceInfo *ScopeType,
2834 SourceLocation CCLoc,
2835 SourceLocation TildeLoc,
2836 PseudoDestructorTypeStorage Destroyed);
2837
2838 /// Build a new unary operator expression.
2839 ///
2840 /// By default, performs semantic analysis to build the new expression.
2841 /// Subclasses may override this routine to provide different behavior.
2842 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2843 UnaryOperatorKind Opc,
2844 Expr *SubExpr) {
2845 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2846 }
2847
2848 /// Build a new builtin offsetof expression.
2849 ///
2850 /// By default, performs semantic analysis to build the new expression.
2851 /// Subclasses may override this routine to provide different behavior.
2852 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2853 TypeSourceInfo *Type, const Designation &Desig,
2854 SourceLocation RParenLoc) {
2855 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2856 }
2857
2858 /// Build a new sizeof, alignof or vec_step expression with a
2859 /// type argument.
2860 ///
2861 /// By default, performs semantic analysis to build the new expression.
2862 /// Subclasses may override this routine to provide different behavior.
2863 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2864 SourceLocation OpLoc,
2865 UnaryExprOrTypeTrait ExprKind,
2866 SourceRange R) {
2867 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2868 }
2869
2870 /// Build a new sizeof, alignof or vec step expression with an
2871 /// expression argument.
2872 ///
2873 /// By default, performs semantic analysis to build the new expression.
2874 /// Subclasses may override this routine to provide different behavior.
2875 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2876 UnaryExprOrTypeTrait ExprKind,
2877 SourceRange R) {
2878 ExprResult Result
2879 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2880 if (Result.isInvalid())
2881 return ExprError();
2882
2883 return Result;
2884 }
2885
2886 /// Build a new array subscript expression.
2887 ///
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2890 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2891 SourceLocation LBracketLoc,
2892 Expr *RHS,
2893 SourceLocation RBracketLoc) {
2894 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2895 LBracketLoc, RHS,
2896 RBracketLoc);
2897 }
2898
2899 /// Build a new matrix single subscript expression.
2900 ///
2901 /// By default, performs semantic analysis to build the new expression.
2902 /// Subclasses may override this routine to provide different behavior.
2903 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2904 SourceLocation RBracketLoc) {
2905 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2906 RBracketLoc);
2907 }
2908
2909 /// Build a new matrix subscript expression.
2910 ///
2911 /// By default, performs semantic analysis to build the new expression.
2912 /// Subclasses may override this routine to provide different behavior.
2913 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2914 Expr *ColumnIdx,
2915 SourceLocation RBracketLoc) {
2916 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2917 RBracketLoc);
2918 }
2919
2920 /// Build a new array section expression.
2921 ///
2922 /// By default, performs semantic analysis to build the new expression.
2923 /// Subclasses may override this routine to provide different behavior.
2924 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2925 SourceLocation LBracketLoc,
2926 Expr *LowerBound,
2927 SourceLocation ColonLocFirst,
2928 SourceLocation ColonLocSecond,
2929 Expr *Length, Expr *Stride,
2930 SourceLocation RBracketLoc) {
2931 if (IsOMPArraySection)
2932 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2933 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2934 Stride, RBracketLoc);
2935
2936 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2937 "Stride/second colon not allowed for OpenACC");
2938
2939 return getSema().OpenACC().ActOnArraySectionExpr(
2940 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2941 }
2942
2943 /// Build a new array shaping expression.
2944 ///
2945 /// By default, performs semantic analysis to build the new expression.
2946 /// Subclasses may override this routine to provide different behavior.
2947 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2948 SourceLocation RParenLoc,
2949 ArrayRef<Expr *> Dims,
2950 ArrayRef<SourceRange> BracketsRanges) {
2951 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2952 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2953 }
2954
2955 /// Build a new iterator expression.
2956 ///
2957 /// By default, performs semantic analysis to build the new expression.
2958 /// Subclasses may override this routine to provide different behavior.
2959 ExprResult
2960 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2961 SourceLocation RLoc,
2962 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2963 return getSema().OpenMP().ActOnOMPIteratorExpr(
2964 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2965 }
2966
2967 /// Build a new call expression.
2968 ///
2969 /// By default, performs semantic analysis to build the new expression.
2970 /// Subclasses may override this routine to provide different behavior.
2971 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2972 MultiExprArg Args,
2973 SourceLocation RParenLoc,
2974 Expr *ExecConfig = nullptr) {
2975 return getSema().ActOnCallExpr(
2976 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2977 }
2978
2979 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2980 MultiExprArg Args,
2981 SourceLocation RParenLoc) {
2982 return getSema().ActOnArraySubscriptExpr(
2983 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2984 }
2985
2986 /// Build a new member access expression.
2987 ///
2988 /// By default, performs semantic analysis to build the new expression.
2989 /// Subclasses may override this routine to provide different behavior.
2990 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2991 bool isArrow,
2992 NestedNameSpecifierLoc QualifierLoc,
2993 SourceLocation TemplateKWLoc,
2994 const DeclarationNameInfo &MemberNameInfo,
2995 ValueDecl *Member,
2996 NamedDecl *FoundDecl,
2997 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2998 NamedDecl *FirstQualifierInScope) {
2999 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
3000 isArrow);
3001 if (!Member->getDeclName()) {
3002 // We have a reference to an unnamed field. This is always the
3003 // base of an anonymous struct/union member access, i.e. the
3004 // field is always of record type.
3005 assert(Member->getType()->isRecordType() &&
3006 "unnamed member not of record type?");
3007
3008 BaseResult =
3009 getSema().PerformObjectMemberConversion(BaseResult.get(),
3010 QualifierLoc.getNestedNameSpecifier(),
3011 FoundDecl, Member);
3012 if (BaseResult.isInvalid())
3013 return ExprError();
3014 Base = BaseResult.get();
3015
3016 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
3017 // from the AST, so we need to re-insert them if needed (since
3018 // `BuildFieldRefereneExpr()` doesn't do this).
3019 if (!isArrow && Base->isPRValue()) {
3020 BaseResult = getSema().TemporaryMaterializationConversion(Base);
3021 if (BaseResult.isInvalid())
3022 return ExprError();
3023 Base = BaseResult.get();
3024 }
3025
3026 CXXScopeSpec EmptySS;
3027 return getSema().BuildFieldReferenceExpr(
3028 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3029 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3030 MemberNameInfo);
3031 }
3032
3033 CXXScopeSpec SS;
3034 SS.Adopt(Other: QualifierLoc);
3035
3036 Base = BaseResult.get();
3037 if (Base->containsErrors())
3038 return ExprError();
3039
3040 QualType BaseType = Base->getType();
3041
3042 if (isArrow && !BaseType->isPointerType())
3043 return ExprError();
3044
3045 // FIXME: this involves duplicating earlier analysis in a lot of
3046 // cases; we should avoid this when possible.
3047 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3048 R.addDecl(D: FoundDecl);
3049 R.resolveKind();
3050
3051 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3052 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3053 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3054 ->getType()
3055 ->getPointeeType()
3056 ->getAsCXXRecordDecl()) {
3057 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3058 // In unevaluated contexts, an expression supposed to be a member access
3059 // might reference a member in an unrelated class.
3060 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3061 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3062 VK_LValue, Member->getLocation());
3063 }
3064 }
3065
3066 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3067 SS, TemplateKWLoc,
3068 FirstQualifierInScope,
3069 R, ExplicitTemplateArgs,
3070 /*S*/nullptr);
3071 }
3072
3073 /// Build a new binary operator expression.
3074 ///
3075 /// By default, performs semantic analysis to build the new expression.
3076 /// Subclasses may override this routine to provide different behavior.
3077 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3078 Expr *LHS, Expr *RHS,
3079 bool ForFoldExpression = false) {
3080 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3081 ForFoldExpression);
3082 }
3083
3084 /// Build a new rewritten operator expression.
3085 ///
3086 /// By default, performs semantic analysis to build the new expression.
3087 /// Subclasses may override this routine to provide different behavior.
3088 ExprResult RebuildCXXRewrittenBinaryOperator(
3089 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3090 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3091 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3092 RHS, /*RequiresADL*/false);
3093 }
3094
3095 /// Build a new conditional operator expression.
3096 ///
3097 /// By default, performs semantic analysis to build the new expression.
3098 /// Subclasses may override this routine to provide different behavior.
3099 ExprResult RebuildConditionalOperator(Expr *Cond,
3100 SourceLocation QuestionLoc,
3101 Expr *LHS,
3102 SourceLocation ColonLoc,
3103 Expr *RHS) {
3104 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3105 LHS, RHS);
3106 }
3107
3108 /// Build a new C-style cast expression.
3109 ///
3110 /// By default, performs semantic analysis to build the new expression.
3111 /// Subclasses may override this routine to provide different behavior.
3112 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3113 TypeSourceInfo *TInfo,
3114 SourceLocation RParenLoc,
3115 Expr *SubExpr) {
3116 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3117 SubExpr);
3118 }
3119
3120 /// Build a new compound literal expression.
3121 ///
3122 /// By default, performs semantic analysis to build the new expression.
3123 /// Subclasses may override this routine to provide different behavior.
3124 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3125 TypeSourceInfo *TInfo,
3126 SourceLocation RParenLoc,
3127 Expr *Init) {
3128 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3129 Init);
3130 }
3131
3132 /// Build a new extended vector or matrix element access expression.
3133 ///
3134 /// By default, performs semantic analysis to build the new expression.
3135 /// Subclasses may override this routine to provide different behavior.
3136 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3137 SourceLocation OpLoc,
3138 bool IsArrow,
3139 SourceLocation AccessorLoc,
3140 IdentifierInfo &Accessor) {
3141
3142 CXXScopeSpec SS;
3143 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3144 return getSema().BuildMemberReferenceExpr(
3145 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3146 /*FirstQualifierInScope*/ nullptr, NameInfo,
3147 /* TemplateArgs */ nullptr,
3148 /*S*/ nullptr);
3149 }
3150
3151 /// Build a new initializer list expression.
3152 ///
3153 /// By default, performs semantic analysis to build the new expression.
3154 /// Subclasses may override this routine to provide different behavior.
3155 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3156 SourceLocation RBraceLoc, bool IsExplicit) {
3157 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3158 }
3159
3160 /// Build a new designated initializer expression.
3161 ///
3162 /// By default, performs semantic analysis to build the new expression.
3163 /// Subclasses may override this routine to provide different behavior.
3164 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3165 MultiExprArg ArrayExprs,
3166 SourceLocation EqualOrColonLoc,
3167 bool GNUSyntax,
3168 Expr *Init) {
3169 ExprResult Result
3170 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3171 Init);
3172 if (Result.isInvalid())
3173 return ExprError();
3174
3175 return Result;
3176 }
3177
3178 /// Build a new value-initialized expression.
3179 ///
3180 /// By default, builds the implicit value initialization without performing
3181 /// any semantic analysis. Subclasses may override this routine to provide
3182 /// different behavior.
3183 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3184 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3185 }
3186
3187 /// Build a new \c va_arg expression.
3188 ///
3189 /// By default, performs semantic analysis to build the new expression.
3190 /// Subclasses may override this routine to provide different behavior.
3191 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3192 Expr *SubExpr, TypeSourceInfo *TInfo,
3193 SourceLocation RParenLoc) {
3194 return getSema().BuildVAArgExpr(BuiltinLoc,
3195 SubExpr, TInfo,
3196 RParenLoc);
3197 }
3198
3199 /// Build a new expression list in parentheses.
3200 ///
3201 /// By default, performs semantic analysis to build the new expression.
3202 /// Subclasses may override this routine to provide different behavior.
3203 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3204 MultiExprArg SubExprs,
3205 SourceLocation RParenLoc) {
3206 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3207 }
3208
3209 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3210 unsigned NumUserSpecifiedExprs,
3211 SourceLocation InitLoc,
3212 SourceLocation LParenLoc,
3213 SourceLocation RParenLoc) {
3214 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3215 InitLoc, LParenLoc, RParenLoc);
3216 }
3217
3218 /// Build a new address-of-label expression.
3219 ///
3220 /// By default, performs semantic analysis, using the name of the label
3221 /// rather than attempting to map the label statement itself.
3222 /// Subclasses may override this routine to provide different behavior.
3223 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3224 SourceLocation LabelLoc, LabelDecl *Label) {
3225 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3226 }
3227
3228 /// Build a new GNU statement expression.
3229 ///
3230 /// By default, performs semantic analysis to build the new expression.
3231 /// Subclasses may override this routine to provide different behavior.
3232 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3233 SourceLocation RParenLoc, unsigned TemplateDepth) {
3234 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3235 TemplateDepth);
3236 }
3237
3238 /// Build a new __builtin_choose_expr expression.
3239 ///
3240 /// By default, performs semantic analysis to build the new expression.
3241 /// Subclasses may override this routine to provide different behavior.
3242 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3243 Expr *Cond, Expr *LHS, Expr *RHS,
3244 SourceLocation RParenLoc) {
3245 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3246 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3247 RPLoc: RParenLoc);
3248 }
3249
3250 /// Build a new generic selection expression with an expression predicate.
3251 ///
3252 /// By default, performs semantic analysis to build the new expression.
3253 /// Subclasses may override this routine to provide different behavior.
3254 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3255 SourceLocation DefaultLoc,
3256 SourceLocation RParenLoc,
3257 Expr *ControllingExpr,
3258 ArrayRef<TypeSourceInfo *> Types,
3259 ArrayRef<Expr *> Exprs) {
3260 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3261 /*PredicateIsExpr=*/true,
3262 ControllingExpr, Types, Exprs);
3263 }
3264
3265 /// Build a new generic selection expression with a type predicate.
3266 ///
3267 /// By default, performs semantic analysis to build the new expression.
3268 /// Subclasses may override this routine to provide different behavior.
3269 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3270 SourceLocation DefaultLoc,
3271 SourceLocation RParenLoc,
3272 TypeSourceInfo *ControllingType,
3273 ArrayRef<TypeSourceInfo *> Types,
3274 ArrayRef<Expr *> Exprs) {
3275 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3276 /*PredicateIsExpr=*/false,
3277 ControllingType, Types, Exprs);
3278 }
3279
3280 /// Build a new overloaded operator call expression.
3281 ///
3282 /// By default, performs semantic analysis to build the new expression.
3283 /// The semantic analysis provides the behavior of template instantiation,
3284 /// copying with transformations that turn what looks like an overloaded
3285 /// operator call into a use of a builtin operator, performing
3286 /// argument-dependent lookup, etc. Subclasses may override this routine to
3287 /// provide different behavior.
3288 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3289 SourceLocation OpLoc,
3290 SourceLocation CalleeLoc,
3291 bool RequiresADL,
3292 const UnresolvedSetImpl &Functions,
3293 Expr *First, Expr *Second);
3294
3295 /// Build a new C++ "named" cast expression, such as static_cast or
3296 /// reinterpret_cast.
3297 ///
3298 /// By default, this routine dispatches to one of the more-specific routines
3299 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3300 /// Subclasses may override this routine to provide different behavior.
3301 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3302 Stmt::StmtClass Class,
3303 SourceLocation LAngleLoc,
3304 TypeSourceInfo *TInfo,
3305 SourceLocation RAngleLoc,
3306 SourceLocation LParenLoc,
3307 Expr *SubExpr,
3308 SourceLocation RParenLoc) {
3309 switch (Class) {
3310 case Stmt::CXXStaticCastExprClass:
3311 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3312 RAngleLoc, LParenLoc,
3313 SubExpr, RParenLoc);
3314
3315 case Stmt::CXXDynamicCastExprClass:
3316 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3317 RAngleLoc, LParenLoc,
3318 SubExpr, RParenLoc);
3319
3320 case Stmt::CXXReinterpretCastExprClass:
3321 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3322 RAngleLoc, LParenLoc,
3323 SubExpr,
3324 RParenLoc);
3325
3326 case Stmt::CXXConstCastExprClass:
3327 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3328 RAngleLoc, LParenLoc,
3329 SubExpr, RParenLoc);
3330
3331 case Stmt::CXXAddrspaceCastExprClass:
3332 return getDerived().RebuildCXXAddrspaceCastExpr(
3333 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3334
3335 default:
3336 llvm_unreachable("Invalid C++ named cast");
3337 }
3338 }
3339
3340 /// Build a new C++ static_cast expression.
3341 ///
3342 /// By default, performs semantic analysis to build the new expression.
3343 /// Subclasses may override this routine to provide different behavior.
3344 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3345 SourceLocation LAngleLoc,
3346 TypeSourceInfo *TInfo,
3347 SourceLocation RAngleLoc,
3348 SourceLocation LParenLoc,
3349 Expr *SubExpr,
3350 SourceLocation RParenLoc) {
3351 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3352 TInfo, SubExpr,
3353 SourceRange(LAngleLoc, RAngleLoc),
3354 SourceRange(LParenLoc, RParenLoc));
3355 }
3356
3357 /// Build a new C++ dynamic_cast expression.
3358 ///
3359 /// By default, performs semantic analysis to build the new expression.
3360 /// Subclasses may override this routine to provide different behavior.
3361 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3362 SourceLocation LAngleLoc,
3363 TypeSourceInfo *TInfo,
3364 SourceLocation RAngleLoc,
3365 SourceLocation LParenLoc,
3366 Expr *SubExpr,
3367 SourceLocation RParenLoc) {
3368 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3369 TInfo, SubExpr,
3370 SourceRange(LAngleLoc, RAngleLoc),
3371 SourceRange(LParenLoc, RParenLoc));
3372 }
3373
3374 /// Build a new C++ reinterpret_cast expression.
3375 ///
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
3378 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3379 SourceLocation LAngleLoc,
3380 TypeSourceInfo *TInfo,
3381 SourceLocation RAngleLoc,
3382 SourceLocation LParenLoc,
3383 Expr *SubExpr,
3384 SourceLocation RParenLoc) {
3385 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3386 TInfo, SubExpr,
3387 SourceRange(LAngleLoc, RAngleLoc),
3388 SourceRange(LParenLoc, RParenLoc));
3389 }
3390
3391 /// Build a new C++ const_cast expression.
3392 ///
3393 /// By default, performs semantic analysis to build the new expression.
3394 /// Subclasses may override this routine to provide different behavior.
3395 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3396 SourceLocation LAngleLoc,
3397 TypeSourceInfo *TInfo,
3398 SourceLocation RAngleLoc,
3399 SourceLocation LParenLoc,
3400 Expr *SubExpr,
3401 SourceLocation RParenLoc) {
3402 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3403 TInfo, SubExpr,
3404 SourceRange(LAngleLoc, RAngleLoc),
3405 SourceRange(LParenLoc, RParenLoc));
3406 }
3407
3408 ExprResult
3409 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3410 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3411 SourceLocation LParenLoc, Expr *SubExpr,
3412 SourceLocation RParenLoc) {
3413 return getSema().BuildCXXNamedCast(
3414 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3415 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3416 }
3417
3418 /// Build a new C++ functional-style cast expression.
3419 ///
3420 /// By default, performs semantic analysis to build the new expression.
3421 /// Subclasses may override this routine to provide different behavior.
3422 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3423 SourceLocation LParenLoc,
3424 Expr *Sub,
3425 SourceLocation RParenLoc,
3426 bool ListInitialization) {
3427 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3428 // CXXParenListInitExpr. Pass its expanded arguments so that the
3429 // CXXParenListInitExpr can be rebuilt.
3430 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3431 return getSema().BuildCXXTypeConstructExpr(
3432 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3433 RParenLoc, ListInitialization);
3434
3435 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3436 return getSema().BuildCXXTypeConstructExpr(
3437 TInfo, LParenLoc, PLE->getUserSpecifiedInitExprs(), RParenLoc,
3438 ListInitialization);
3439
3440 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3441 MultiExprArg(&Sub, 1), RParenLoc,
3442 ListInitialization);
3443 }
3444
3445 /// Build a new C++ __builtin_bit_cast expression.
3446 ///
3447 /// By default, performs semantic analysis to build the new expression.
3448 /// Subclasses may override this routine to provide different behavior.
3449 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3450 TypeSourceInfo *TSI, Expr *Sub,
3451 SourceLocation RParenLoc) {
3452 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3453 }
3454
3455 /// Build a new C++ typeid(type) expression.
3456 ///
3457 /// By default, performs semantic analysis to build the new expression.
3458 /// Subclasses may override this routine to provide different behavior.
3459 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3460 SourceLocation TypeidLoc,
3461 TypeSourceInfo *Operand,
3462 SourceLocation RParenLoc) {
3463 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3464 RParenLoc);
3465 }
3466
3467
3468 /// Build a new C++ typeid(expr) expression.
3469 ///
3470 /// By default, performs semantic analysis to build the new expression.
3471 /// Subclasses may override this routine to provide different behavior.
3472 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3473 SourceLocation TypeidLoc,
3474 Expr *Operand,
3475 SourceLocation RParenLoc) {
3476 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3477 RParenLoc);
3478 }
3479
3480 /// Build a new C++ __uuidof(type) expression.
3481 ///
3482 /// By default, performs semantic analysis to build the new expression.
3483 /// Subclasses may override this routine to provide different behavior.
3484 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3485 TypeSourceInfo *Operand,
3486 SourceLocation RParenLoc) {
3487 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3488 }
3489
3490 /// Build a new C++ __uuidof(expr) expression.
3491 ///
3492 /// By default, performs semantic analysis to build the new expression.
3493 /// Subclasses may override this routine to provide different behavior.
3494 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3495 Expr *Operand, SourceLocation RParenLoc) {
3496 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3497 }
3498
3499 /// Build a new C++ "this" expression.
3500 ///
3501 /// By default, performs semantic analysis to build a new "this" expression.
3502 /// Subclasses may override this routine to provide different behavior.
3503 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3504 QualType ThisType,
3505 bool isImplicit) {
3506 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3507 return ExprError();
3508 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3509 }
3510
3511 /// Build a new C++ throw expression.
3512 ///
3513 /// By default, performs semantic analysis to build the new expression.
3514 /// Subclasses may override this routine to provide different behavior.
3515 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3516 bool IsThrownVariableInScope) {
3517 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3518 }
3519
3520 /// Build a new C++ default-argument expression.
3521 ///
3522 /// By default, builds a new default-argument expression, which does not
3523 /// require any semantic analysis. Subclasses may override this routine to
3524 /// provide different behavior.
3525 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3526 Expr *RewrittenExpr) {
3527 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3528 RewrittenExpr, UsedContext: getSema().CurContext);
3529 }
3530
3531 /// Build a new C++11 default-initialization expression.
3532 ///
3533 /// By default, builds a new default field initialization expression, which
3534 /// does not require any semantic analysis. Subclasses may override this
3535 /// routine to provide different behavior.
3536 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field,
3537 Expr *RewrittenInit) {
3538 return CXXDefaultInitExpr::Create(Ctx: getSema().Context, Loc, Field,
3539 UsedContext: getSema().CurContext, RewrittenInitExpr: RewrittenInit);
3540 }
3541
3542 /// Build a new C++ zero-initialization expression.
3543 ///
3544 /// By default, performs semantic analysis to build the new expression.
3545 /// Subclasses may override this routine to provide different behavior.
3546 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3547 SourceLocation LParenLoc,
3548 SourceLocation RParenLoc) {
3549 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3550 /*ListInitialization=*/false);
3551 }
3552
3553 /// Build a new C++ "new" expression.
3554 ///
3555 /// By default, performs semantic analysis to build the new expression.
3556 /// Subclasses may override this routine to provide different behavior.
3557 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3558 SourceLocation PlacementLParen,
3559 MultiExprArg PlacementArgs,
3560 SourceLocation PlacementRParen,
3561 SourceRange TypeIdParens, QualType AllocatedType,
3562 TypeSourceInfo *AllocatedTypeInfo,
3563 std::optional<Expr *> ArraySize,
3564 SourceRange DirectInitRange, Expr *Initializer) {
3565 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3566 PlacementLParen,
3567 PlacementArgs,
3568 PlacementRParen,
3569 TypeIdParens,
3570 AllocatedType,
3571 AllocatedTypeInfo,
3572 ArraySize,
3573 DirectInitRange,
3574 Initializer);
3575 }
3576
3577 /// Build a new C++ "delete" expression.
3578 ///
3579 /// By default, performs semantic analysis to build the new expression.
3580 /// Subclasses may override this routine to provide different behavior.
3581 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3582 bool IsGlobalDelete,
3583 bool IsArrayForm,
3584 Expr *Operand) {
3585 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3586 Operand);
3587 }
3588
3589 /// Build a new type trait expression.
3590 ///
3591 /// By default, performs semantic analysis to build the new expression.
3592 /// Subclasses may override this routine to provide different behavior.
3593 ExprResult RebuildTypeTrait(TypeTrait Trait,
3594 SourceLocation StartLoc,
3595 ArrayRef<TypeSourceInfo *> Args,
3596 SourceLocation RParenLoc) {
3597 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3598 }
3599
3600 /// Build a new array type trait expression.
3601 ///
3602 /// By default, performs semantic analysis to build the new expression.
3603 /// Subclasses may override this routine to provide different behavior.
3604 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3605 SourceLocation StartLoc,
3606 TypeSourceInfo *TSInfo,
3607 Expr *DimExpr,
3608 SourceLocation RParenLoc) {
3609 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3610 }
3611
3612 /// Build a new expression trait expression.
3613 ///
3614 /// By default, performs semantic analysis to build the new expression.
3615 /// Subclasses may override this routine to provide different behavior.
3616 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3617 SourceLocation StartLoc,
3618 Expr *Queried,
3619 SourceLocation RParenLoc) {
3620 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3621 }
3622
3623 /// Build a new (previously unresolved) declaration reference
3624 /// expression.
3625 ///
3626 /// By default, performs semantic analysis to build the new expression.
3627 /// Subclasses may override this routine to provide different behavior.
3628 ExprResult RebuildDependentScopeDeclRefExpr(
3629 NestedNameSpecifierLoc QualifierLoc,
3630 SourceLocation TemplateKWLoc,
3631 const DeclarationNameInfo &NameInfo,
3632 const TemplateArgumentListInfo *TemplateArgs,
3633 bool IsAddressOfOperand,
3634 TypeSourceInfo **RecoveryTSI) {
3635 CXXScopeSpec SS;
3636 SS.Adopt(Other: QualifierLoc);
3637
3638 if (TemplateArgs || TemplateKWLoc.isValid())
3639 return getSema().BuildQualifiedTemplateIdExpr(
3640 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3641
3642 return getSema().BuildQualifiedDeclarationNameExpr(
3643 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3644 }
3645
3646 /// Build a new template-id expression.
3647 ///
3648 /// By default, performs semantic analysis to build the new expression.
3649 /// Subclasses may override this routine to provide different behavior.
3650 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3651 SourceLocation TemplateKWLoc,
3652 LookupResult &R,
3653 bool RequiresADL,
3654 const TemplateArgumentListInfo *TemplateArgs) {
3655 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3656 TemplateArgs);
3657 }
3658
3659 /// Build a new object-construction expression.
3660 ///
3661 /// By default, performs semantic analysis to build the new expression.
3662 /// Subclasses may override this routine to provide different behavior.
3663 ExprResult RebuildCXXConstructExpr(
3664 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3665 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3666 bool ListInitialization, bool StdInitListInitialization,
3667 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3668 SourceRange ParenRange) {
3669 // Reconstruct the constructor we originally found, which might be
3670 // different if this is a call to an inherited constructor.
3671 CXXConstructorDecl *FoundCtor = Constructor;
3672 if (Constructor->isInheritingConstructor())
3673 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3674
3675 SmallVector<Expr *, 8> ConvertedArgs;
3676 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3677 ConvertedArgs))
3678 return ExprError();
3679
3680 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3681 IsElidable,
3682 ConvertedArgs,
3683 HadMultipleCandidates,
3684 ListInitialization,
3685 StdInitListInitialization,
3686 RequiresZeroInit, ConstructKind,
3687 ParenRange);
3688 }
3689
3690 /// Build a new implicit construction via inherited constructor
3691 /// expression.
3692 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3693 CXXConstructorDecl *Constructor,
3694 bool ConstructsVBase,
3695 bool InheritedFromVBase) {
3696 return new (getSema().Context) CXXInheritedCtorInitExpr(
3697 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3698 }
3699
3700 /// Build a new object-construction expression.
3701 ///
3702 /// By default, performs semantic analysis to build the new expression.
3703 /// Subclasses may override this routine to provide different behavior.
3704 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3705 SourceLocation LParenOrBraceLoc,
3706 MultiExprArg Args,
3707 SourceLocation RParenOrBraceLoc,
3708 bool ListInitialization) {
3709 return getSema().BuildCXXTypeConstructExpr(
3710 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3711 }
3712
3713 /// Build a new object-construction expression.
3714 ///
3715 /// By default, performs semantic analysis to build the new expression.
3716 /// Subclasses may override this routine to provide different behavior.
3717 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3718 SourceLocation LParenLoc,
3719 MultiExprArg Args,
3720 SourceLocation RParenLoc,
3721 bool ListInitialization) {
3722 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3723 RParenLoc, ListInitialization);
3724 }
3725
3726 /// Build a new member reference expression.
3727 ///
3728 /// By default, performs semantic analysis to build the new expression.
3729 /// Subclasses may override this routine to provide different behavior.
3730 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3731 QualType BaseType,
3732 bool IsArrow,
3733 SourceLocation OperatorLoc,
3734 NestedNameSpecifierLoc QualifierLoc,
3735 SourceLocation TemplateKWLoc,
3736 NamedDecl *FirstQualifierInScope,
3737 const DeclarationNameInfo &MemberNameInfo,
3738 const TemplateArgumentListInfo *TemplateArgs) {
3739 CXXScopeSpec SS;
3740 SS.Adopt(Other: QualifierLoc);
3741
3742 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3743 OpLoc: OperatorLoc, IsArrow,
3744 SS, TemplateKWLoc,
3745 FirstQualifierInScope,
3746 NameInfo: MemberNameInfo,
3747 TemplateArgs, /*S*/S: nullptr);
3748 }
3749
3750 /// Build a new member reference expression.
3751 ///
3752 /// By default, performs semantic analysis to build the new expression.
3753 /// Subclasses may override this routine to provide different behavior.
3754 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3755 SourceLocation OperatorLoc,
3756 bool IsArrow,
3757 NestedNameSpecifierLoc QualifierLoc,
3758 SourceLocation TemplateKWLoc,
3759 NamedDecl *FirstQualifierInScope,
3760 LookupResult &R,
3761 const TemplateArgumentListInfo *TemplateArgs) {
3762 CXXScopeSpec SS;
3763 SS.Adopt(Other: QualifierLoc);
3764
3765 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3766 OpLoc: OperatorLoc, IsArrow,
3767 SS, TemplateKWLoc,
3768 FirstQualifierInScope,
3769 R, TemplateArgs, /*S*/S: nullptr);
3770 }
3771
3772 /// Build a new noexcept expression.
3773 ///
3774 /// By default, performs semantic analysis to build the new expression.
3775 /// Subclasses may override this routine to provide different behavior.
3776 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3777 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3778 }
3779
3780 UnsignedOrNone
3781 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3782
3783 /// Build a new expression to compute the length of a parameter pack.
3784 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3785 SourceLocation PackLoc,
3786 SourceLocation RParenLoc,
3787 UnsignedOrNone Length,
3788 ArrayRef<TemplateArgument> PartialArgs) {
3789 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3790 RParenLoc, Length, PartialArgs);
3791 }
3792
3793 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3794 SourceLocation RSquareLoc,
3795 Expr *PackIdExpression, Expr *IndexExpr,
3796 ArrayRef<Expr *> ExpandedExprs,
3797 bool FullySubstituted = false) {
3798 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3799 IndexExpr, RSquareLoc, ExpandedExprs,
3800 FullySubstituted);
3801 }
3802
3803 /// Build a new expression representing a call to a source location
3804 /// builtin.
3805 ///
3806 /// By default, performs semantic analysis to build the new expression.
3807 /// Subclasses may override this routine to provide different behavior.
3808 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3809 SourceLocation BuiltinLoc,
3810 SourceLocation RPLoc,
3811 DeclContext *ParentContext) {
3812 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3813 ParentContext);
3814 }
3815
3816 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3817 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3818 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3819 TemplateArgumentListInfo *TALI) {
3820 CXXScopeSpec SS;
3821 SS.Adopt(Other: NNS);
3822 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3823 ConceptNameInfo,
3824 FoundDecl,
3825 NamedConcept, TALI);
3826 if (Result.isInvalid())
3827 return ExprError();
3828 return Result;
3829 }
3830
3831 /// \brief Build a new requires expression.
3832 ///
3833 /// By default, performs semantic analysis to build the new expression.
3834 /// Subclasses may override this routine to provide different behavior.
3835 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3836 RequiresExprBodyDecl *Body,
3837 SourceLocation LParenLoc,
3838 ArrayRef<ParmVarDecl *> LocalParameters,
3839 SourceLocation RParenLoc,
3840 ArrayRef<concepts::Requirement *> Requirements,
3841 SourceLocation ClosingBraceLoc) {
3842 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3843 LocalParameters, RParenLoc, Requirements,
3844 RBraceLoc: ClosingBraceLoc);
3845 }
3846
3847 concepts::TypeRequirement *
3848 RebuildTypeRequirement(
3849 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3850 return SemaRef.BuildTypeRequirement(SubstDiag);
3851 }
3852
3853 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3854 return SemaRef.BuildTypeRequirement(Type: T);
3855 }
3856
3857 concepts::ExprRequirement *
3858 RebuildExprRequirement(
3859 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3860 SourceLocation NoexceptLoc,
3861 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3862 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3863 ReturnTypeRequirement: std::move(Ret));
3864 }
3865
3866 concepts::ExprRequirement *
3867 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3868 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3869 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3870 ReturnTypeRequirement: std::move(Ret));
3871 }
3872
3873 concepts::NestedRequirement *
3874 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3875 const ASTConstraintSatisfaction &Satisfaction) {
3876 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3877 Satisfaction);
3878 }
3879
3880 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3881 return SemaRef.BuildNestedRequirement(E: Constraint);
3882 }
3883
3884 /// \brief Build a new Objective-C boxed expression.
3885 ///
3886 /// By default, performs semantic analysis to build the new expression.
3887 /// Subclasses may override this routine to provide different behavior.
3888 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3889 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3890 }
3891
3892 /// Build a new Objective-C array literal.
3893 ///
3894 /// By default, performs semantic analysis to build the new expression.
3895 /// Subclasses may override this routine to provide different behavior.
3896 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3897 Expr **Elements, unsigned NumElements) {
3898 return getSema().ObjC().BuildObjCArrayLiteral(
3899 Range, MultiExprArg(Elements, NumElements));
3900 }
3901
3902 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3903 Expr *Base, Expr *Key,
3904 ObjCMethodDecl *getterMethod,
3905 ObjCMethodDecl *setterMethod) {
3906 return getSema().ObjC().BuildObjCSubscriptExpression(
3907 RB, Base, Key, getterMethod, setterMethod);
3908 }
3909
3910 /// Build a new Objective-C dictionary literal.
3911 ///
3912 /// By default, performs semantic analysis to build the new expression.
3913 /// Subclasses may override this routine to provide different behavior.
3914 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3915 MutableArrayRef<ObjCDictionaryElement> Elements) {
3916 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3917 }
3918
3919 /// Build a new Objective-C \@encode expression.
3920 ///
3921 /// By default, performs semantic analysis to build the new expression.
3922 /// Subclasses may override this routine to provide different behavior.
3923 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3924 TypeSourceInfo *EncodeTypeInfo,
3925 SourceLocation RParenLoc) {
3926 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3927 RParenLoc);
3928 }
3929
3930 /// Build a new Objective-C class message.
3931 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3932 Selector Sel,
3933 ArrayRef<SourceLocation> SelectorLocs,
3934 ObjCMethodDecl *Method,
3935 SourceLocation LBracLoc,
3936 MultiExprArg Args,
3937 SourceLocation RBracLoc) {
3938 return SemaRef.ObjC().BuildClassMessage(
3939 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3940 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3941 RBracLoc, Args);
3942 }
3943
3944 /// Build a new Objective-C instance message.
3945 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3946 Selector Sel,
3947 ArrayRef<SourceLocation> SelectorLocs,
3948 ObjCMethodDecl *Method,
3949 SourceLocation LBracLoc,
3950 MultiExprArg Args,
3951 SourceLocation RBracLoc) {
3952 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3953 /*SuperLoc=*/SuperLoc: SourceLocation(),
3954 Sel, Method, LBracLoc,
3955 SelectorLocs, RBracLoc, Args);
3956 }
3957
3958 /// Build a new Objective-C instance/class message to 'super'.
3959 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3960 Selector Sel,
3961 ArrayRef<SourceLocation> SelectorLocs,
3962 QualType SuperType,
3963 ObjCMethodDecl *Method,
3964 SourceLocation LBracLoc,
3965 MultiExprArg Args,
3966 SourceLocation RBracLoc) {
3967 return Method->isInstanceMethod()
3968 ? SemaRef.ObjC().BuildInstanceMessage(
3969 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3970 SelectorLocs, RBracLoc, Args)
3971 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3972 Sel, Method, LBracLoc,
3973 SelectorLocs, RBracLoc, Args);
3974 }
3975
3976 /// Build a new Objective-C ivar reference expression.
3977 ///
3978 /// By default, performs semantic analysis to build the new expression.
3979 /// Subclasses may override this routine to provide different behavior.
3980 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3981 SourceLocation IvarLoc,
3982 bool IsArrow, bool IsFreeIvar) {
3983 CXXScopeSpec SS;
3984 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3985 ExprResult Result = getSema().BuildMemberReferenceExpr(
3986 BaseArg, BaseArg->getType(),
3987 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3988 /*FirstQualifierInScope=*/nullptr, NameInfo,
3989 /*TemplateArgs=*/nullptr,
3990 /*S=*/nullptr);
3991 if (IsFreeIvar && Result.isUsable())
3992 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3993 return Result;
3994 }
3995
3996 /// Build a new Objective-C property reference expression.
3997 ///
3998 /// By default, performs semantic analysis to build the new expression.
3999 /// Subclasses may override this routine to provide different behavior.
4000 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
4001 ObjCPropertyDecl *Property,
4002 SourceLocation PropertyLoc) {
4003 CXXScopeSpec SS;
4004 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
4005 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4006 /*FIXME:*/PropertyLoc,
4007 /*IsArrow=*/false,
4008 SS, SourceLocation(),
4009 /*FirstQualifierInScope=*/nullptr,
4010 NameInfo,
4011 /*TemplateArgs=*/nullptr,
4012 /*S=*/nullptr);
4013 }
4014
4015 /// Build a new Objective-C property reference expression.
4016 ///
4017 /// By default, performs semantic analysis to build the new expression.
4018 /// Subclasses may override this routine to provide different behavior.
4019 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
4020 ObjCMethodDecl *Getter,
4021 ObjCMethodDecl *Setter,
4022 SourceLocation PropertyLoc) {
4023 // Since these expressions can only be value-dependent, we do not
4024 // need to perform semantic analysis again.
4025 return Owned(
4026 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4027 VK_LValue, OK_ObjCProperty,
4028 PropertyLoc, Base));
4029 }
4030
4031 /// Build a new Objective-C "isa" expression.
4032 ///
4033 /// By default, performs semantic analysis to build the new expression.
4034 /// Subclasses may override this routine to provide different behavior.
4035 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4036 SourceLocation OpLoc, bool IsArrow) {
4037 CXXScopeSpec SS;
4038 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4039 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4040 OpLoc, IsArrow,
4041 SS, SourceLocation(),
4042 /*FirstQualifierInScope=*/nullptr,
4043 NameInfo,
4044 /*TemplateArgs=*/nullptr,
4045 /*S=*/nullptr);
4046 }
4047
4048 /// Build a new shuffle vector expression.
4049 ///
4050 /// By default, performs semantic analysis to build the new expression.
4051 /// Subclasses may override this routine to provide different behavior.
4052 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4053 MultiExprArg SubExprs,
4054 SourceLocation RParenLoc) {
4055 // Find the declaration for __builtin_shufflevector
4056 const IdentifierInfo &Name
4057 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4058 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4059 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4060 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4061
4062 // Build a reference to the __builtin_shufflevector builtin
4063 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4064 Expr *Callee = new (SemaRef.Context)
4065 DeclRefExpr(SemaRef.Context, Builtin, false,
4066 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4067 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4068 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4069 CK: CK_BuiltinFnToFnPtr).get();
4070
4071 // Build the CallExpr
4072 ExprResult TheCall = CallExpr::Create(
4073 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4074 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4075 FPFeatures: FPOptionsOverride());
4076
4077 // Type-check the __builtin_shufflevector expression.
4078 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4079 }
4080
4081 /// Build a new convert vector expression.
4082 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4083 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4084 SourceLocation RParenLoc) {
4085 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4086 }
4087
4088 /// Build a new template argument pack expansion.
4089 ///
4090 /// By default, performs semantic analysis to build a new pack expansion
4091 /// for a template argument. Subclasses may override this routine to provide
4092 /// different behavior.
4093 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4094 SourceLocation EllipsisLoc,
4095 UnsignedOrNone NumExpansions) {
4096 switch (Pattern.getArgument().getKind()) {
4097 case TemplateArgument::Expression: {
4098 ExprResult Result
4099 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4100 EllipsisLoc, NumExpansions);
4101 if (Result.isInvalid())
4102 return TemplateArgumentLoc();
4103
4104 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4105 /*IsCanonical=*/false),
4106 Result.get());
4107 }
4108
4109 case TemplateArgument::Template:
4110 return TemplateArgumentLoc(
4111 SemaRef.Context,
4112 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4113 NumExpansions),
4114 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4115 Pattern.getTemplateNameLoc(), EllipsisLoc);
4116
4117 case TemplateArgument::Null:
4118 case TemplateArgument::Integral:
4119 case TemplateArgument::Declaration:
4120 case TemplateArgument::StructuralValue:
4121 case TemplateArgument::Pack:
4122 case TemplateArgument::TemplateExpansion:
4123 case TemplateArgument::NullPtr:
4124 llvm_unreachable("Pack expansion pattern has no parameter packs");
4125
4126 case TemplateArgument::Type:
4127 if (TypeSourceInfo *Expansion
4128 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4129 EllipsisLoc,
4130 NumExpansions))
4131 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4132 Expansion);
4133 break;
4134 }
4135
4136 return TemplateArgumentLoc();
4137 }
4138
4139 /// Build a new expression pack expansion.
4140 ///
4141 /// By default, performs semantic analysis to build a new pack expansion
4142 /// for an expression. Subclasses may override this routine to provide
4143 /// different behavior.
4144 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4145 UnsignedOrNone NumExpansions) {
4146 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4147 }
4148
4149 /// Build a new C++1z fold-expression.
4150 ///
4151 /// By default, performs semantic analysis in order to build a new fold
4152 /// expression.
4153 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4154 SourceLocation LParenLoc, Expr *LHS,
4155 BinaryOperatorKind Operator,
4156 SourceLocation EllipsisLoc, Expr *RHS,
4157 SourceLocation RParenLoc,
4158 UnsignedOrNone NumExpansions) {
4159 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4160 EllipsisLoc, RHS, RParenLoc,
4161 NumExpansions);
4162 }
4163
4164 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4165 LambdaScopeInfo *LSI) {
4166 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4167 if (Expr *Init = PVD->getInit())
4168 LSI->ContainsUnexpandedParameterPack |=
4169 Init->containsUnexpandedParameterPack();
4170 else if (PVD->hasUninstantiatedDefaultArg())
4171 LSI->ContainsUnexpandedParameterPack |=
4172 PVD->getUninstantiatedDefaultArg()
4173 ->containsUnexpandedParameterPack();
4174 }
4175 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4176 }
4177
4178 /// Build an empty C++1z fold-expression with the given operator.
4179 ///
4180 /// By default, produces the fallback value for the fold-expression, or
4181 /// produce an error if there is no fallback value.
4182 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4183 BinaryOperatorKind Operator) {
4184 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4185 }
4186
4187 /// Build a new atomic operation expression.
4188 ///
4189 /// By default, performs semantic analysis to build the new expression.
4190 /// Subclasses may override this routine to provide different behavior.
4191 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4192 AtomicExpr::AtomicOp Op,
4193 SourceLocation RParenLoc) {
4194 // Use this for all of the locations, since we don't know the difference
4195 // between the call and the expr at this point.
4196 SourceRange Range{BuiltinLoc, RParenLoc};
4197 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4198 Sema::AtomicArgumentOrder::AST);
4199 }
4200
4201 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4202 ArrayRef<Expr *> SubExprs, QualType Type) {
4203 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4204 }
4205
4206 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4207 SourceLocation BeginLoc,
4208 SourceLocation DirLoc,
4209 SourceLocation EndLoc,
4210 ArrayRef<OpenACCClause *> Clauses,
4211 StmtResult StrBlock) {
4212 return getSema().OpenACC().ActOnEndStmtDirective(
4213 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4214 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4215 }
4216
4217 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4218 SourceLocation DirLoc,
4219 SourceLocation EndLoc,
4220 ArrayRef<OpenACCClause *> Clauses,
4221 StmtResult Loop) {
4222 return getSema().OpenACC().ActOnEndStmtDirective(
4223 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4224 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4225 Clauses, Loop);
4226 }
4227
4228 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4229 SourceLocation BeginLoc,
4230 SourceLocation DirLoc,
4231 SourceLocation EndLoc,
4232 ArrayRef<OpenACCClause *> Clauses,
4233 StmtResult Loop) {
4234 return getSema().OpenACC().ActOnEndStmtDirective(
4235 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4236 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4237 }
4238
4239 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4240 SourceLocation DirLoc,
4241 SourceLocation EndLoc,
4242 ArrayRef<OpenACCClause *> Clauses,
4243 StmtResult StrBlock) {
4244 return getSema().OpenACC().ActOnEndStmtDirective(
4245 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4246 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4247 Clauses, StrBlock);
4248 }
4249
4250 StmtResult
4251 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4252 SourceLocation DirLoc, SourceLocation EndLoc,
4253 ArrayRef<OpenACCClause *> Clauses) {
4254 return getSema().OpenACC().ActOnEndStmtDirective(
4255 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4256 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4257 Clauses, {});
4258 }
4259
4260 StmtResult
4261 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4262 SourceLocation DirLoc, SourceLocation EndLoc,
4263 ArrayRef<OpenACCClause *> Clauses) {
4264 return getSema().OpenACC().ActOnEndStmtDirective(
4265 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4266 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4267 Clauses, {});
4268 }
4269
4270 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4271 SourceLocation DirLoc,
4272 SourceLocation EndLoc,
4273 ArrayRef<OpenACCClause *> Clauses,
4274 StmtResult StrBlock) {
4275 return getSema().OpenACC().ActOnEndStmtDirective(
4276 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4277 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4278 Clauses, StrBlock);
4279 }
4280
4281 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4282 SourceLocation DirLoc,
4283 SourceLocation EndLoc,
4284 ArrayRef<OpenACCClause *> Clauses) {
4285 return getSema().OpenACC().ActOnEndStmtDirective(
4286 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4287 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4288 Clauses, {});
4289 }
4290
4291 StmtResult
4292 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4293 SourceLocation DirLoc, SourceLocation EndLoc,
4294 ArrayRef<OpenACCClause *> Clauses) {
4295 return getSema().OpenACC().ActOnEndStmtDirective(
4296 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4297 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4298 Clauses, {});
4299 }
4300
4301 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4302 SourceLocation DirLoc,
4303 SourceLocation EndLoc,
4304 ArrayRef<OpenACCClause *> Clauses) {
4305 return getSema().OpenACC().ActOnEndStmtDirective(
4306 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4307 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4308 Clauses, {});
4309 }
4310
4311 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4312 SourceLocation DirLoc,
4313 SourceLocation EndLoc,
4314 ArrayRef<OpenACCClause *> Clauses) {
4315 return getSema().OpenACC().ActOnEndStmtDirective(
4316 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4317 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4318 Clauses, {});
4319 }
4320
4321 StmtResult RebuildOpenACCWaitConstruct(
4322 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4323 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4324 SourceLocation RParenLoc, SourceLocation EndLoc,
4325 ArrayRef<OpenACCClause *> Clauses) {
4326 llvm::SmallVector<Expr *> Exprs;
4327 Exprs.push_back(Elt: DevNumExpr);
4328 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4329 return getSema().OpenACC().ActOnEndStmtDirective(
4330 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4331 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4332 }
4333
4334 StmtResult RebuildOpenACCCacheConstruct(
4335 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4336 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4337 SourceLocation RParenLoc, SourceLocation EndLoc) {
4338 return getSema().OpenACC().ActOnEndStmtDirective(
4339 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4340 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4341 }
4342
4343 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4344 SourceLocation DirLoc,
4345 OpenACCAtomicKind AtKind,
4346 SourceLocation EndLoc,
4347 ArrayRef<OpenACCClause *> Clauses,
4348 StmtResult AssociatedStmt) {
4349 return getSema().OpenACC().ActOnEndStmtDirective(
4350 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4351 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4352 AssociatedStmt);
4353 }
4354
4355 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4356 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4357 }
4358
4359 ExprResult
4360 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4361 QualType ParamType, SourceLocation Loc,
4362 TemplateArgument Arg,
4363 UnsignedOrNone PackIndex, bool Final) {
4364 return getSema().BuildSubstNonTypeTemplateParmExpr(
4365 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4366 }
4367
4368 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4369 SourceLocation StartLoc,
4370 SourceLocation LParenLoc,
4371 SourceLocation EndLoc) {
4372 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4373 LParenLoc, EndLoc);
4374 }
4375
4376private:
4377 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4378 QualType ObjectType,
4379 NamedDecl *FirstQualifierInScope);
4380
4381 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4382 QualType ObjectType,
4383 NamedDecl *FirstQualifierInScope) {
4384 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4385 return TSInfo;
4386
4387 TypeLocBuilder TLB;
4388 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4389 ObjectType, FirstQualifierInScope);
4390 if (T.isNull())
4391 return nullptr;
4392 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4393 }
4394
4395 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4396 DependentNameTypeLoc TL,
4397 bool DeducibleTSTContext,
4398 QualType ObjectType = QualType(),
4399 NamedDecl *UnqualLookup = nullptr);
4400
4401 llvm::SmallVector<OpenACCClause *>
4402 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4403 ArrayRef<const OpenACCClause *> OldClauses);
4404
4405 OpenACCClause *
4406 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4407 OpenACCDirectiveKind DirKind,
4408 const OpenACCClause *OldClause);
4409};
4410
4411template <typename Derived>
4412StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4413 if (!S)
4414 return S;
4415
4416 switch (S->getStmtClass()) {
4417 case Stmt::NoStmtClass: break;
4418
4419 // Transform individual statement nodes
4420 // Pass SDK into statements that can produce a value
4421#define STMT(Node, Parent) \
4422 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4423#define VALUESTMT(Node, Parent) \
4424 case Stmt::Node##Class: \
4425 return getDerived().Transform##Node(cast<Node>(S), SDK);
4426#define ABSTRACT_STMT(Node)
4427#define EXPR(Node, Parent)
4428#include "clang/AST/StmtNodes.inc"
4429
4430 // Transform expressions by calling TransformExpr.
4431#define STMT(Node, Parent)
4432#define ABSTRACT_STMT(Stmt)
4433#define EXPR(Node, Parent) case Stmt::Node##Class:
4434#include "clang/AST/StmtNodes.inc"
4435 {
4436 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4437
4438 if (SDK == StmtDiscardKind::StmtExprResult)
4439 E = getSema().ActOnStmtExprResult(E);
4440 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4441 }
4442 }
4443
4444 return S;
4445}
4446
4447template<typename Derived>
4448OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4449 if (!S)
4450 return S;
4451
4452 switch (S->getClauseKind()) {
4453 default: break;
4454 // Transform individual clause nodes
4455#define GEN_CLANG_CLAUSE_CLASS
4456#define CLAUSE_CLASS(Enum, Str, Class) \
4457 case Enum: \
4458 return getDerived().Transform##Class(cast<Class>(S));
4459#include "llvm/Frontend/OpenMP/OMP.inc"
4460 }
4461
4462 return S;
4463}
4464
4465
4466template<typename Derived>
4467ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4468 if (!E)
4469 return E;
4470
4471 switch (E->getStmtClass()) {
4472 case Stmt::NoStmtClass: break;
4473#define STMT(Node, Parent) case Stmt::Node##Class: break;
4474#define ABSTRACT_STMT(Stmt)
4475#define EXPR(Node, Parent) \
4476 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4477#include "clang/AST/StmtNodes.inc"
4478 }
4479
4480 return E;
4481}
4482
4483template<typename Derived>
4484ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4485 bool NotCopyInit) {
4486 // Initializers are instantiated like expressions, except that various outer
4487 // layers are stripped.
4488 if (!Init)
4489 return Init;
4490
4491 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4492 Init = FE->getSubExpr();
4493
4494 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4495 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4496 Init = OVE->getSourceExpr();
4497 }
4498
4499 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4500 Init = MTE->getSubExpr();
4501
4502 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4503 Init = Binder->getSubExpr();
4504
4505 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4506 Init = ICE->getSubExprAsWritten();
4507
4508 if (CXXStdInitializerListExpr *ILE =
4509 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4510 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4511
4512 // If this is copy-initialization, we only need to reconstruct
4513 // InitListExprs. Other forms of copy-initialization will be a no-op if
4514 // the initializer is already the right type.
4515 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4516 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4517 return getDerived().TransformExpr(Init);
4518
4519 // Revert value-initialization back to empty parens.
4520 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4521 SourceRange Parens = VIE->getSourceRange();
4522 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4523 Parens.getEnd());
4524 }
4525
4526 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4527 if (isa<ImplicitValueInitExpr>(Val: Init))
4528 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4529 SourceLocation());
4530
4531 // Revert initialization by constructor back to a parenthesized or braced list
4532 // of expressions. Any other form of initializer can just be reused directly.
4533 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4534 return getDerived().TransformExpr(Init);
4535
4536 // If the initialization implicitly converted an initializer list to a
4537 // std::initializer_list object, unwrap the std::initializer_list too.
4538 if (Construct && Construct->isStdInitListInitialization())
4539 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4540
4541 // Enter a list-init context if this was list initialization.
4542 EnterExpressionEvaluationContext Context(
4543 getSema(), EnterExpressionEvaluationContext::InitList,
4544 Construct->isListInitialization());
4545
4546 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4547 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4548 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4549 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4550 SmallVector<Expr*, 8> NewArgs;
4551 bool ArgChanged = false;
4552 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4553 /*IsCall*/true, NewArgs, &ArgChanged))
4554 return ExprError();
4555
4556 // If this was list initialization, revert to syntactic list form.
4557 if (Construct->isListInitialization())
4558 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4559 Construct->getEndLoc(),
4560 /*IsExplicit=*/true);
4561
4562 // Build a ParenListExpr to represent anything else.
4563 SourceRange Parens = Construct->getParenOrBraceRange();
4564 if (Parens.isInvalid()) {
4565 // This was a variable declaration's initialization for which no initializer
4566 // was specified.
4567 assert(NewArgs.empty() &&
4568 "no parens or braces but have direct init with arguments?");
4569 return ExprEmpty();
4570 }
4571 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4572 Parens.getEnd());
4573}
4574
4575template<typename Derived>
4576bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4577 unsigned NumInputs,
4578 bool IsCall,
4579 SmallVectorImpl<Expr *> &Outputs,
4580 bool *ArgChanged) {
4581 for (unsigned I = 0; I != NumInputs; ++I) {
4582 // If requested, drop call arguments that need to be dropped.
4583 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4584 if (ArgChanged)
4585 *ArgChanged = true;
4586
4587 break;
4588 }
4589
4590 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4591 Expr *Pattern = Expansion->getPattern();
4592
4593 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4594 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4595 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4596
4597 // Determine whether the set of unexpanded parameter packs can and should
4598 // be expanded.
4599 bool Expand = true;
4600 bool RetainExpansion = false;
4601 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4602 UnsignedOrNone NumExpansions = OrigNumExpansions;
4603 if (getDerived().TryExpandParameterPacks(
4604 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4605 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4606 RetainExpansion, NumExpansions))
4607 return true;
4608
4609 if (!Expand) {
4610 // The transform has determined that we should perform a simple
4611 // transformation on the pack expansion, producing another pack
4612 // expansion.
4613 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4614 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4615 if (OutPattern.isInvalid())
4616 return true;
4617
4618 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4619 Expansion->getEllipsisLoc(),
4620 NumExpansions);
4621 if (Out.isInvalid())
4622 return true;
4623
4624 if (ArgChanged)
4625 *ArgChanged = true;
4626 Outputs.push_back(Elt: Out.get());
4627 continue;
4628 }
4629
4630 // Record right away that the argument was changed. This needs
4631 // to happen even if the array expands to nothing.
4632 if (ArgChanged) *ArgChanged = true;
4633
4634 // The transform has determined that we should perform an elementwise
4635 // expansion of the pattern. Do so.
4636 for (unsigned I = 0; I != *NumExpansions; ++I) {
4637 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4638 ExprResult Out = getDerived().TransformExpr(Pattern);
4639 if (Out.isInvalid())
4640 return true;
4641
4642 if (Out.get()->containsUnexpandedParameterPack()) {
4643 Out = getDerived().RebuildPackExpansion(
4644 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4645 if (Out.isInvalid())
4646 return true;
4647 }
4648
4649 Outputs.push_back(Elt: Out.get());
4650 }
4651
4652 // If we're supposed to retain a pack expansion, do so by temporarily
4653 // forgetting the partially-substituted parameter pack.
4654 if (RetainExpansion) {
4655 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4656
4657 ExprResult Out = getDerived().TransformExpr(Pattern);
4658 if (Out.isInvalid())
4659 return true;
4660
4661 Out = getDerived().RebuildPackExpansion(
4662 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4663 if (Out.isInvalid())
4664 return true;
4665
4666 Outputs.push_back(Elt: Out.get());
4667 }
4668
4669 continue;
4670 }
4671
4672 ExprResult Result =
4673 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4674 : getDerived().TransformExpr(Inputs[I]);
4675 if (Result.isInvalid())
4676 return true;
4677
4678 if (Result.get() != Inputs[I] && ArgChanged)
4679 *ArgChanged = true;
4680
4681 Outputs.push_back(Elt: Result.get());
4682 }
4683
4684 return false;
4685}
4686
4687template <typename Derived>
4688Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4689 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4690
4691 EnterExpressionEvaluationContext Eval(
4692 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4693 /*LambdaContextDecl=*/nullptr,
4694 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4695 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4696
4697 if (Var) {
4698 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4699 getDerived().TransformDefinition(Var->getLocation(), Var));
4700
4701 if (!ConditionVar)
4702 return Sema::ConditionError();
4703
4704 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4705 }
4706
4707 if (Expr) {
4708 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4709
4710 if (CondExpr.isInvalid())
4711 return Sema::ConditionError();
4712
4713 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4714 /*MissingOK=*/true);
4715 }
4716
4717 return Sema::ConditionResult();
4718}
4719
4720template <typename Derived>
4721NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4722 NestedNameSpecifierLoc NNS, QualType ObjectType,
4723 NamedDecl *FirstQualifierInScope) {
4724 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4725
4726 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4727 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4728 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4729 Qualifiers.push_back(Elt: Qualifier);
4730 };
4731 insertNNS(NNS);
4732
4733 CXXScopeSpec SS;
4734 while (!Qualifiers.empty()) {
4735 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4736 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4737
4738 switch (QNNS.getKind()) {
4739 case NestedNameSpecifier::Kind::Null:
4740 llvm_unreachable("unexpected null nested name specifier");
4741
4742 case NestedNameSpecifier::Kind::Namespace: {
4743 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4744 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4745 QNNS.getAsNamespaceAndPrefix().Namespace)));
4746 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4747 break;
4748 }
4749
4750 case NestedNameSpecifier::Kind::Global:
4751 // There is no meaningful transformation that one could perform on the
4752 // global scope.
4753 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4754 break;
4755
4756 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4757 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4758 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4759 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4760 ColonColonLoc: Q.getEndLoc());
4761 break;
4762 }
4763
4764 case NestedNameSpecifier::Kind::Type: {
4765 assert(SS.isEmpty());
4766 TypeLoc TL = Q.castAsTypeLoc();
4767
4768 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4769 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4770 if (QualifierLoc) {
4771 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4772 QualifierLoc, ObjectType, FirstQualifierInScope);
4773 if (!QualifierLoc)
4774 return NestedNameSpecifierLoc();
4775 ObjectType = QualType();
4776 FirstQualifierInScope = nullptr;
4777 }
4778 SS.Adopt(Other: QualifierLoc);
4779 Sema::NestedNameSpecInfo IdInfo(
4780 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4781 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4782 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4783 EnteringContext: false, SS,
4784 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4785 return NestedNameSpecifierLoc();
4786 return SS.getWithLocInContext(Context&: SemaRef.Context);
4787 }
4788
4789 QualType T = TL.getType();
4790 TypeLocBuilder TLB;
4791 if (!getDerived().AlreadyTransformed(T)) {
4792 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4793 FirstQualifierInScope);
4794 if (T.isNull())
4795 return NestedNameSpecifierLoc();
4796 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4797 }
4798
4799 if (T->isDependentType() || T->isRecordType() ||
4800 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4801 if (T->isEnumeralType())
4802 SemaRef.Diag(Loc: TL.getBeginLoc(),
4803 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4804 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4805 break;
4806 }
4807 // If the nested-name-specifier is an invalid type def, don't emit an
4808 // error because a previous error should have already been emitted.
4809 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4810 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4811 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4812 << T << SS.getRange();
4813 }
4814 return NestedNameSpecifierLoc();
4815 }
4816 }
4817 }
4818
4819 // Don't rebuild the nested-name-specifier if we don't have to.
4820 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4821 !getDerived().AlwaysRebuild())
4822 return NNS;
4823
4824 // If we can re-use the source-location data from the original
4825 // nested-name-specifier, do so.
4826 if (SS.location_size() == NNS.getDataLength() &&
4827 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4828 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4829
4830 // Allocate new nested-name-specifier location information.
4831 return SS.getWithLocInContext(Context&: SemaRef.Context);
4832}
4833
4834template<typename Derived>
4835DeclarationNameInfo
4836TreeTransform<Derived>
4837::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4838 DeclarationName Name = NameInfo.getName();
4839 if (!Name)
4840 return DeclarationNameInfo();
4841
4842 switch (Name.getNameKind()) {
4843 case DeclarationName::Identifier:
4844 case DeclarationName::ObjCZeroArgSelector:
4845 case DeclarationName::ObjCOneArgSelector:
4846 case DeclarationName::ObjCMultiArgSelector:
4847 case DeclarationName::CXXOperatorName:
4848 case DeclarationName::CXXLiteralOperatorName:
4849 case DeclarationName::CXXUsingDirective:
4850 return NameInfo;
4851
4852 case DeclarationName::CXXDeductionGuideName: {
4853 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4854 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4855 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4856 if (!NewTemplate)
4857 return DeclarationNameInfo();
4858
4859 DeclarationNameInfo NewNameInfo(NameInfo);
4860 NewNameInfo.setName(
4861 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4862 return NewNameInfo;
4863 }
4864
4865 case DeclarationName::CXXConstructorName:
4866 case DeclarationName::CXXDestructorName:
4867 case DeclarationName::CXXConversionFunctionName: {
4868 TypeSourceInfo *NewTInfo;
4869 CanQualType NewCanTy;
4870 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4871 NewTInfo = getDerived().TransformType(OldTInfo);
4872 if (!NewTInfo)
4873 return DeclarationNameInfo();
4874 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4875 }
4876 else {
4877 NewTInfo = nullptr;
4878 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4879 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4880 if (NewT.isNull())
4881 return DeclarationNameInfo();
4882 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4883 }
4884
4885 DeclarationName NewName
4886 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4887 Ty: NewCanTy);
4888 DeclarationNameInfo NewNameInfo(NameInfo);
4889 NewNameInfo.setName(NewName);
4890 NewNameInfo.setNamedTypeInfo(NewTInfo);
4891 return NewNameInfo;
4892 }
4893 }
4894
4895 llvm_unreachable("Unknown name kind.");
4896}
4897
4898template <typename Derived>
4899TemplateName TreeTransform<Derived>::RebuildTemplateName(
4900 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4901 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4902 QualType ObjectType, bool AllowInjectedClassName) {
4903 if (const IdentifierInfo *II = IO.getIdentifier())
4904 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4905 ObjectType, AllowInjectedClassName);
4906 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4907 NameLoc, ObjectType,
4908 AllowInjectedClassName);
4909}
4910
4911template <typename Derived>
4912TemplateName TreeTransform<Derived>::TransformTemplateName(
4913 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4914 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4915 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4916 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4917 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4918
4919 if (QualifierLoc) {
4920 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4921 QualifierLoc, ObjectType, FirstQualifierInScope);
4922 if (!QualifierLoc)
4923 return TemplateName();
4924 }
4925
4926 NestedNameSpecifierLoc UnderlyingQualifier;
4927 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4928 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4929 FirstQualifierInScope, AllowInjectedClassName);
4930 if (NewUnderlyingName.isNull())
4931 return TemplateName();
4932 assert(!UnderlyingQualifier && "unexpected qualifier");
4933
4934 if (!getDerived().AlwaysRebuild() &&
4935 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4936 NewUnderlyingName == UnderlyingName)
4937 return Name;
4938 CXXScopeSpec SS;
4939 SS.Adopt(Other: QualifierLoc);
4940 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4941 NewUnderlyingName);
4942 }
4943
4944 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4945 if (QualifierLoc) {
4946 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4947 QualifierLoc, ObjectType, FirstQualifierInScope);
4948 if (!QualifierLoc)
4949 return TemplateName();
4950 // The qualifier-in-scope and object type only apply to the leftmost
4951 // entity.
4952 ObjectType = QualType();
4953 }
4954
4955 if (!getDerived().AlwaysRebuild() &&
4956 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4957 ObjectType.isNull())
4958 return Name;
4959
4960 CXXScopeSpec SS;
4961 SS.Adopt(Other: QualifierLoc);
4962 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4963 NameLoc, ObjectType,
4964 AllowInjectedClassName);
4965 }
4966
4967 if (SubstTemplateTemplateParmStorage *S =
4968 Name.getAsSubstTemplateTemplateParm()) {
4969 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4970
4971 NestedNameSpecifierLoc ReplacementQualifierLoc;
4972 TemplateName ReplacementName = S->getReplacement();
4973 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4974 NestedNameSpecifierLocBuilder Builder;
4975 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4976 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4977 }
4978
4979 TemplateName NewName = getDerived().TransformTemplateName(
4980 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4981 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4982 if (NewName.isNull())
4983 return TemplateName();
4984 Decl *AssociatedDecl =
4985 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4986 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4987 AssociatedDecl == S->getAssociatedDecl())
4988 return Name;
4989 return SemaRef.Context.getSubstTemplateTemplateParm(
4990 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4991 Final: S->getFinal());
4992 }
4993
4994 if (PackIndexingTemplateStorage *PI = Name.getAsPackIndexingTemplate()) {
4995 assert(!QualifierLoc && "Unexpected qualified pack-index-template-name");
4996
4997 ExprResult IndexExpr;
4998 {
4999 EnterExpressionEvaluationContext ConstantContext(
5000 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5001 IndexExpr = getDerived().TransformExpr(PI->getIndexExpr());
5002 if (IndexExpr.isInvalid())
5003 return TemplateName();
5004 }
5005
5006 auto TransformOne = [&](TemplateName N) {
5007 NestedNameSpecifierLoc NoQualifier;
5008 return getDerived().TransformTemplateName(
5009 NoQualifier, TemplateKWLoc, N, NameLoc, ObjectType,
5010 FirstQualifierInScope, AllowInjectedClassName);
5011 };
5012
5013 TemplateName Pattern = PI->getPattern();
5014 SmallVector<TemplateName, 4> SubstitutedNames;
5015 ArrayRef<TemplateName> Names = PI->getExpansions();
5016
5017 bool NotYetExpanded = Names.empty();
5018 bool FullySubstituted = true;
5019
5020 if (Names.empty() && !PI->expandsToEmptyPack())
5021 Names = ArrayRef(&Pattern, 1);
5022
5023 for (TemplateName N : Names) {
5024 if (!N.containsUnexpandedParameterPack()) {
5025 TemplateName Transformed = TransformOne(N);
5026 if (Transformed.isNull())
5027 return TemplateName();
5028 SubstitutedNames.push_back(Elt: Transformed);
5029 continue;
5030 }
5031
5032 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5033 getSema().collectUnexpandedParameterPacks(N, Unexpanded);
5034 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5035
5036 bool ShouldExpand = true;
5037 bool RetainExpansion = false;
5038 UnsignedOrNone NumExpansions = std::nullopt;
5039 if (getDerived().TryExpandParameterPacks(
5040 NameLoc, SourceRange(), Unexpanded,
5041 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
5042 RetainExpansion, NumExpansions))
5043 return TemplateName();
5044
5045 if (!ShouldExpand) {
5046 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5047 TemplateName Pack = TransformOne(N);
5048 if (Pack.isNull())
5049 return TemplateName();
5050 if (NotYetExpanded) {
5051 FullySubstituted = false;
5052 return getDerived().RebuildPackIndexingTemplateName(
5053 Pack, IndexExpr.get(), FullySubstituted);
5054 }
5055 SubstitutedNames.push_back(Elt: Pack);
5056 continue;
5057 }
5058
5059 for (unsigned I = 0; I != *NumExpansions; ++I) {
5060 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5061 TemplateName Out = TransformOne(N);
5062 if (Out.isNull())
5063 return TemplateName();
5064 SubstitutedNames.push_back(Elt: Out);
5065 FullySubstituted &= !Out.containsUnexpandedParameterPack();
5066 }
5067
5068 // If we're supposed to retain a pack expansion, do so by temporarily
5069 // forgetting the partially-substituted parameter pack.
5070 if (RetainExpansion) {
5071 FullySubstituted = false;
5072 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5073 TemplateName Out = TransformOne(N);
5074 if (Out.isNull())
5075 return TemplateName();
5076 SubstitutedNames.push_back(Elt: Out);
5077 }
5078 }
5079
5080 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5081 TemplateName NewPattern = TransformOne(Pattern);
5082 if (NewPattern.isNull())
5083 return TemplateName();
5084
5085 return getDerived().RebuildPackIndexingTemplateName(
5086 NewPattern, IndexExpr.get(), FullySubstituted, SubstitutedNames);
5087 }
5088
5089 assert(!Name.getAsDeducedTemplateName() &&
5090 "DeducedTemplateName should not escape partial ordering");
5091
5092 // FIXME: Preserve UsingTemplateName.
5093 if (auto *Template = Name.getAsTemplateDecl()) {
5094 assert(!QualifierLoc && "Unexpected qualifier");
5095 return TemplateName(cast_or_null<TemplateDecl>(
5096 getDerived().TransformDecl(NameLoc, Template)));
5097 }
5098
5099 if (SubstTemplateTemplateParmPackStorage *SubstPack
5100 = Name.getAsSubstTemplateTemplateParmPack()) {
5101 assert(!QualifierLoc &&
5102 "Unexpected qualified SubstTemplateTemplateParmPack");
5103 return getDerived().RebuildTemplateName(
5104 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
5105 SubstPack->getIndex(), SubstPack->getFinal());
5106 }
5107
5108 // These should be getting filtered out before they reach the AST.
5109 llvm_unreachable("overloaded function decl survived to here");
5110}
5111
5112template <typename Derived>
5113TemplateName
5114TreeTransform<Derived>::TransformConceptTemplateName(TemplateName Name,
5115 SourceLocation NameLoc) {
5116 NestedNameSpecifierLoc QualifierLoc;
5117 return getDerived().TransformTemplateName(
5118 QualifierLoc, /*TemplateKWLoc=*/SourceLocation(), Name, NameLoc);
5119}
5120
5121template <typename Derived>
5122TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
5123 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
5124 TemplateName Name, SourceLocation NameLoc) {
5125 TemplateName TN = getDerived().TransformTemplateName(
5126 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
5127 if (TN.isNull())
5128 return TemplateArgument();
5129 return TemplateArgument(TN);
5130}
5131
5132template<typename Derived>
5133void TreeTransform<Derived>::InventTemplateArgumentLoc(
5134 const TemplateArgument &Arg,
5135 TemplateArgumentLoc &Output) {
5136 Output = getSema().getTrivialTemplateArgumentLoc(
5137 Arg, QualType(), getDerived().getBaseLocation());
5138}
5139
5140template <typename Derived>
5141bool TreeTransform<Derived>::TransformTemplateArgument(
5142 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5143 bool Uneval) {
5144 const TemplateArgument &Arg = Input.getArgument();
5145 switch (Arg.getKind()) {
5146 case TemplateArgument::Null:
5147 case TemplateArgument::Pack:
5148 llvm_unreachable("Unexpected TemplateArgument");
5149
5150 case TemplateArgument::Integral:
5151 case TemplateArgument::NullPtr:
5152 case TemplateArgument::Declaration:
5153 case TemplateArgument::StructuralValue: {
5154 // Transform a resolved template argument straight to a resolved template
5155 // argument. We get here when substituting into an already-substituted
5156 // template type argument during concept satisfaction checking.
5157 QualType T = Arg.getNonTypeTemplateArgumentType();
5158 QualType NewT = getDerived().TransformType(T);
5159 if (NewT.isNull())
5160 return true;
5161
5162 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5163 ? Arg.getAsDecl()
5164 : nullptr;
5165 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5166 getDerived().getBaseLocation(), D))
5167 : nullptr;
5168 if (D && !NewD)
5169 return true;
5170
5171 if (NewT == T && D == NewD)
5172 Output = Input;
5173 else if (Arg.getKind() == TemplateArgument::Integral)
5174 Output = TemplateArgumentLoc(
5175 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5176 TemplateArgumentLocInfo());
5177 else if (Arg.getKind() == TemplateArgument::NullPtr)
5178 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5179 TemplateArgumentLocInfo());
5180 else if (Arg.getKind() == TemplateArgument::Declaration)
5181 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5182 TemplateArgumentLocInfo());
5183 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5184 Output = TemplateArgumentLoc(
5185 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5186 TemplateArgumentLocInfo());
5187 else
5188 llvm_unreachable("unexpected template argument kind");
5189
5190 return false;
5191 }
5192
5193 case TemplateArgument::Type: {
5194 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5195 if (!TSI)
5196 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5197
5198 TSI = getDerived().TransformType(TSI);
5199 if (!TSI)
5200 return true;
5201
5202 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5203 return false;
5204 }
5205
5206 case TemplateArgument::Template: {
5207 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5208
5209 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5210 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5211 Input.getTemplateNameLoc());
5212 if (Out.isNull())
5213 return true;
5214 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5215 QualifierLoc, Input.getTemplateNameLoc());
5216 return false;
5217 }
5218
5219 case TemplateArgument::TemplateExpansion:
5220 llvm_unreachable("Caller should expand pack expansions");
5221
5222 case TemplateArgument::Expression: {
5223 // Template argument expressions are constant expressions.
5224 EnterExpressionEvaluationContext Unevaluated(
5225 getSema(),
5226 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5227 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5228 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5229 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5230
5231 Expr *InputExpr = Input.getSourceExpression();
5232 if (!InputExpr)
5233 InputExpr = Input.getArgument().getAsExpr();
5234
5235 ExprResult E = getDerived().TransformExpr(InputExpr);
5236 E = SemaRef.ActOnConstantExpression(Res: E);
5237 if (E.isInvalid())
5238 return true;
5239 Output = TemplateArgumentLoc(
5240 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5241 return false;
5242 }
5243 }
5244
5245 // Work around bogus GCC warning
5246 return true;
5247}
5248
5249/// Iterator adaptor that invents template argument location information
5250/// for each of the template arguments in its underlying iterator.
5251template<typename Derived, typename InputIterator>
5252class TemplateArgumentLocInventIterator {
5253 TreeTransform<Derived> &Self;
5254 InputIterator Iter;
5255
5256public:
5257 typedef TemplateArgumentLoc value_type;
5258 typedef TemplateArgumentLoc reference;
5259 typedef typename std::iterator_traits<InputIterator>::difference_type
5260 difference_type;
5261 typedef std::input_iterator_tag iterator_category;
5262
5263 class pointer {
5264 TemplateArgumentLoc Arg;
5265
5266 public:
5267 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5268
5269 const TemplateArgumentLoc *operator->() const { return &Arg; }
5270 };
5271
5272 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5273 InputIterator Iter)
5274 : Self(Self), Iter(Iter) { }
5275
5276 TemplateArgumentLocInventIterator &operator++() {
5277 ++Iter;
5278 return *this;
5279 }
5280
5281 TemplateArgumentLocInventIterator operator++(int) {
5282 TemplateArgumentLocInventIterator Old(*this);
5283 ++(*this);
5284 return Old;
5285 }
5286
5287 reference operator*() const {
5288 TemplateArgumentLoc Result;
5289 Self.InventTemplateArgumentLoc(*Iter, Result);
5290 return Result;
5291 }
5292
5293 pointer operator->() const { return pointer(**this); }
5294
5295 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5296 const TemplateArgumentLocInventIterator &Y) {
5297 return X.Iter == Y.Iter;
5298 }
5299
5300 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5301 const TemplateArgumentLocInventIterator &Y) {
5302 return X.Iter != Y.Iter;
5303 }
5304};
5305
5306template<typename Derived>
5307template<typename InputIterator>
5308bool TreeTransform<Derived>::TransformTemplateArguments(
5309 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5310 bool Uneval) {
5311 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5312 TemplateArgumentLoc Out;
5313 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5314 // Unpack argument packs, which we translate them into separate
5315 // arguments.
5316 // FIXME: We could do much better if we could guarantee that the
5317 // TemplateArgumentLocInfo for the pack expansion would be usable for
5318 // all of the template arguments in the argument pack.
5319 typedef TemplateArgumentLocInventIterator<Derived,
5320 TemplateArgument::pack_iterator>
5321 PackLocIterator;
5322
5323 TemplateArgumentListInfo *PackOutput = &Outputs;
5324 TemplateArgumentListInfo New;
5325
5326 if (TransformTemplateArguments(
5327 PackLocIterator(*this, In.getArgument().pack_begin()),
5328 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5329 Uneval))
5330 return true;
5331
5332 continue;
5333 }
5334
5335 if (In.getArgument().isPackExpansion()) {
5336 UnexpandedInfo Info;
5337 TemplateArgumentLoc Prepared;
5338 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5339 return true;
5340 if (!Info.Expand) {
5341 Outputs.addArgument(Loc: Prepared);
5342 continue;
5343 }
5344
5345 // The transform has determined that we should perform an elementwise
5346 // expansion of the pattern. Do so.
5347 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5348 if (Info.ExpandUnderForgetSubstitions)
5349 ForgetSubst.emplace(getDerived());
5350 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5351 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5352
5353 TemplateArgumentLoc Out;
5354 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5355 return true;
5356
5357 if (Out.getArgument().containsUnexpandedParameterPack()) {
5358 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5359 Info.OrigNumExpansions);
5360 if (Out.getArgument().isNull())
5361 return true;
5362 }
5363
5364 Outputs.addArgument(Loc: Out);
5365 }
5366
5367 // If we're supposed to retain a pack expansion, do so by temporarily
5368 // forgetting the partially-substituted parameter pack.
5369 if (Info.RetainExpansion) {
5370 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5371
5372 TemplateArgumentLoc Out;
5373 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5374 return true;
5375
5376 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5377 Info.OrigNumExpansions);
5378 if (Out.getArgument().isNull())
5379 return true;
5380
5381 Outputs.addArgument(Loc: Out);
5382 }
5383
5384 continue;
5385 }
5386
5387 // The simple case:
5388 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5389 return true;
5390
5391 Outputs.addArgument(Loc: Out);
5392 }
5393
5394 return false;
5395}
5396
5397template <typename Derived>
5398template <typename InputIterator>
5399bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5400 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5401 bool Uneval) {
5402
5403 // [C++26][temp.constr.normal]
5404 // any non-dependent concept template argument
5405 // is substituted into the constraint-expression of C.
5406 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5407 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5408 };
5409
5410 for (; First != Last; ++First) {
5411 TemplateArgumentLoc Out;
5412 TemplateArgumentLoc In = *First;
5413
5414 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5415 typedef TemplateArgumentLocInventIterator<Derived,
5416 TemplateArgument::pack_iterator>
5417 PackLocIterator;
5418 if (TransformConceptTemplateArguments(
5419 PackLocIterator(*this, In.getArgument().pack_begin()),
5420 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5421 Uneval))
5422 return true;
5423 continue;
5424 }
5425
5426 if (!isNonDependentConceptArgument(In.getArgument())) {
5427 Outputs.addArgument(Loc: In);
5428 continue;
5429 }
5430
5431 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5432 return true;
5433
5434 Outputs.addArgument(Loc: Out);
5435 }
5436
5437 return false;
5438}
5439
5440// FIXME: Find ways to reduce code duplication for pack expansions.
5441template <typename Derived>
5442bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5443 bool Uneval,
5444 TemplateArgumentLoc &Out,
5445 UnexpandedInfo &Info) {
5446 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5447 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5448 TemplateArgumentLoc &Pattern) {
5449 assert(Arg.getArgument().isPackExpansion());
5450 // We have a pack expansion, for which we will be substituting into the
5451 // pattern.
5452 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5453 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5454 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5455 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5456 if (IsLateExpansionAttempt) {
5457 // Request expansion only when there is an opportunity to expand a pack
5458 // that required a substituion first.
5459 bool SawPackTypes =
5460 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5461 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5462 });
5463 if (!SawPackTypes) {
5464 Info.Expand = false;
5465 return false;
5466 }
5467 }
5468 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5469
5470 // Determine whether the set of unexpanded parameter packs can and
5471 // should be expanded.
5472 Info.Expand = true;
5473 Info.RetainExpansion = false;
5474 Info.NumExpansions = Info.OrigNumExpansions;
5475 return getDerived().TryExpandParameterPacks(
5476 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5477 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5478 Info.RetainExpansion, Info.NumExpansions);
5479 };
5480
5481 TemplateArgumentLoc Pattern;
5482 if (ComputeInfo(In, false, Info, Pattern))
5483 return true;
5484
5485 if (Info.Expand) {
5486 Out = Pattern;
5487 return false;
5488 }
5489
5490 // The transform has determined that we should perform a simple
5491 // transformation on the pack expansion, producing another pack
5492 // expansion.
5493 TemplateArgumentLoc OutPattern;
5494 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5495 std::in_place, getSema(), std::nullopt);
5496 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5497 return true;
5498
5499 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5500 Info.NumExpansions);
5501 if (Out.getArgument().isNull())
5502 return true;
5503 SubstIndex.reset();
5504
5505 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5506 return false;
5507
5508 // Some packs will learn their length after substitution, e.g.
5509 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5510 // value of `T`.
5511 //
5512 // We only expand after we know sizes of all packs, check if this is the case
5513 // or not. However, we avoid a full template substitution and only do
5514 // expanstions after this point.
5515
5516 // E.g. when substituting template arguments of tuple with {T -> int} in the
5517 // following example:
5518 // template <class T>
5519 // struct TupleWithInt {
5520 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5521 // };
5522 // TupleWithInt<int>::type y;
5523 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5524 // length and run `ComputeInfo()` to provide the necessary information to our
5525 // caller.
5526 //
5527 // Note that we may still have situations where builtin is not going to be
5528 // expanded. For example:
5529 // template <class T>
5530 // struct Foo {
5531 // template <class U> using tuple_with_t =
5532 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5533 // tuple_with_t<short>;
5534 // }
5535 // Because the substitution into `type` happens in dependent context, `type`
5536 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5537 // and the caller will not be able to expand it.
5538 ForgetSubstitutionRAII ForgetSubst(getDerived());
5539 if (ComputeInfo(Out, true, Info, OutPattern))
5540 return true;
5541 if (!Info.Expand)
5542 return false;
5543 Out = OutPattern;
5544 Info.ExpandUnderForgetSubstitions = true;
5545 return false;
5546}
5547
5548//===----------------------------------------------------------------------===//
5549// Type transformation
5550//===----------------------------------------------------------------------===//
5551
5552template<typename Derived>
5553QualType TreeTransform<Derived>::TransformType(QualType T) {
5554 if (getDerived().AlreadyTransformed(T))
5555 return T;
5556
5557 // Temporary workaround. All of these transformations should
5558 // eventually turn into transformations on TypeLocs.
5559 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5560 T, getDerived().getBaseLocation());
5561
5562 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5563
5564 if (!NewTSI)
5565 return QualType();
5566
5567 return NewTSI->getType();
5568}
5569
5570template <typename Derived>
5571TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5572 // Refine the base location to the type's location.
5573 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5574 getDerived().getBaseEntity());
5575 if (getDerived().AlreadyTransformed(TSI->getType()))
5576 return TSI;
5577
5578 TypeLocBuilder TLB;
5579
5580 TypeLoc TL = TSI->getTypeLoc();
5581 TLB.reserve(Requested: TL.getFullDataSize());
5582
5583 QualType Result = getDerived().TransformType(TLB, TL);
5584 if (Result.isNull())
5585 return nullptr;
5586
5587 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5588}
5589
5590template<typename Derived>
5591QualType
5592TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5593 switch (T.getTypeLocClass()) {
5594#define ABSTRACT_TYPELOC(CLASS, PARENT)
5595#define TYPELOC(CLASS, PARENT) \
5596 case TypeLoc::CLASS: \
5597 return getDerived().Transform##CLASS##Type(TLB, \
5598 T.castAs<CLASS##TypeLoc>());
5599#include "clang/AST/TypeLocNodes.def"
5600 }
5601
5602 llvm_unreachable("unhandled type loc!");
5603}
5604
5605template<typename Derived>
5606QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5607 if (!isa<DependentNameType>(Val: T))
5608 return TransformType(T);
5609
5610 if (getDerived().AlreadyTransformed(T))
5611 return T;
5612 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5613 T, getDerived().getBaseLocation());
5614 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5615 return NewTSI ? NewTSI->getType() : QualType();
5616}
5617
5618template <typename Derived>
5619TypeSourceInfo *
5620TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5621 if (!isa<DependentNameType>(Val: TSI->getType()))
5622 return TransformType(TSI);
5623
5624 // Refine the base location to the type's location.
5625 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5626 getDerived().getBaseEntity());
5627 if (getDerived().AlreadyTransformed(TSI->getType()))
5628 return TSI;
5629
5630 TypeLocBuilder TLB;
5631
5632 TypeLoc TL = TSI->getTypeLoc();
5633 TLB.reserve(Requested: TL.getFullDataSize());
5634
5635 auto QTL = TL.getAs<QualifiedTypeLoc>();
5636 if (QTL)
5637 TL = QTL.getUnqualifiedLoc();
5638
5639 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5640
5641 QualType Result = getDerived().TransformDependentNameType(
5642 TLB, DNTL, /*DeducedTSTContext*/true);
5643 if (Result.isNull())
5644 return nullptr;
5645
5646 if (QTL) {
5647 Result = getDerived().RebuildQualifiedType(Result, QTL);
5648 if (Result.isNull())
5649 return nullptr;
5650 TLB.TypeWasModifiedSafely(T: Result);
5651 }
5652
5653 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5654}
5655
5656template<typename Derived>
5657QualType
5658TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5659 QualifiedTypeLoc T) {
5660 QualType Result;
5661 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5662 auto SuppressObjCLifetime =
5663 T.getType().getLocalQualifiers().hasObjCLifetime();
5664 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5665 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5666 SuppressObjCLifetime);
5667 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5668 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5669 TLB, STTP, SuppressObjCLifetime);
5670 } else {
5671 Result = getDerived().TransformType(TLB, UnqualTL);
5672 }
5673
5674 if (Result.isNull())
5675 return QualType();
5676
5677 Result = getDerived().RebuildQualifiedType(Result, T);
5678
5679 if (Result.isNull())
5680 return QualType();
5681
5682 // RebuildQualifiedType might have updated the type, but not in a way
5683 // that invalidates the TypeLoc. (There's no location information for
5684 // qualifiers.)
5685 TLB.TypeWasModifiedSafely(T: Result);
5686
5687 return Result;
5688}
5689
5690template <typename Derived>
5691QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5692 QualifiedTypeLoc TL) {
5693
5694 SourceLocation Loc = TL.getBeginLoc();
5695 Qualifiers Quals = TL.getType().getLocalQualifiers();
5696
5697 if ((T.getAddressSpace() != LangAS::Default &&
5698 Quals.getAddressSpace() != LangAS::Default) &&
5699 T.getAddressSpace() != Quals.getAddressSpace()) {
5700 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5701 << TL.getType() << T;
5702 return QualType();
5703 }
5704
5705 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5706 if (LocalPointerAuth.isPresent()) {
5707 if (T.getPointerAuth().isPresent()) {
5708 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5709 return QualType();
5710 }
5711 if (!T->isDependentType()) {
5712 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5713 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5714 return QualType();
5715 }
5716 }
5717 }
5718 // C++ [dcl.fct]p7:
5719 // [When] adding cv-qualifications on top of the function type [...] the
5720 // cv-qualifiers are ignored.
5721 if (T->isFunctionType()) {
5722 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5723 AddressSpace: Quals.getAddressSpace());
5724 return T;
5725 }
5726
5727 // C++ [dcl.ref]p1:
5728 // when the cv-qualifiers are introduced through the use of a typedef-name
5729 // or decltype-specifier [...] the cv-qualifiers are ignored.
5730 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5731 // applied to a reference type.
5732 if (T->isReferenceType()) {
5733 // The only qualifier that applies to a reference type is restrict.
5734 if (!Quals.hasRestrict())
5735 return T;
5736 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5737 }
5738
5739 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5740 // resulting type.
5741 if (Quals.hasObjCLifetime()) {
5742 if (!T->isObjCLifetimeType() && !T->isDependentType())
5743 Quals.removeObjCLifetime();
5744 else if (T.getObjCLifetime()) {
5745 // Objective-C ARC:
5746 // A lifetime qualifier applied to a substituted template parameter
5747 // overrides the lifetime qualifier from the template argument.
5748 const AutoType *AutoTy;
5749 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5750 // 'auto' types behave the same way as template parameters.
5751 QualType Deduced = AutoTy->getDeducedType();
5752 Qualifiers Qs = Deduced.getQualifiers();
5753 Qs.removeObjCLifetime();
5754 Deduced =
5755 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5756 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5757 Keyword: AutoTy->getKeyword(),
5758 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5759 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5760 } else {
5761 // Otherwise, complain about the addition of a qualifier to an
5762 // already-qualified type.
5763 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5764 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5765 Quals.removeObjCLifetime();
5766 }
5767 }
5768 }
5769
5770 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5771}
5772
5773template <typename Derived>
5774QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5775 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5776 NamedDecl *FirstQualifierInScope) {
5777 assert(!getDerived().AlreadyTransformed(TL.getType()));
5778
5779 switch (TL.getTypeLocClass()) {
5780 case TypeLoc::TemplateSpecialization:
5781 return getDerived().TransformTemplateSpecializationType(
5782 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5783 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5784 case TypeLoc::DependentName:
5785 return getDerived().TransformDependentNameType(
5786 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5787 ObjectType, FirstQualifierInScope);
5788 default:
5789 // Any dependent canonical type can appear here, through type alias
5790 // templates.
5791 return getDerived().TransformType(TLB, TL);
5792 }
5793}
5794
5795template <class TyLoc> static inline
5796QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5797 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5798 NewT.setNameLoc(T.getNameLoc());
5799 return T.getType();
5800}
5801
5802template<typename Derived>
5803QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5804 BuiltinTypeLoc T) {
5805 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5806 NewT.setBuiltinLoc(T.getBuiltinLoc());
5807 if (T.needsExtraLocalData())
5808 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5809 return T.getType();
5810}
5811
5812template<typename Derived>
5813QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5814 ComplexTypeLoc T) {
5815 // FIXME: recurse?
5816 return TransformTypeSpecType(TLB, T);
5817}
5818
5819template <typename Derived>
5820QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5821 AdjustedTypeLoc TL) {
5822 // Adjustments applied during transformation are handled elsewhere.
5823 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5824}
5825
5826template<typename Derived>
5827QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5828 DecayedTypeLoc TL) {
5829 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5830 if (OriginalType.isNull())
5831 return QualType();
5832
5833 QualType Result = TL.getType();
5834 if (getDerived().AlwaysRebuild() ||
5835 OriginalType != TL.getOriginalLoc().getType())
5836 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5837 TLB.push<DecayedTypeLoc>(T: Result);
5838 // Nothing to set for DecayedTypeLoc.
5839 return Result;
5840}
5841
5842template <typename Derived>
5843QualType
5844TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5845 ArrayParameterTypeLoc TL) {
5846 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5847 if (OriginalType.isNull())
5848 return QualType();
5849
5850 QualType Result = TL.getType();
5851 if (getDerived().AlwaysRebuild() ||
5852 OriginalType != TL.getElementLoc().getType())
5853 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5854 TLB.push<ArrayParameterTypeLoc>(T: Result);
5855 // Nothing to set for ArrayParameterTypeLoc.
5856 return Result;
5857}
5858
5859template<typename Derived>
5860QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5861 PointerTypeLoc TL) {
5862 QualType PointeeType
5863 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5864 if (PointeeType.isNull())
5865 return QualType();
5866
5867 QualType Result = TL.getType();
5868 if (PointeeType->getAs<ObjCObjectType>()) {
5869 // A dependent pointer type 'T *' has is being transformed such
5870 // that an Objective-C class type is being replaced for 'T'. The
5871 // resulting pointer type is an ObjCObjectPointerType, not a
5872 // PointerType.
5873 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5874
5875 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5876 NewT.setStarLoc(TL.getStarLoc());
5877 return Result;
5878 }
5879
5880 if (getDerived().AlwaysRebuild() ||
5881 PointeeType != TL.getPointeeLoc().getType()) {
5882 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5883 if (Result.isNull())
5884 return QualType();
5885 }
5886
5887 // Objective-C ARC can add lifetime qualifiers to the type that we're
5888 // pointing to.
5889 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5890
5891 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5892 NewT.setSigilLoc(TL.getSigilLoc());
5893 return Result;
5894}
5895
5896template<typename Derived>
5897QualType
5898TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5899 BlockPointerTypeLoc TL) {
5900 QualType PointeeType
5901 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5902 if (PointeeType.isNull())
5903 return QualType();
5904
5905 QualType Result = TL.getType();
5906 if (getDerived().AlwaysRebuild() ||
5907 PointeeType != TL.getPointeeLoc().getType()) {
5908 Result = getDerived().RebuildBlockPointerType(PointeeType,
5909 TL.getSigilLoc());
5910 if (Result.isNull())
5911 return QualType();
5912 }
5913
5914 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5915 NewT.setSigilLoc(TL.getSigilLoc());
5916 return Result;
5917}
5918
5919/// Transforms a reference type. Note that somewhat paradoxically we
5920/// don't care whether the type itself is an l-value type or an r-value
5921/// type; we only care if the type was *written* as an l-value type
5922/// or an r-value type.
5923template<typename Derived>
5924QualType
5925TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5926 ReferenceTypeLoc TL) {
5927 const ReferenceType *T = TL.getTypePtr();
5928
5929 // Note that this works with the pointee-as-written.
5930 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5931 if (PointeeType.isNull())
5932 return QualType();
5933
5934 QualType Result = TL.getType();
5935 if (getDerived().AlwaysRebuild() ||
5936 PointeeType != T->getPointeeTypeAsWritten()) {
5937 Result = getDerived().RebuildReferenceType(PointeeType,
5938 T->isSpelledAsLValue(),
5939 TL.getSigilLoc());
5940 if (Result.isNull())
5941 return QualType();
5942 }
5943
5944 // Objective-C ARC can add lifetime qualifiers to the type that we're
5945 // referring to.
5946 TLB.TypeWasModifiedSafely(
5947 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5948
5949 // r-value references can be rebuilt as l-value references.
5950 ReferenceTypeLoc NewTL;
5951 if (isa<LValueReferenceType>(Val: Result))
5952 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5953 else
5954 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5955 NewTL.setSigilLoc(TL.getSigilLoc());
5956
5957 return Result;
5958}
5959
5960template<typename Derived>
5961QualType
5962TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5963 LValueReferenceTypeLoc TL) {
5964 return TransformReferenceType(TLB, TL);
5965}
5966
5967template<typename Derived>
5968QualType
5969TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5970 RValueReferenceTypeLoc TL) {
5971 return TransformReferenceType(TLB, TL);
5972}
5973
5974template<typename Derived>
5975QualType
5976TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5977 MemberPointerTypeLoc TL) {
5978 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5979 if (PointeeType.isNull())
5980 return QualType();
5981
5982 const MemberPointerType *T = TL.getTypePtr();
5983
5984 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5985 NestedNameSpecifierLoc NewQualifierLoc =
5986 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5987 if (!NewQualifierLoc)
5988 return QualType();
5989
5990 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5991 if (OldCls) {
5992 NewCls = cast_or_null<CXXRecordDecl>(
5993 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5994 if (!NewCls)
5995 return QualType();
5996 }
5997
5998 QualType Result = TL.getType();
5999 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
6000 NewQualifierLoc.getNestedNameSpecifier() !=
6001 OldQualifierLoc.getNestedNameSpecifier() ||
6002 NewCls != OldCls) {
6003 CXXScopeSpec SS;
6004 SS.Adopt(Other: NewQualifierLoc);
6005 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
6006 TL.getStarLoc());
6007 if (Result.isNull())
6008 return QualType();
6009 }
6010
6011 // If we had to adjust the pointee type when building a member pointer, make
6012 // sure to push TypeLoc info for it.
6013 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
6014 if (MPT && PointeeType != MPT->getPointeeType()) {
6015 assert(isa<AdjustedType>(MPT->getPointeeType()));
6016 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
6017 }
6018
6019 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
6020 NewTL.setSigilLoc(TL.getSigilLoc());
6021 NewTL.setQualifierLoc(NewQualifierLoc);
6022
6023 return Result;
6024}
6025
6026template<typename Derived>
6027QualType
6028TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
6029 ConstantArrayTypeLoc TL) {
6030 const ConstantArrayType *T = TL.getTypePtr();
6031 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6032 if (ElementType.isNull())
6033 return QualType();
6034
6035 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6036 Expr *OldSize = TL.getSizeExpr();
6037 if (!OldSize)
6038 OldSize = const_cast<Expr*>(T->getSizeExpr());
6039 Expr *NewSize = nullptr;
6040 if (OldSize) {
6041 EnterExpressionEvaluationContext Unevaluated(
6042 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6043 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
6044 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
6045 }
6046
6047 QualType Result = TL.getType();
6048 if (getDerived().AlwaysRebuild() ||
6049 ElementType != T->getElementType() ||
6050 (T->getSizeExpr() && NewSize != OldSize)) {
6051 Result = getDerived().RebuildConstantArrayType(ElementType,
6052 T->getSizeModifier(),
6053 T->getSize(), NewSize,
6054 T->getIndexTypeCVRQualifiers(),
6055 TL.getBracketsRange());
6056 if (Result.isNull())
6057 return QualType();
6058 }
6059
6060 // We might have either a ConstantArrayType or a VariableArrayType now:
6061 // a ConstantArrayType is allowed to have an element type which is a
6062 // VariableArrayType if the type is dependent. Fortunately, all array
6063 // types have the same location layout.
6064 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6065 NewTL.setLBracketLoc(TL.getLBracketLoc());
6066 NewTL.setRBracketLoc(TL.getRBracketLoc());
6067 NewTL.setSizeExpr(NewSize);
6068
6069 return Result;
6070}
6071
6072template<typename Derived>
6073QualType TreeTransform<Derived>::TransformIncompleteArrayType(
6074 TypeLocBuilder &TLB,
6075 IncompleteArrayTypeLoc TL) {
6076 const IncompleteArrayType *T = TL.getTypePtr();
6077 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6078 if (ElementType.isNull())
6079 return QualType();
6080
6081 QualType Result = TL.getType();
6082 if (getDerived().AlwaysRebuild() ||
6083 ElementType != T->getElementType()) {
6084 Result = getDerived().RebuildIncompleteArrayType(ElementType,
6085 T->getSizeModifier(),
6086 T->getIndexTypeCVRQualifiers(),
6087 TL.getBracketsRange());
6088 if (Result.isNull())
6089 return QualType();
6090 }
6091
6092 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
6093 NewTL.setLBracketLoc(TL.getLBracketLoc());
6094 NewTL.setRBracketLoc(TL.getRBracketLoc());
6095 NewTL.setSizeExpr(nullptr);
6096
6097 return Result;
6098}
6099
6100template<typename Derived>
6101QualType
6102TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
6103 VariableArrayTypeLoc TL) {
6104 const VariableArrayType *T = TL.getTypePtr();
6105 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6106 if (ElementType.isNull())
6107 return QualType();
6108
6109 ExprResult SizeResult;
6110 {
6111 EnterExpressionEvaluationContext Context(
6112 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
6113 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
6114 }
6115 if (SizeResult.isInvalid())
6116 return QualType();
6117 SizeResult =
6118 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
6119 if (SizeResult.isInvalid())
6120 return QualType();
6121
6122 Expr *Size = SizeResult.get();
6123
6124 QualType Result = TL.getType();
6125 if (getDerived().AlwaysRebuild() ||
6126 ElementType != T->getElementType() ||
6127 Size != T->getSizeExpr()) {
6128 Result = getDerived().RebuildVariableArrayType(ElementType,
6129 T->getSizeModifier(),
6130 Size,
6131 T->getIndexTypeCVRQualifiers(),
6132 TL.getBracketsRange());
6133 if (Result.isNull())
6134 return QualType();
6135 }
6136
6137 // We might have constant size array now, but fortunately it has the same
6138 // location layout.
6139 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6140 NewTL.setLBracketLoc(TL.getLBracketLoc());
6141 NewTL.setRBracketLoc(TL.getRBracketLoc());
6142 NewTL.setSizeExpr(Size);
6143
6144 return Result;
6145}
6146
6147template<typename Derived>
6148QualType
6149TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6150 DependentSizedArrayTypeLoc TL) {
6151 const DependentSizedArrayType *T = TL.getTypePtr();
6152 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6153 if (ElementType.isNull())
6154 return QualType();
6155
6156 // Array bounds are constant expressions.
6157 EnterExpressionEvaluationContext Unevaluated(
6158 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6159
6160 // If we have a VLA then it won't be a constant.
6161 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6162
6163 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6164 Expr *origSize = TL.getSizeExpr();
6165 if (!origSize) origSize = T->getSizeExpr();
6166
6167 ExprResult sizeResult
6168 = getDerived().TransformExpr(origSize);
6169 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6170 if (sizeResult.isInvalid())
6171 return QualType();
6172
6173 Expr *size = sizeResult.get();
6174
6175 QualType Result = TL.getType();
6176 if (getDerived().AlwaysRebuild() ||
6177 ElementType != T->getElementType() ||
6178 size != origSize) {
6179 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6180 T->getSizeModifier(),
6181 size,
6182 T->getIndexTypeCVRQualifiers(),
6183 TL.getBracketsRange());
6184 if (Result.isNull())
6185 return QualType();
6186 }
6187
6188 // We might have any sort of array type now, but fortunately they
6189 // all have the same location layout.
6190 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6191 NewTL.setLBracketLoc(TL.getLBracketLoc());
6192 NewTL.setRBracketLoc(TL.getRBracketLoc());
6193 NewTL.setSizeExpr(size);
6194
6195 return Result;
6196}
6197
6198template <typename Derived>
6199QualType TreeTransform<Derived>::TransformDependentVectorType(
6200 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6201 const DependentVectorType *T = TL.getTypePtr();
6202 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6203 if (ElementType.isNull())
6204 return QualType();
6205
6206 EnterExpressionEvaluationContext Unevaluated(
6207 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6208
6209 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6210 Size = SemaRef.ActOnConstantExpression(Res: Size);
6211 if (Size.isInvalid())
6212 return QualType();
6213
6214 QualType Result = TL.getType();
6215 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6216 Size.get() != T->getSizeExpr()) {
6217 Result = getDerived().RebuildDependentVectorType(
6218 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6219 if (Result.isNull())
6220 return QualType();
6221 }
6222
6223 // Result might be dependent or not.
6224 if (isa<DependentVectorType>(Val: Result)) {
6225 DependentVectorTypeLoc NewTL =
6226 TLB.push<DependentVectorTypeLoc>(T: Result);
6227 NewTL.setNameLoc(TL.getNameLoc());
6228 } else {
6229 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6230 NewTL.setNameLoc(TL.getNameLoc());
6231 }
6232
6233 return Result;
6234}
6235
6236template<typename Derived>
6237QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6238 TypeLocBuilder &TLB,
6239 DependentSizedExtVectorTypeLoc TL) {
6240 const DependentSizedExtVectorType *T = TL.getTypePtr();
6241
6242 // FIXME: ext vector locs should be nested
6243 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6244 if (ElementType.isNull())
6245 return QualType();
6246
6247 // Vector sizes are constant expressions.
6248 EnterExpressionEvaluationContext Unevaluated(
6249 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6250
6251 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6252 Size = SemaRef.ActOnConstantExpression(Res: Size);
6253 if (Size.isInvalid())
6254 return QualType();
6255
6256 QualType Result = TL.getType();
6257 if (getDerived().AlwaysRebuild() ||
6258 ElementType != T->getElementType() ||
6259 Size.get() != T->getSizeExpr()) {
6260 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6261 Size.get(),
6262 T->getAttributeLoc());
6263 if (Result.isNull())
6264 return QualType();
6265 }
6266
6267 // Result might be dependent or not.
6268 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6269 DependentSizedExtVectorTypeLoc NewTL
6270 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6271 NewTL.setNameLoc(TL.getNameLoc());
6272 } else {
6273 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6274 NewTL.setNameLoc(TL.getNameLoc());
6275 }
6276
6277 return Result;
6278}
6279
6280template <typename Derived>
6281QualType
6282TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6283 ConstantMatrixTypeLoc TL) {
6284 const ConstantMatrixType *T = TL.getTypePtr();
6285 QualType ElementType = getDerived().TransformType(T->getElementType());
6286 if (ElementType.isNull())
6287 return QualType();
6288
6289 QualType Result = TL.getType();
6290 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6291 Result = getDerived().RebuildConstantMatrixType(
6292 ElementType, T->getNumRows(), T->getNumColumns());
6293 if (Result.isNull())
6294 return QualType();
6295 }
6296
6297 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6298 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6299 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6300 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6301 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6302
6303 return Result;
6304}
6305
6306template <typename Derived>
6307QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6308 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6309 const DependentSizedMatrixType *T = TL.getTypePtr();
6310
6311 QualType ElementType = getDerived().TransformType(T->getElementType());
6312 if (ElementType.isNull()) {
6313 return QualType();
6314 }
6315
6316 // Matrix dimensions are constant expressions.
6317 EnterExpressionEvaluationContext Unevaluated(
6318 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6319
6320 Expr *origRows = TL.getAttrRowOperand();
6321 if (!origRows)
6322 origRows = T->getRowExpr();
6323 Expr *origColumns = TL.getAttrColumnOperand();
6324 if (!origColumns)
6325 origColumns = T->getColumnExpr();
6326
6327 ExprResult rowResult = getDerived().TransformExpr(origRows);
6328 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6329 if (rowResult.isInvalid())
6330 return QualType();
6331
6332 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6333 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6334 if (columnResult.isInvalid())
6335 return QualType();
6336
6337 Expr *rows = rowResult.get();
6338 Expr *columns = columnResult.get();
6339
6340 QualType Result = TL.getType();
6341 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6342 rows != origRows || columns != origColumns) {
6343 Result = getDerived().RebuildDependentSizedMatrixType(
6344 ElementType, rows, columns, T->getAttributeLoc());
6345
6346 if (Result.isNull())
6347 return QualType();
6348 }
6349
6350 // We might have any sort of matrix type now, but fortunately they
6351 // all have the same location layout.
6352 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6353 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6354 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6355 NewTL.setAttrRowOperand(rows);
6356 NewTL.setAttrColumnOperand(columns);
6357 return Result;
6358}
6359
6360template <typename Derived>
6361QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6362 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6363 const DependentAddressSpaceType *T = TL.getTypePtr();
6364
6365 QualType pointeeType =
6366 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6367
6368 if (pointeeType.isNull())
6369 return QualType();
6370
6371 // Address spaces are constant expressions.
6372 EnterExpressionEvaluationContext Unevaluated(
6373 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6374
6375 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6376 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6377 if (AddrSpace.isInvalid())
6378 return QualType();
6379
6380 QualType Result = TL.getType();
6381 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6382 AddrSpace.get() != T->getAddrSpaceExpr()) {
6383 Result = getDerived().RebuildDependentAddressSpaceType(
6384 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6385 if (Result.isNull())
6386 return QualType();
6387 }
6388
6389 // Result might be dependent or not.
6390 if (isa<DependentAddressSpaceType>(Val: Result)) {
6391 DependentAddressSpaceTypeLoc NewTL =
6392 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6393
6394 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6395 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6396 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6397
6398 } else {
6399 TLB.TypeWasModifiedSafely(T: Result);
6400 }
6401
6402 return Result;
6403}
6404
6405template <typename Derived>
6406QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6407 VectorTypeLoc TL) {
6408 const VectorType *T = TL.getTypePtr();
6409 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6410 if (ElementType.isNull())
6411 return QualType();
6412
6413 QualType Result = TL.getType();
6414 if (getDerived().AlwaysRebuild() ||
6415 ElementType != T->getElementType()) {
6416 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6417 T->getVectorKind());
6418 if (Result.isNull())
6419 return QualType();
6420 }
6421
6422 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6423 NewTL.setNameLoc(TL.getNameLoc());
6424
6425 return Result;
6426}
6427
6428template<typename Derived>
6429QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6430 ExtVectorTypeLoc TL) {
6431 const VectorType *T = TL.getTypePtr();
6432 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6433 if (ElementType.isNull())
6434 return QualType();
6435
6436 QualType Result = TL.getType();
6437 if (getDerived().AlwaysRebuild() ||
6438 ElementType != T->getElementType()) {
6439 Result = getDerived().RebuildExtVectorType(ElementType,
6440 T->getNumElements(),
6441 /*FIXME*/ SourceLocation());
6442 if (Result.isNull())
6443 return QualType();
6444 }
6445
6446 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6447 NewTL.setNameLoc(TL.getNameLoc());
6448
6449 return Result;
6450}
6451
6452template <typename Derived>
6453ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6454 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6455 bool ExpectParameterPack) {
6456 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6457 TypeSourceInfo *NewTSI = nullptr;
6458
6459 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6460 // If we're substituting into a pack expansion type and we know the
6461 // length we want to expand to, just substitute for the pattern.
6462 TypeLoc OldTL = OldTSI->getTypeLoc();
6463 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6464
6465 TypeLocBuilder TLB;
6466 TypeLoc NewTL = OldTSI->getTypeLoc();
6467 TLB.reserve(Requested: NewTL.getFullDataSize());
6468
6469 QualType Result = getDerived().TransformType(TLB,
6470 OldExpansionTL.getPatternLoc());
6471 if (Result.isNull())
6472 return nullptr;
6473
6474 Result = RebuildPackExpansionType(Pattern: Result,
6475 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6476 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6477 NumExpansions);
6478 if (Result.isNull())
6479 return nullptr;
6480
6481 PackExpansionTypeLoc NewExpansionTL
6482 = TLB.push<PackExpansionTypeLoc>(T: Result);
6483 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6484 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6485 } else
6486 NewTSI = getDerived().TransformType(OldTSI);
6487 if (!NewTSI)
6488 return nullptr;
6489
6490 if (NewTSI == OldTSI && indexAdjustment == 0)
6491 return OldParm;
6492
6493 ParmVarDecl *newParm = ParmVarDecl::Create(
6494 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6495 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6496 TInfo: NewTSI, S: OldParm->getStorageClass(),
6497 /* DefArg */ DefArg: nullptr);
6498 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6499 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6500 getDerived().transformedLocalDecl(OldParm, {newParm});
6501 return newParm;
6502}
6503
6504template <typename Derived>
6505bool TreeTransform<Derived>::TransformFunctionTypeParams(
6506 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6507 const QualType *ParamTypes,
6508 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6509 SmallVectorImpl<QualType> &OutParamTypes,
6510 SmallVectorImpl<ParmVarDecl *> *PVars,
6511 Sema::ExtParameterInfoBuilder &PInfos,
6512 unsigned *LastParamTransformed) {
6513 int indexAdjustment = 0;
6514
6515 unsigned NumParams = Params.size();
6516 for (unsigned i = 0; i != NumParams; ++i) {
6517 if (LastParamTransformed)
6518 *LastParamTransformed = i;
6519 if (ParmVarDecl *OldParm = Params[i]) {
6520 assert(OldParm->getFunctionScopeIndex() == i);
6521
6522 UnsignedOrNone NumExpansions = std::nullopt;
6523 ParmVarDecl *NewParm = nullptr;
6524 if (OldParm->isParameterPack()) {
6525 // We have a function parameter pack that may need to be expanded.
6526 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6527
6528 // Find the parameter packs that could be expanded.
6529 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6530 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6531 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6532 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6533
6534 // Determine whether we should expand the parameter packs.
6535 bool ShouldExpand = false;
6536 bool RetainExpansion = false;
6537 UnsignedOrNone OrigNumExpansions = std::nullopt;
6538 if (Unexpanded.size() > 0) {
6539 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6540 NumExpansions = OrigNumExpansions;
6541 if (getDerived().TryExpandParameterPacks(
6542 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6543 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6544 ShouldExpand, RetainExpansion, NumExpansions)) {
6545 return true;
6546 }
6547 } else {
6548#ifndef NDEBUG
6549 const AutoType *AT =
6550 Pattern.getType().getTypePtr()->getContainedAutoType();
6551 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6552 "Could not find parameter packs or undeduced auto type!");
6553#endif
6554 }
6555
6556 if (ShouldExpand) {
6557 // Expand the function parameter pack into multiple, separate
6558 // parameters.
6559 getDerived().ExpandingFunctionParameterPack(OldParm);
6560 for (unsigned I = 0; I != *NumExpansions; ++I) {
6561 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6562 ParmVarDecl *NewParm
6563 = getDerived().TransformFunctionTypeParam(OldParm,
6564 indexAdjustment++,
6565 OrigNumExpansions,
6566 /*ExpectParameterPack=*/false);
6567 if (!NewParm)
6568 return true;
6569
6570 if (ParamInfos)
6571 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6572 OutParamTypes.push_back(Elt: NewParm->getType());
6573 if (PVars)
6574 PVars->push_back(Elt: NewParm);
6575 }
6576
6577 // If we're supposed to retain a pack expansion, do so by temporarily
6578 // forgetting the partially-substituted parameter pack.
6579 if (RetainExpansion) {
6580 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6581 ParmVarDecl *NewParm
6582 = getDerived().TransformFunctionTypeParam(OldParm,
6583 indexAdjustment++,
6584 OrigNumExpansions,
6585 /*ExpectParameterPack=*/false);
6586 if (!NewParm)
6587 return true;
6588
6589 if (ParamInfos)
6590 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6591 OutParamTypes.push_back(Elt: NewParm->getType());
6592 if (PVars)
6593 PVars->push_back(Elt: NewParm);
6594 }
6595
6596 // The next parameter should have the same adjustment as the
6597 // last thing we pushed, but we post-incremented indexAdjustment
6598 // on every push. Also, if we push nothing, the adjustment should
6599 // go down by one.
6600 indexAdjustment--;
6601
6602 // We're done with the pack expansion.
6603 continue;
6604 }
6605
6606 // We'll substitute the parameter now without expanding the pack
6607 // expansion.
6608 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6609 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6610 indexAdjustment,
6611 NumExpansions,
6612 /*ExpectParameterPack=*/true);
6613 assert(NewParm->isParameterPack() &&
6614 "Parameter pack no longer a parameter pack after "
6615 "transformation.");
6616 } else {
6617 NewParm = getDerived().TransformFunctionTypeParam(
6618 OldParm, indexAdjustment, std::nullopt,
6619 /*ExpectParameterPack=*/false);
6620 }
6621
6622 if (!NewParm)
6623 return true;
6624
6625 if (ParamInfos)
6626 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6627 OutParamTypes.push_back(Elt: NewParm->getType());
6628 if (PVars)
6629 PVars->push_back(Elt: NewParm);
6630 continue;
6631 }
6632
6633 // Deal with the possibility that we don't have a parameter
6634 // declaration for this parameter.
6635 assert(ParamTypes);
6636 QualType OldType = ParamTypes[i];
6637 bool IsPackExpansion = false;
6638 UnsignedOrNone NumExpansions = std::nullopt;
6639 QualType NewType;
6640 if (const PackExpansionType *Expansion
6641 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6642 // We have a function parameter pack that may need to be expanded.
6643 QualType Pattern = Expansion->getPattern();
6644 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6645 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6646
6647 // Determine whether we should expand the parameter packs.
6648 bool ShouldExpand = false;
6649 bool RetainExpansion = false;
6650 if (getDerived().TryExpandParameterPacks(
6651 Loc, SourceRange(), Unexpanded,
6652 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6653 RetainExpansion, NumExpansions)) {
6654 return true;
6655 }
6656
6657 if (ShouldExpand) {
6658 // Expand the function parameter pack into multiple, separate
6659 // parameters.
6660 for (unsigned I = 0; I != *NumExpansions; ++I) {
6661 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6662 QualType NewType = getDerived().TransformType(Pattern);
6663 if (NewType.isNull())
6664 return true;
6665
6666 if (NewType->containsUnexpandedParameterPack()) {
6667 NewType = getSema().getASTContext().getPackExpansionType(
6668 NewType, std::nullopt);
6669
6670 if (NewType.isNull())
6671 return true;
6672 }
6673
6674 if (ParamInfos)
6675 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6676 OutParamTypes.push_back(Elt: NewType);
6677 if (PVars)
6678 PVars->push_back(Elt: nullptr);
6679 }
6680
6681 // We're done with the pack expansion.
6682 continue;
6683 }
6684
6685 // If we're supposed to retain a pack expansion, do so by temporarily
6686 // forgetting the partially-substituted parameter pack.
6687 if (RetainExpansion) {
6688 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6689 QualType NewType = getDerived().TransformType(Pattern);
6690 if (NewType.isNull())
6691 return true;
6692
6693 if (ParamInfos)
6694 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6695 OutParamTypes.push_back(Elt: NewType);
6696 if (PVars)
6697 PVars->push_back(Elt: nullptr);
6698 }
6699
6700 // We'll substitute the parameter now without expanding the pack
6701 // expansion.
6702 OldType = Expansion->getPattern();
6703 IsPackExpansion = true;
6704 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6705 NewType = getDerived().TransformType(OldType);
6706 } else {
6707 NewType = getDerived().TransformType(OldType);
6708 }
6709
6710 if (NewType.isNull())
6711 return true;
6712
6713 if (IsPackExpansion)
6714 NewType = getSema().Context.getPackExpansionType(NewType,
6715 NumExpansions);
6716
6717 if (ParamInfos)
6718 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6719 OutParamTypes.push_back(Elt: NewType);
6720 if (PVars)
6721 PVars->push_back(Elt: nullptr);
6722 }
6723
6724#ifndef NDEBUG
6725 if (PVars) {
6726 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6727 if (ParmVarDecl *parm = (*PVars)[i])
6728 assert(parm->getFunctionScopeIndex() == i);
6729 }
6730#endif
6731
6732 return false;
6733}
6734
6735template<typename Derived>
6736QualType
6737TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6738 FunctionProtoTypeLoc TL) {
6739 SmallVector<QualType, 4> ExceptionStorage;
6740 return getDerived().TransformFunctionProtoType(
6741 TLB, TL, nullptr, Qualifiers(),
6742 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6743 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6744 ExceptionStorage, Changed);
6745 });
6746}
6747
6748template<typename Derived> template<typename Fn>
6749QualType TreeTransform<Derived>::TransformFunctionProtoType(
6750 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6751 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6752
6753 // Transform the parameters and return type.
6754 //
6755 // We are required to instantiate the params and return type in source order.
6756 // When the function has a trailing return type, we instantiate the
6757 // parameters before the return type, since the return type can then refer
6758 // to the parameters themselves (via decltype, sizeof, etc.).
6759 //
6760 SmallVector<QualType, 4> ParamTypes;
6761 SmallVector<ParmVarDecl*, 4> ParamDecls;
6762 Sema::ExtParameterInfoBuilder ExtParamInfos;
6763 const FunctionProtoType *T = TL.getTypePtr();
6764
6765 QualType ResultType;
6766
6767 if (T->hasTrailingReturn()) {
6768 if (getDerived().TransformFunctionTypeParams(
6769 TL.getBeginLoc(), TL.getParams(),
6770 TL.getTypePtr()->param_type_begin(),
6771 T->getExtParameterInfosOrNull(),
6772 ParamTypes, &ParamDecls, ExtParamInfos))
6773 return QualType();
6774
6775 {
6776 // C++11 [expr.prim.general]p3:
6777 // If a declaration declares a member function or member function
6778 // template of a class X, the expression this is a prvalue of type
6779 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6780 // and the end of the function-definition, member-declarator, or
6781 // declarator.
6782 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6783 Sema::CXXThisScopeRAII ThisScope(
6784 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6785
6786 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6787 if (ResultType.isNull())
6788 return QualType();
6789 }
6790 }
6791 else {
6792 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6793 if (ResultType.isNull())
6794 return QualType();
6795
6796 if (getDerived().TransformFunctionTypeParams(
6797 TL.getBeginLoc(), TL.getParams(),
6798 TL.getTypePtr()->param_type_begin(),
6799 T->getExtParameterInfosOrNull(),
6800 ParamTypes, &ParamDecls, ExtParamInfos))
6801 return QualType();
6802 }
6803
6804 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6805
6806 bool EPIChanged = false;
6807 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6808 return QualType();
6809
6810 // Handle extended parameter information.
6811 if (auto NewExtParamInfos =
6812 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6813 if (!EPI.ExtParameterInfos ||
6814 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6815 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6816 EPIChanged = true;
6817 }
6818 EPI.ExtParameterInfos = NewExtParamInfos;
6819 } else if (EPI.ExtParameterInfos) {
6820 EPIChanged = true;
6821 EPI.ExtParameterInfos = nullptr;
6822 }
6823
6824 // Transform any function effects with unevaluated conditions.
6825 // Hold this set in a local for the rest of this function, since EPI
6826 // may need to hold a FunctionEffectsRef pointing into it.
6827 std::optional<FunctionEffectSet> NewFX;
6828 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6829 NewFX.emplace();
6830 EnterExpressionEvaluationContext Unevaluated(
6831 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6832
6833 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6834 FunctionEffectWithCondition NewEC = PrevEC;
6835 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6836 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6837 if (NewExpr.isInvalid())
6838 return QualType();
6839 std::optional<FunctionEffectMode> Mode =
6840 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6841 if (!Mode)
6842 return QualType();
6843
6844 // The condition expression has been transformed, and re-evaluated.
6845 // It may or may not have become constant.
6846 switch (*Mode) {
6847 case FunctionEffectMode::True:
6848 NewEC.Cond = {};
6849 break;
6850 case FunctionEffectMode::False:
6851 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6852 NewEC.Cond = {};
6853 break;
6854 case FunctionEffectMode::Dependent:
6855 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6856 break;
6857 case FunctionEffectMode::None:
6858 llvm_unreachable(
6859 "FunctionEffectMode::None shouldn't be possible here");
6860 }
6861 }
6862 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6863 NewAttrLoc: TL.getBeginLoc())) {
6864 FunctionEffectSet::Conflicts Errs;
6865 NewFX->insert(NewEC, Errs);
6866 assert(Errs.empty());
6867 }
6868 }
6869 EPI.FunctionEffects = *NewFX;
6870 EPIChanged = true;
6871 }
6872
6873 QualType Result = TL.getType();
6874 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6875 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6876 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6877 if (Result.isNull())
6878 return QualType();
6879 }
6880
6881 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6882 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6883 NewTL.setLParenLoc(TL.getLParenLoc());
6884 NewTL.setRParenLoc(TL.getRParenLoc());
6885 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6886 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6887 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6888 NewTL.setParam(i, VD: ParamDecls[i]);
6889
6890 return Result;
6891}
6892
6893template<typename Derived>
6894bool TreeTransform<Derived>::TransformExceptionSpec(
6895 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6896 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6897 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6898
6899 // Instantiate a dynamic noexcept expression, if any.
6900 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6901 // Update this scrope because ContextDecl in Sema will be used in
6902 // TransformExpr.
6903 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6904 Sema::CXXThisScopeRAII ThisScope(
6905 SemaRef, Method ? Method->getParent() : nullptr,
6906 Method ? Method->getMethodQualifiers() : Qualifiers{},
6907 Method != nullptr);
6908 EnterExpressionEvaluationContext Unevaluated(
6909 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6910 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6911 if (NoexceptExpr.isInvalid())
6912 return true;
6913
6914 ExceptionSpecificationType EST = ESI.Type;
6915 NoexceptExpr =
6916 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6917 if (NoexceptExpr.isInvalid())
6918 return true;
6919
6920 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6921 Changed = true;
6922 ESI.NoexceptExpr = NoexceptExpr.get();
6923 ESI.Type = EST;
6924 }
6925
6926 if (ESI.Type != EST_Dynamic)
6927 return false;
6928
6929 // Instantiate a dynamic exception specification's type.
6930 for (QualType T : ESI.Exceptions) {
6931 if (const PackExpansionType *PackExpansion =
6932 T->getAs<PackExpansionType>()) {
6933 Changed = true;
6934
6935 // We have a pack expansion. Instantiate it.
6936 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6937 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6938 Unexpanded);
6939 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6940
6941 // Determine whether the set of unexpanded parameter packs can and
6942 // should
6943 // be expanded.
6944 bool Expand = false;
6945 bool RetainExpansion = false;
6946 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6947 // FIXME: Track the location of the ellipsis (and track source location
6948 // information for the types in the exception specification in general).
6949 if (getDerived().TryExpandParameterPacks(
6950 Loc, SourceRange(), Unexpanded,
6951 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6952 NumExpansions))
6953 return true;
6954
6955 if (!Expand) {
6956 // We can't expand this pack expansion into separate arguments yet;
6957 // just substitute into the pattern and create a new pack expansion
6958 // type.
6959 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6960 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6961 if (U.isNull())
6962 return true;
6963
6964 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6965 Exceptions.push_back(Elt: U);
6966 continue;
6967 }
6968
6969 // Substitute into the pack expansion pattern for each slice of the
6970 // pack.
6971 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6972 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6973
6974 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6975 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6976 return true;
6977
6978 Exceptions.push_back(Elt: U);
6979 }
6980 } else {
6981 QualType U = getDerived().TransformType(T);
6982 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6983 return true;
6984 if (T != U)
6985 Changed = true;
6986
6987 Exceptions.push_back(Elt: U);
6988 }
6989 }
6990
6991 ESI.Exceptions = Exceptions;
6992 if (ESI.Exceptions.empty())
6993 ESI.Type = EST_DynamicNone;
6994 return false;
6995}
6996
6997template<typename Derived>
6998QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6999 TypeLocBuilder &TLB,
7000 FunctionNoProtoTypeLoc TL) {
7001 const FunctionNoProtoType *T = TL.getTypePtr();
7002 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
7003 if (ResultType.isNull())
7004 return QualType();
7005
7006 QualType Result = TL.getType();
7007 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
7008 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
7009
7010 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
7011 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
7012 NewTL.setLParenLoc(TL.getLParenLoc());
7013 NewTL.setRParenLoc(TL.getRParenLoc());
7014 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
7015
7016 return Result;
7017}
7018
7019template <typename Derived>
7020QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
7021 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
7022
7023 const UnresolvedUsingType *T = TL.getTypePtr();
7024 bool Changed = false;
7025
7026 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7027 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7028 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7029 if (!QualifierLoc)
7030 return QualType();
7031 Changed |= QualifierLoc != OldQualifierLoc;
7032 }
7033
7034 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
7035 if (!D)
7036 return QualType();
7037 Changed |= D != T->getDecl();
7038
7039 QualType Result = TL.getType();
7040 if (getDerived().AlwaysRebuild() || Changed) {
7041 Result = getDerived().RebuildUnresolvedUsingType(
7042 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
7043 D);
7044 if (Result.isNull())
7045 return QualType();
7046 }
7047
7048 if (isa<UsingType>(Val: Result))
7049 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7050 QualifierLoc, NameLoc: TL.getNameLoc());
7051 else
7052 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7053 QualifierLoc, NameLoc: TL.getNameLoc());
7054 return Result;
7055}
7056
7057template <typename Derived>
7058QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
7059 UsingTypeLoc TL) {
7060 const UsingType *T = TL.getTypePtr();
7061 bool Changed = false;
7062
7063 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7064 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7065 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7066 if (!QualifierLoc)
7067 return QualType();
7068 Changed |= QualifierLoc != OldQualifierLoc;
7069 }
7070
7071 auto *D = cast_or_null<UsingShadowDecl>(
7072 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7073 if (!D)
7074 return QualType();
7075 Changed |= D != T->getDecl();
7076
7077 QualType UnderlyingType = getDerived().TransformType(T->desugar());
7078 if (UnderlyingType.isNull())
7079 return QualType();
7080 Changed |= UnderlyingType != T->desugar();
7081
7082 QualType Result = TL.getType();
7083 if (getDerived().AlwaysRebuild() || Changed) {
7084 Result = getDerived().RebuildUsingType(
7085 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
7086 UnderlyingType);
7087 if (Result.isNull())
7088 return QualType();
7089 }
7090 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
7091 NameLoc: TL.getNameLoc());
7092 return Result;
7093}
7094
7095template<typename Derived>
7096QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
7097 TypedefTypeLoc TL) {
7098 const TypedefType *T = TL.getTypePtr();
7099 bool Changed = false;
7100
7101 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7102 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
7103 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7104 if (!QualifierLoc)
7105 return QualType();
7106 Changed |= QualifierLoc != OldQualifierLoc;
7107 }
7108
7109 auto *Typedef = cast_or_null<TypedefNameDecl>(
7110 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7111 if (!Typedef)
7112 return QualType();
7113 Changed |= Typedef != T->getDecl();
7114
7115 // FIXME: Transform the UnderlyingType if different from decl.
7116
7117 QualType Result = TL.getType();
7118 if (getDerived().AlwaysRebuild() || Changed) {
7119 Result = getDerived().RebuildTypedefType(
7120 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
7121 if (Result.isNull())
7122 return QualType();
7123 }
7124
7125 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7126 QualifierLoc, NameLoc: TL.getNameLoc());
7127 return Result;
7128}
7129
7130template<typename Derived>
7131QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7132 TypeOfExprTypeLoc TL) {
7133 // typeof expressions are not potentially evaluated contexts
7134 EnterExpressionEvaluationContext Unevaluated(
7135 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7136 Sema::ReuseLambdaContextDecl);
7137
7138 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7139 if (E.isInvalid())
7140 return QualType();
7141
7142 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7143 if (E.isInvalid())
7144 return QualType();
7145
7146 QualType Result = TL.getType();
7147 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7148 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7149 Result =
7150 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7151 if (Result.isNull())
7152 return QualType();
7153 }
7154
7155 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7156 NewTL.setTypeofLoc(TL.getTypeofLoc());
7157 NewTL.setLParenLoc(TL.getLParenLoc());
7158 NewTL.setRParenLoc(TL.getRParenLoc());
7159
7160 return Result;
7161}
7162
7163template<typename Derived>
7164QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7165 TypeOfTypeLoc TL) {
7166 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7167 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7168 if (!New_Under_TI)
7169 return QualType();
7170
7171 QualType Result = TL.getType();
7172 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7173 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7174 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7175 if (Result.isNull())
7176 return QualType();
7177 }
7178
7179 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7180 NewTL.setTypeofLoc(TL.getTypeofLoc());
7181 NewTL.setLParenLoc(TL.getLParenLoc());
7182 NewTL.setRParenLoc(TL.getRParenLoc());
7183 NewTL.setUnmodifiedTInfo(New_Under_TI);
7184
7185 return Result;
7186}
7187
7188template<typename Derived>
7189QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7190 DecltypeTypeLoc TL) {
7191 const DecltypeType *T = TL.getTypePtr();
7192
7193 // decltype expressions are not potentially evaluated contexts
7194 EnterExpressionEvaluationContext Unevaluated(
7195 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7196 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7197
7198 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7199 if (E.isInvalid())
7200 return QualType();
7201
7202 E = getSema().ActOnDecltypeExpression(E.get());
7203 if (E.isInvalid())
7204 return QualType();
7205
7206 QualType Result = TL.getType();
7207 if (getDerived().AlwaysRebuild() ||
7208 E.get() != T->getUnderlyingExpr()) {
7209 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7210 if (Result.isNull())
7211 return QualType();
7212 }
7213 else E.get();
7214
7215 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7216 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7217 NewTL.setRParenLoc(TL.getRParenLoc());
7218 return Result;
7219}
7220
7221template <typename Derived>
7222QualType
7223TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7224 PackIndexingTypeLoc TL) {
7225 // Transform the index
7226 ExprResult IndexExpr;
7227 {
7228 EnterExpressionEvaluationContext ConstantContext(
7229 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7230
7231 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7232 if (IndexExpr.isInvalid())
7233 return QualType();
7234 }
7235 QualType Pattern = TL.getPattern();
7236
7237 const PackIndexingType *PIT = TL.getTypePtr();
7238 SmallVector<QualType, 5> SubtitutedTypes;
7239 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7240
7241 bool NotYetExpanded = Types.empty();
7242 bool FullySubstituted = true;
7243
7244 if (Types.empty() && !PIT->expandsToEmptyPack())
7245 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7246
7247 for (QualType T : Types) {
7248 if (!T->containsUnexpandedParameterPack()) {
7249 QualType Transformed = getDerived().TransformType(T);
7250 if (Transformed.isNull())
7251 return QualType();
7252 SubtitutedTypes.push_back(Elt: Transformed);
7253 continue;
7254 }
7255
7256 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7257 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7258 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7259 // Determine whether the set of unexpanded parameter packs can and should
7260 // be expanded.
7261 bool ShouldExpand = true;
7262 bool RetainExpansion = false;
7263 UnsignedOrNone NumExpansions = std::nullopt;
7264 if (getDerived().TryExpandParameterPacks(
7265 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7266 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7267 RetainExpansion, NumExpansions))
7268 return QualType();
7269 if (!ShouldExpand) {
7270 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7271 // FIXME: should we keep TypeLoc for individual expansions in
7272 // PackIndexingTypeLoc?
7273 TypeSourceInfo *TI =
7274 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7275 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7276 if (Pack.isNull())
7277 return QualType();
7278 if (NotYetExpanded) {
7279 FullySubstituted = false;
7280 QualType Out = getDerived().RebuildPackIndexingType(
7281 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7282 FullySubstituted);
7283 if (Out.isNull())
7284 return QualType();
7285
7286 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7287 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7288 return Out;
7289 }
7290 SubtitutedTypes.push_back(Elt: Pack);
7291 continue;
7292 }
7293 for (unsigned I = 0; I != *NumExpansions; ++I) {
7294 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7295 QualType Out = getDerived().TransformType(T);
7296 if (Out.isNull())
7297 return QualType();
7298 SubtitutedTypes.push_back(Elt: Out);
7299 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7300 }
7301 // If we're supposed to retain a pack expansion, do so by temporarily
7302 // forgetting the partially-substituted parameter pack.
7303 if (RetainExpansion) {
7304 FullySubstituted = false;
7305 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7306 QualType Out = getDerived().TransformType(T);
7307 if (Out.isNull())
7308 return QualType();
7309 SubtitutedTypes.push_back(Elt: Out);
7310 }
7311 }
7312
7313 // A pack indexing type can appear in a larger pack expansion,
7314 // e.g. `Pack...[pack_of_indexes]...`
7315 // so we need to temporarily disable substitution of pack elements
7316 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7317 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7318
7319 QualType Out = getDerived().RebuildPackIndexingType(
7320 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7321 FullySubstituted, SubtitutedTypes);
7322 if (Out.isNull())
7323 return Out;
7324
7325 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7326 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7327 return Out;
7328}
7329
7330template<typename Derived>
7331QualType TreeTransform<Derived>::TransformUnaryTransformType(
7332 TypeLocBuilder &TLB,
7333 UnaryTransformTypeLoc TL) {
7334 QualType Result = TL.getType();
7335 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7336 if (Result->isDependentType()) {
7337 const UnaryTransformType *T = TL.getTypePtr();
7338
7339 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7340 if (!NewBaseTSI)
7341 return QualType();
7342 QualType NewBase = NewBaseTSI->getType();
7343
7344 Result = getDerived().RebuildUnaryTransformType(NewBase,
7345 T->getUTTKind(),
7346 TL.getKWLoc());
7347 if (Result.isNull())
7348 return QualType();
7349 }
7350
7351 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7352 NewTL.setKWLoc(TL.getKWLoc());
7353 NewTL.setParensRange(TL.getParensRange());
7354 NewTL.setUnderlyingTInfo(NewBaseTSI);
7355 return Result;
7356}
7357
7358template<typename Derived>
7359QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7360 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7361 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7362
7363 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7364 TemplateName TemplateName = getDerived().TransformTemplateName(
7365 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7366 TL.getTemplateNameLoc());
7367 if (TemplateName.isNull())
7368 return QualType();
7369
7370 QualType OldDeduced = T->getDeducedType();
7371 QualType NewDeduced;
7372 if (!OldDeduced.isNull()) {
7373 NewDeduced = getDerived().TransformType(OldDeduced);
7374 if (NewDeduced.isNull())
7375 return QualType();
7376 }
7377
7378 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7379 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7380 NewDeduced, T->getKeyword(), TemplateName);
7381 if (Result.isNull())
7382 return QualType();
7383
7384 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7385 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7386 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7387 NewTL.setQualifierLoc(QualifierLoc);
7388 return Result;
7389}
7390
7391template <typename Derived>
7392QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7393 TagTypeLoc TL) {
7394 const TagType *T = TL.getTypePtr();
7395
7396 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7397 if (QualifierLoc) {
7398 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7399 if (!QualifierLoc)
7400 return QualType();
7401 }
7402
7403 auto *TD = cast_or_null<TagDecl>(
7404 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7405 if (!TD)
7406 return QualType();
7407
7408 QualType Result = TL.getType();
7409 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7410 TD != T->getDecl()) {
7411 if (T->isCanonicalUnqualified())
7412 Result = getDerived().RebuildCanonicalTagType(TD);
7413 else
7414 Result = getDerived().RebuildTagType(
7415 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7416 if (Result.isNull())
7417 return QualType();
7418 }
7419
7420 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7421 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7422 NewTL.setQualifierLoc(QualifierLoc);
7423 NewTL.setNameLoc(TL.getNameLoc());
7424
7425 return Result;
7426}
7427
7428template <typename Derived>
7429QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7430 EnumTypeLoc TL) {
7431 return getDerived().TransformTagType(TLB, TL);
7432}
7433
7434template <typename Derived>
7435QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7436 RecordTypeLoc TL) {
7437 return getDerived().TransformTagType(TLB, TL);
7438}
7439
7440template<typename Derived>
7441QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7442 TypeLocBuilder &TLB,
7443 InjectedClassNameTypeLoc TL) {
7444 return getDerived().TransformTagType(TLB, TL);
7445}
7446
7447template<typename Derived>
7448QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7449 TypeLocBuilder &TLB,
7450 TemplateTypeParmTypeLoc TL) {
7451 return getDerived().TransformTemplateTypeParmType(
7452 TLB, TL,
7453 /*SuppressObjCLifetime=*/false);
7454}
7455
7456template <typename Derived>
7457QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7458 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7459 return TransformTypeSpecType(TLB, T: TL);
7460}
7461
7462template<typename Derived>
7463QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7464 TypeLocBuilder &TLB,
7465 SubstTemplateTypeParmTypeLoc TL) {
7466 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7467
7468 Decl *NewReplaced =
7469 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7470
7471 // Substitute into the replacement type, which itself might involve something
7472 // that needs to be transformed. This only tends to occur with default
7473 // template arguments of template template parameters.
7474 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7475 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7476 if (Replacement.isNull())
7477 return QualType();
7478
7479 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7480 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7481 Final: T->getFinal());
7482
7483 // Propagate type-source information.
7484 SubstTemplateTypeParmTypeLoc NewTL
7485 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7486 NewTL.setNameLoc(TL.getNameLoc());
7487 return Result;
7488
7489}
7490template <typename Derived>
7491QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7492 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7493 return TransformTypeSpecType(TLB, T: TL);
7494}
7495
7496template<typename Derived>
7497QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7498 TypeLocBuilder &TLB,
7499 SubstTemplateTypeParmPackTypeLoc TL) {
7500 return getDerived().TransformSubstTemplateTypeParmPackType(
7501 TLB, TL, /*SuppressObjCLifetime=*/false);
7502}
7503
7504template <typename Derived>
7505QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7506 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7507 return TransformTypeSpecType(TLB, T: TL);
7508}
7509
7510template<typename Derived>
7511QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7512 AtomicTypeLoc TL) {
7513 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7514 if (ValueType.isNull())
7515 return QualType();
7516
7517 QualType Result = TL.getType();
7518 if (getDerived().AlwaysRebuild() ||
7519 ValueType != TL.getValueLoc().getType()) {
7520 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7521 if (Result.isNull())
7522 return QualType();
7523 }
7524
7525 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7526 NewTL.setKWLoc(TL.getKWLoc());
7527 NewTL.setLParenLoc(TL.getLParenLoc());
7528 NewTL.setRParenLoc(TL.getRParenLoc());
7529
7530 return Result;
7531}
7532
7533template <typename Derived>
7534QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7535 PipeTypeLoc TL) {
7536 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7537 if (ValueType.isNull())
7538 return QualType();
7539
7540 QualType Result = TL.getType();
7541 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7542 const PipeType *PT = Result->castAs<PipeType>();
7543 bool isReadPipe = PT->isReadOnly();
7544 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7545 if (Result.isNull())
7546 return QualType();
7547 }
7548
7549 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7550 NewTL.setKWLoc(TL.getKWLoc());
7551
7552 return Result;
7553}
7554
7555template <typename Derived>
7556QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7557 BitIntTypeLoc TL) {
7558 const BitIntType *EIT = TL.getTypePtr();
7559 QualType Result = TL.getType();
7560
7561 if (getDerived().AlwaysRebuild()) {
7562 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7563 EIT->getNumBits(), TL.getNameLoc());
7564 if (Result.isNull())
7565 return QualType();
7566 }
7567
7568 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7569 NewTL.setNameLoc(TL.getNameLoc());
7570 return Result;
7571}
7572
7573template <typename Derived>
7574QualType TreeTransform<Derived>::TransformDependentBitIntType(
7575 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7576 const DependentBitIntType *EIT = TL.getTypePtr();
7577
7578 EnterExpressionEvaluationContext Unevaluated(
7579 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7580 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7581 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7582
7583 if (BitsExpr.isInvalid())
7584 return QualType();
7585
7586 QualType Result = TL.getType();
7587
7588 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7589 Result = getDerived().RebuildDependentBitIntType(
7590 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7591
7592 if (Result.isNull())
7593 return QualType();
7594 }
7595
7596 if (isa<DependentBitIntType>(Val: Result)) {
7597 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7598 NewTL.setNameLoc(TL.getNameLoc());
7599 } else {
7600 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7601 NewTL.setNameLoc(TL.getNameLoc());
7602 }
7603 return Result;
7604}
7605
7606template <typename Derived>
7607QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7608 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7609 llvm_unreachable("This type does not need to be transformed.");
7610}
7611
7612 /// Simple iterator that traverses the template arguments in a
7613 /// container that provides a \c getArgLoc() member function.
7614 ///
7615 /// This iterator is intended to be used with the iterator form of
7616 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7617 template<typename ArgLocContainer>
7618 class TemplateArgumentLocContainerIterator {
7619 ArgLocContainer *Container;
7620 unsigned Index;
7621
7622 public:
7623 typedef TemplateArgumentLoc value_type;
7624 typedef TemplateArgumentLoc reference;
7625 typedef int difference_type;
7626 typedef std::input_iterator_tag iterator_category;
7627
7628 class pointer {
7629 TemplateArgumentLoc Arg;
7630
7631 public:
7632 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7633
7634 const TemplateArgumentLoc *operator->() const {
7635 return &Arg;
7636 }
7637 };
7638
7639
7640 TemplateArgumentLocContainerIterator() {}
7641
7642 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7643 unsigned Index)
7644 : Container(&Container), Index(Index) { }
7645
7646 TemplateArgumentLocContainerIterator &operator++() {
7647 ++Index;
7648 return *this;
7649 }
7650
7651 TemplateArgumentLocContainerIterator operator++(int) {
7652 TemplateArgumentLocContainerIterator Old(*this);
7653 ++(*this);
7654 return Old;
7655 }
7656
7657 TemplateArgumentLoc operator*() const {
7658 return Container->getArgLoc(Index);
7659 }
7660
7661 pointer operator->() const {
7662 return pointer(Container->getArgLoc(Index));
7663 }
7664
7665 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7666 const TemplateArgumentLocContainerIterator &Y) {
7667 return X.Container == Y.Container && X.Index == Y.Index;
7668 }
7669
7670 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7671 const TemplateArgumentLocContainerIterator &Y) {
7672 return !(X == Y);
7673 }
7674 };
7675
7676template<typename Derived>
7677QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7678 AutoTypeLoc TL) {
7679 const AutoType *T = TL.getTypePtr();
7680 QualType OldDeduced = T->getDeducedType();
7681 QualType NewDeduced;
7682 if (!OldDeduced.isNull()) {
7683 NewDeduced = getDerived().TransformType(OldDeduced);
7684 if (NewDeduced.isNull())
7685 return QualType();
7686 }
7687
7688 TemplateName NewCD;
7689 TemplateArgumentListInfo NewTemplateArgs;
7690 NestedNameSpecifierLoc NewNestedNameSpec;
7691 if (T->isConstrained()) {
7692 assert(TL.getConceptReference());
7693 NewCD = getDerived().TransformConceptTemplateName(
7694 T->getTypeConstraintConcept(), TL.getConceptNameLoc());
7695 if (NewCD.isNull())
7696 return QualType();
7697
7698 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7699 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7700 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7701 if (getDerived().TransformTemplateArguments(
7702 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7703 NewTemplateArgs))
7704 return QualType();
7705
7706 if (TL.getNestedNameSpecifierLoc()) {
7707 NewNestedNameSpec
7708 = getDerived().TransformNestedNameSpecifierLoc(
7709 TL.getNestedNameSpecifierLoc());
7710 if (!NewNestedNameSpec)
7711 return QualType();
7712 }
7713 }
7714
7715 QualType Result = TL.getType();
7716 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7717 T->isDependentType() || T->isConstrained()) {
7718 // FIXME: Maybe don't rebuild if all template arguments are the same.
7719 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7720 NewArgList.reserve(N: NewTemplateArgs.size());
7721 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7722 NewArgList.push_back(Elt: ArgLoc.getArgument());
7723 Result = getDerived().RebuildAutoType(
7724 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7725 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7726 if (Result.isNull())
7727 return QualType();
7728 }
7729
7730 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7731 NewTL.setNameLoc(TL.getNameLoc());
7732 NewTL.setRParenLoc(TL.getRParenLoc());
7733 NewTL.setConceptReference(nullptr);
7734
7735 if (T->isConstrained()) {
7736 DeclarationName ConceptName =
7737 SemaRef.Context
7738 .getNameForTemplate(Name: TL.getTypePtr()->getTypeConstraintConcept(),
7739 NameLoc: TL.getConceptNameLoc())
7740 .getName();
7741 DeclarationNameInfo DNI =
7742 DeclarationNameInfo(ConceptName, TL.getConceptNameLoc(), ConceptName);
7743 auto *CR = ConceptReference::Create(
7744 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7745 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7746 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7747 NewTL.setConceptReference(CR);
7748 }
7749
7750 return Result;
7751}
7752
7753template <typename Derived>
7754QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7755 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7756 return getDerived().TransformTemplateSpecializationType(
7757 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7758 /*AllowInjectedClassName=*/false);
7759}
7760
7761template <typename Derived>
7762QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7763 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7764 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7765 const TemplateSpecializationType *T = TL.getTypePtr();
7766
7767 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7768 TemplateName Template = getDerived().TransformTemplateName(
7769 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7770 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7771 AllowInjectedClassName);
7772 if (Template.isNull())
7773 return QualType();
7774
7775 TemplateArgumentListInfo NewTemplateArgs;
7776 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7777 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7778 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7779 ArgIterator;
7780 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7781 ArgIterator(TL, TL.getNumArgs()),
7782 NewTemplateArgs))
7783 return QualType();
7784
7785 // This needs to be rebuilt if either the arguments changed, or if the
7786 // original template changed. If the template changed, and even if the
7787 // arguments didn't change, these arguments might not correspond to their
7788 // respective parameters, therefore needing conversions.
7789 QualType Result = getDerived().RebuildTemplateSpecializationType(
7790 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7791 NewTemplateArgs);
7792
7793 if (!Result.isNull()) {
7794 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7795 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7796 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7797 }
7798
7799 return Result;
7800}
7801
7802template <typename Derived>
7803QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7804 AttributedTypeLoc TL) {
7805 const AttributedType *oldType = TL.getTypePtr();
7806 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7807 if (modifiedType.isNull())
7808 return QualType();
7809
7810 // HLSL: re-validate matrix-layout markers after substitution. If the
7811 // post-substitution type is no longer a matrix, diagnose now.
7812 if (SemaRef.getLangOpts().HLSL &&
7813 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7814 K: oldType->getAttrKind(), T: modifiedType,
7815 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7816 : TL.getModifiedLoc().getBeginLoc()))
7817 return QualType();
7818
7819 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7820 const Attr *oldAttr = TL.getAttr();
7821 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7822 if (oldAttr && !newAttr)
7823 return QualType();
7824
7825 QualType result = TL.getType();
7826
7827 // FIXME: dependent operand expressions?
7828 if (getDerived().AlwaysRebuild() ||
7829 modifiedType != oldType->getModifiedType()) {
7830 // If the equivalent type is equal to the modified type, we don't want to
7831 // transform it as well because:
7832 //
7833 // 1. The transformation would yield the same result and is therefore
7834 // superfluous, and
7835 //
7836 // 2. Transforming the same type twice can cause problems, e.g. if it
7837 // is a FunctionProtoType, we may end up instantiating the function
7838 // parameters twice, which causes an assertion since the parameters
7839 // are already bound to their counterparts in the template for this
7840 // instantiation.
7841 //
7842 QualType equivalentType = modifiedType;
7843 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7844 TypeLocBuilder AuxiliaryTLB;
7845 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7846 equivalentType =
7847 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7848 if (equivalentType.isNull())
7849 return QualType();
7850 }
7851
7852 // Check whether we can add nullability; it is only represented as
7853 // type sugar, and therefore cannot be diagnosed in any other way.
7854 if (auto nullability = oldType->getImmediateNullability()) {
7855 if (!modifiedType->canHaveNullability()) {
7856 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7857 : TL.getModifiedLoc().getBeginLoc()),
7858 DiagID: diag::err_nullability_nonpointer)
7859 << DiagNullabilityKind(*nullability, false) << modifiedType;
7860 return QualType();
7861 }
7862 }
7863
7864 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7865 modifiedType,
7866 equivalentType,
7867 attr: TL.getAttr());
7868 }
7869
7870 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7871 newTL.setAttr(newAttr);
7872 return result;
7873}
7874
7875template <typename Derived>
7876QualType TreeTransform<Derived>::TransformCountAttributedType(
7877 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7878 const CountAttributedType *OldTy = TL.getTypePtr();
7879 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7880 if (InnerTy.isNull())
7881 return QualType();
7882
7883 Expr *OldCount = TL.getCountExpr();
7884 Expr *NewCount = nullptr;
7885 if (OldCount) {
7886 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7887 if (CountResult.isInvalid())
7888 return QualType();
7889 NewCount = CountResult.get();
7890 }
7891
7892 QualType Result = TL.getType();
7893 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7894 OldCount != NewCount) {
7895 // Currently, CountAttributedType can only wrap incomplete array types.
7896 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7897 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7898 }
7899
7900 TLB.push<CountAttributedTypeLoc>(T: Result);
7901 return Result;
7902}
7903
7904template <typename Derived>
7905QualType
7906TreeTransform<Derived>::TransformLateParsedAttrType(TypeLocBuilder &TLB,
7907 LateParsedAttrTypeLoc TL) {
7908 const LateParsedAttrType *OldTy = TL.getTypePtr();
7909 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7910 if (InnerTy.isNull())
7911 return QualType();
7912
7913 QualType Result = TL.getType();
7914 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getWrappedType()) {
7915 Result = SemaRef.Context.getLateParsedAttrType(
7916 Wrapped: InnerTy, LateParsedAttr: OldTy->getLateParsedAttribute());
7917 }
7918
7919 LateParsedAttrTypeLoc newTL = TLB.push<LateParsedAttrTypeLoc>(T: Result);
7920 newTL.setAttrNameLoc(TL.getAttrNameLoc());
7921 return Result;
7922}
7923
7924template <typename Derived>
7925QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7926 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7927 // The BTFTagAttributedType is available for C only.
7928 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7929}
7930
7931template <typename Derived>
7932QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7933 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7934 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7935 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7936 if (InnerTy.isNull())
7937 return QualType();
7938
7939 QualType Result = TL.getType();
7940 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7941 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7942 Wrapped: InnerTy);
7943 if (Result.isNull())
7944 return QualType();
7945 }
7946
7947 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7948 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7949 return Result;
7950}
7951
7952template <typename Derived>
7953QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7954 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7955
7956 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7957
7958 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7959 if (WrappedTy.isNull())
7960 return QualType();
7961
7962 QualType ContainedTy = QualType();
7963 QualType OldContainedTy = oldType->getContainedType();
7964 TypeSourceInfo *ContainedTSI = nullptr;
7965 if (!OldContainedTy.isNull()) {
7966 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7967 if (!oldContainedTSI)
7968 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7969 OldContainedTy, SourceLocation());
7970 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7971 if (!ContainedTSI)
7972 return QualType();
7973 ContainedTy = ContainedTSI->getType();
7974 }
7975
7976 HLSLAttributedResourceType::Attributes Attrs = oldType->getAttrs();
7977 if (Attrs.SampleCountExpr) {
7978 ExprResult SampleCountResult =
7979 getDerived().TransformExpr(Attrs.SampleCountExpr);
7980 if (SampleCountResult.isInvalid())
7981 return QualType();
7982 Attrs.SampleCountExpr = SampleCountResult.get();
7983 }
7984
7985 QualType Result = TL.getType();
7986 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7987 ContainedTy != oldType->getContainedType() ||
7988 Attrs.SampleCountExpr != oldType->getSampleCountExpr()) {
7989 Result = SemaRef.Context.getHLSLAttributedResourceType(Wrapped: WrappedTy,
7990 Contained: ContainedTy, Attrs);
7991 }
7992
7993 HLSLAttributedResourceTypeLoc NewTL =
7994 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7995 NewTL.setSourceRange(TL.getLocalSourceRange());
7996 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7997 return Result;
7998}
7999
8000template <typename Derived>
8001QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
8002 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
8003 // No transformations needed.
8004 return TL.getType();
8005}
8006
8007template<typename Derived>
8008QualType
8009TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
8010 ParenTypeLoc TL) {
8011 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8012 if (Inner.isNull())
8013 return QualType();
8014
8015 QualType Result = TL.getType();
8016 if (getDerived().AlwaysRebuild() ||
8017 Inner != TL.getInnerLoc().getType()) {
8018 Result = getDerived().RebuildParenType(Inner);
8019 if (Result.isNull())
8020 return QualType();
8021 }
8022
8023 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
8024 NewTL.setLParenLoc(TL.getLParenLoc());
8025 NewTL.setRParenLoc(TL.getRParenLoc());
8026 return Result;
8027}
8028
8029template <typename Derived>
8030QualType
8031TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
8032 MacroQualifiedTypeLoc TL) {
8033 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
8034 if (Inner.isNull())
8035 return QualType();
8036
8037 QualType Result = TL.getType();
8038 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
8039 Result =
8040 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
8041 if (Result.isNull())
8042 return QualType();
8043 }
8044
8045 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
8046 NewTL.setExpansionLoc(TL.getExpansionLoc());
8047 return Result;
8048}
8049
8050template<typename Derived>
8051QualType TreeTransform<Derived>::TransformDependentNameType(
8052 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
8053 return TransformDependentNameType(TLB, TL, false);
8054}
8055
8056template <typename Derived>
8057QualType TreeTransform<Derived>::TransformDependentNameType(
8058 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
8059 QualType ObjectType, NamedDecl *UnqualLookup) {
8060 const DependentNameType *T = TL.getTypePtr();
8061
8062 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
8063 if (QualifierLoc) {
8064 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
8065 QualifierLoc, ObjectType, UnqualLookup);
8066 if (!QualifierLoc)
8067 return QualType();
8068 } else {
8069 assert((ObjectType.isNull() && !UnqualLookup) &&
8070 "must be transformed by TransformNestedNameSpecifierLoc");
8071 }
8072
8073 QualType Result
8074 = getDerived().RebuildDependentNameType(T->getKeyword(),
8075 TL.getElaboratedKeywordLoc(),
8076 QualifierLoc,
8077 T->getIdentifier(),
8078 TL.getNameLoc(),
8079 DeducedTSTContext);
8080 if (Result.isNull())
8081 return QualType();
8082
8083 if (isa<TagType>(Val: Result)) {
8084 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
8085 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8086 NewTL.setQualifierLoc(QualifierLoc);
8087 NewTL.setNameLoc(TL.getNameLoc());
8088 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
8089 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
8090 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8091 NewTL.setTemplateNameLoc(TL.getNameLoc());
8092 NewTL.setQualifierLoc(QualifierLoc);
8093 } else if (isa<TypedefType>(Val: Result)) {
8094 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
8095 QualifierLoc, NameLoc: TL.getNameLoc());
8096 } else if (isa<UnresolvedUsingType>(Val: Result)) {
8097 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
8098 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
8099 } else {
8100 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
8101 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
8102 NewTL.setQualifierLoc(QualifierLoc);
8103 NewTL.setNameLoc(TL.getNameLoc());
8104 }
8105 return Result;
8106}
8107
8108template<typename Derived>
8109QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
8110 PackExpansionTypeLoc TL) {
8111 QualType Pattern
8112 = getDerived().TransformType(TLB, TL.getPatternLoc());
8113 if (Pattern.isNull())
8114 return QualType();
8115
8116 QualType Result = TL.getType();
8117 if (getDerived().AlwaysRebuild() ||
8118 Pattern != TL.getPatternLoc().getType()) {
8119 Result = getDerived().RebuildPackExpansionType(Pattern,
8120 TL.getPatternLoc().getSourceRange(),
8121 TL.getEllipsisLoc(),
8122 TL.getTypePtr()->getNumExpansions());
8123 if (Result.isNull())
8124 return QualType();
8125 }
8126
8127 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
8128 NewT.setEllipsisLoc(TL.getEllipsisLoc());
8129 return Result;
8130}
8131
8132template<typename Derived>
8133QualType
8134TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
8135 ObjCInterfaceTypeLoc TL) {
8136 // ObjCInterfaceType is never dependent.
8137 TLB.pushFullCopy(L: TL);
8138 return TL.getType();
8139}
8140
8141template<typename Derived>
8142QualType
8143TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
8144 ObjCTypeParamTypeLoc TL) {
8145 const ObjCTypeParamType *T = TL.getTypePtr();
8146 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
8147 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
8148 if (!OTP)
8149 return QualType();
8150
8151 QualType Result = TL.getType();
8152 if (getDerived().AlwaysRebuild() ||
8153 OTP != T->getDecl()) {
8154 Result = getDerived().RebuildObjCTypeParamType(
8155 OTP, TL.getProtocolLAngleLoc(),
8156 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8157 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8158 if (Result.isNull())
8159 return QualType();
8160 }
8161
8162 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
8163 if (TL.getNumProtocols()) {
8164 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8165 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8166 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8167 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8168 }
8169 return Result;
8170}
8171
8172template<typename Derived>
8173QualType
8174TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8175 ObjCObjectTypeLoc TL) {
8176 // Transform base type.
8177 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8178 if (BaseType.isNull())
8179 return QualType();
8180
8181 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8182
8183 // Transform type arguments.
8184 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8185 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8186 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8187 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8188 QualType TypeArg = TypeArgInfo->getType();
8189 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8190 AnyChanged = true;
8191
8192 // We have a pack expansion. Instantiate it.
8193 const auto *PackExpansion = PackExpansionLoc.getType()
8194 ->castAs<PackExpansionType>();
8195 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8196 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8197 Unexpanded);
8198 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8199
8200 // Determine whether the set of unexpanded parameter packs can
8201 // and should be expanded.
8202 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8203 bool Expand = false;
8204 bool RetainExpansion = false;
8205 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8206 if (getDerived().TryExpandParameterPacks(
8207 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8208 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8209 RetainExpansion, NumExpansions))
8210 return QualType();
8211
8212 if (!Expand) {
8213 // We can't expand this pack expansion into separate arguments yet;
8214 // just substitute into the pattern and create a new pack expansion
8215 // type.
8216 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8217
8218 TypeLocBuilder TypeArgBuilder;
8219 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8220 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8221 PatternLoc);
8222 if (NewPatternType.isNull())
8223 return QualType();
8224
8225 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8226 Pattern: NewPatternType, NumExpansions);
8227 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8228 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8229 NewTypeArgInfos.push_back(
8230 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8231 continue;
8232 }
8233
8234 // Substitute into the pack expansion pattern for each slice of the
8235 // pack.
8236 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8237 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8238
8239 TypeLocBuilder TypeArgBuilder;
8240 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8241
8242 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8243 PatternLoc);
8244 if (NewTypeArg.isNull())
8245 return QualType();
8246
8247 NewTypeArgInfos.push_back(
8248 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8249 }
8250
8251 continue;
8252 }
8253
8254 TypeLocBuilder TypeArgBuilder;
8255 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8256 QualType NewTypeArg =
8257 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8258 if (NewTypeArg.isNull())
8259 return QualType();
8260
8261 // If nothing changed, just keep the old TypeSourceInfo.
8262 if (NewTypeArg == TypeArg) {
8263 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8264 continue;
8265 }
8266
8267 NewTypeArgInfos.push_back(
8268 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8269 AnyChanged = true;
8270 }
8271
8272 QualType Result = TL.getType();
8273 if (getDerived().AlwaysRebuild() || AnyChanged) {
8274 // Rebuild the type.
8275 Result = getDerived().RebuildObjCObjectType(
8276 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8277 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8278 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8279 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8280
8281 if (Result.isNull())
8282 return QualType();
8283 }
8284
8285 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8286 NewT.setHasBaseTypeAsWritten(true);
8287 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8288 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8289 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8290 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8291 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8292 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8293 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8294 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8295 return Result;
8296}
8297
8298template<typename Derived>
8299QualType
8300TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8301 ObjCObjectPointerTypeLoc TL) {
8302 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8303 if (PointeeType.isNull())
8304 return QualType();
8305
8306 QualType Result = TL.getType();
8307 if (getDerived().AlwaysRebuild() ||
8308 PointeeType != TL.getPointeeLoc().getType()) {
8309 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8310 TL.getStarLoc());
8311 if (Result.isNull())
8312 return QualType();
8313 }
8314
8315 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8316 NewT.setStarLoc(TL.getStarLoc());
8317 return Result;
8318}
8319
8320//===----------------------------------------------------------------------===//
8321// Statement transformation
8322//===----------------------------------------------------------------------===//
8323template<typename Derived>
8324StmtResult
8325TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8326 return S;
8327}
8328
8329template<typename Derived>
8330StmtResult
8331TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8332 return getDerived().TransformCompoundStmt(S, false);
8333}
8334
8335template<typename Derived>
8336StmtResult
8337TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8338 bool IsStmtExpr) {
8339 Sema::CompoundScopeRAII CompoundScope(getSema());
8340 Sema::FPFeaturesStateRAII FPSave(getSema());
8341 if (S->hasStoredFPFeatures())
8342 getSema().resetFPOptions(
8343 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8344
8345 bool SubStmtInvalid = false;
8346 bool SubStmtChanged = false;
8347 SmallVector<Stmt*, 8> Statements;
8348 for (auto *B : S->body()) {
8349 StmtResult Result = getDerived().TransformStmt(
8350 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8351 : StmtDiscardKind::Discarded);
8352
8353 if (Result.isInvalid()) {
8354 // Immediately fail if this was a DeclStmt, since it's very
8355 // likely that this will cause problems for future statements.
8356 if (isa<DeclStmt>(Val: B))
8357 return StmtError();
8358
8359 // Otherwise, just keep processing substatements and fail later.
8360 SubStmtInvalid = true;
8361 continue;
8362 }
8363
8364 SubStmtChanged = SubStmtChanged || Result.get() != B;
8365 Statements.push_back(Elt: Result.getAs<Stmt>());
8366 }
8367
8368 if (SubStmtInvalid)
8369 return StmtError();
8370
8371 if (!getDerived().AlwaysRebuild() &&
8372 !SubStmtChanged)
8373 return S;
8374
8375 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8376 Statements,
8377 S->getRBracLoc(),
8378 IsStmtExpr);
8379}
8380
8381template<typename Derived>
8382StmtResult
8383TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8384 ExprResult LHS, RHS;
8385 {
8386 EnterExpressionEvaluationContext Unevaluated(
8387 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8388
8389 // Transform the left-hand case value.
8390 LHS = getDerived().TransformExpr(S->getLHS());
8391 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8392 if (LHS.isInvalid())
8393 return StmtError();
8394
8395 // Transform the right-hand case value (for the GNU case-range extension).
8396 RHS = getDerived().TransformExpr(S->getRHS());
8397 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8398 if (RHS.isInvalid())
8399 return StmtError();
8400 }
8401
8402 // Build the case statement.
8403 // Case statements are always rebuilt so that they will attached to their
8404 // transformed switch statement.
8405 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8406 LHS.get(),
8407 S->getEllipsisLoc(),
8408 RHS.get(),
8409 S->getColonLoc());
8410 if (Case.isInvalid())
8411 return StmtError();
8412
8413 // Transform the statement following the case
8414 StmtResult SubStmt =
8415 getDerived().TransformStmt(S->getSubStmt());
8416 if (SubStmt.isInvalid())
8417 return StmtError();
8418
8419 // Attach the body to the case statement
8420 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8421}
8422
8423template <typename Derived>
8424StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8425 // Transform the statement following the default case
8426 StmtResult SubStmt =
8427 getDerived().TransformStmt(S->getSubStmt());
8428 if (SubStmt.isInvalid())
8429 return StmtError();
8430
8431 // Default statements are always rebuilt
8432 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8433 SubStmt.get());
8434}
8435
8436template<typename Derived>
8437StmtResult
8438TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8439 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8440 if (SubStmt.isInvalid())
8441 return StmtError();
8442
8443 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8444 S->getDecl());
8445 if (!LD)
8446 return StmtError();
8447
8448 // If we're transforming "in-place" (we're not creating new local
8449 // declarations), assume we're replacing the old label statement
8450 // and clear out the reference to it.
8451 if (LD == S->getDecl())
8452 S->getDecl()->setStmt(nullptr);
8453
8454 // FIXME: Pass the real colon location in.
8455 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8456 cast<LabelDecl>(Val: LD), SourceLocation(),
8457 SubStmt.get());
8458}
8459
8460template <typename Derived>
8461const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8462 if (!R)
8463 return R;
8464
8465 switch (R->getKind()) {
8466// Transform attributes by calling TransformXXXAttr.
8467#define ATTR(X) \
8468 case attr::X: \
8469 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8470#include "clang/Basic/AttrList.inc"
8471 }
8472 return R;
8473}
8474
8475template <typename Derived>
8476const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8477 const Stmt *InstS,
8478 const Attr *R) {
8479 if (!R)
8480 return R;
8481
8482 switch (R->getKind()) {
8483// Transform attributes by calling TransformStmtXXXAttr.
8484#define ATTR(X) \
8485 case attr::X: \
8486 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8487#include "clang/Basic/AttrList.inc"
8488 }
8489 return TransformAttr(R);
8490}
8491
8492template <typename Derived>
8493StmtResult
8494TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8495 StmtDiscardKind SDK) {
8496 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8497 if (SubStmt.isInvalid())
8498 return StmtError();
8499
8500 bool AttrsChanged = false;
8501 SmallVector<const Attr *, 1> Attrs;
8502
8503 // Visit attributes and keep track if any are transformed.
8504 for (const auto *I : S->getAttrs()) {
8505 const Attr *R =
8506 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8507 AttrsChanged |= (I != R);
8508 if (R)
8509 Attrs.push_back(Elt: R);
8510 }
8511
8512 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8513 return S;
8514
8515 // If transforming the attributes failed for all of the attributes in the
8516 // statement, don't make an AttributedStmt without attributes.
8517 if (Attrs.empty())
8518 return SubStmt;
8519
8520 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8521 SubStmt.get());
8522}
8523
8524template<typename Derived>
8525StmtResult
8526TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8527 // Transform the initialization statement
8528 StmtResult Init = getDerived().TransformStmt(S->getInit());
8529 if (Init.isInvalid())
8530 return StmtError();
8531
8532 Sema::ConditionResult Cond;
8533 if (!S->isConsteval()) {
8534 // Transform the condition
8535 Cond = getDerived().TransformCondition(
8536 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8537 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8538 : Sema::ConditionKind::Boolean);
8539 if (Cond.isInvalid())
8540 return StmtError();
8541 }
8542
8543 // If this is a constexpr if, determine which arm we should instantiate.
8544 std::optional<bool> ConstexprConditionValue;
8545 if (S->isConstexpr())
8546 ConstexprConditionValue = Cond.getKnownValue();
8547
8548 // Transform the "then" branch.
8549 StmtResult Then;
8550 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8551 EnterExpressionEvaluationContext Ctx(
8552 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8553 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8554 S->isNonNegatedConsteval());
8555
8556 Then = getDerived().TransformStmt(S->getThen());
8557 if (Then.isInvalid())
8558 return StmtError();
8559 } else {
8560 // Discarded branch is replaced with empty CompoundStmt so we can keep
8561 // proper source location for start and end of original branch, so
8562 // subsequent transformations like CoverageMapping work properly
8563 Then = new (getSema().Context)
8564 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8565 }
8566
8567 // Transform the "else" branch.
8568 StmtResult Else;
8569 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8570 EnterExpressionEvaluationContext Ctx(
8571 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8572 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8573 S->isNegatedConsteval());
8574
8575 Else = getDerived().TransformStmt(S->getElse());
8576 if (Else.isInvalid())
8577 return StmtError();
8578 } else if (S->getElse() && ConstexprConditionValue &&
8579 *ConstexprConditionValue) {
8580 // Same thing here as with <then> branch, we are discarding it, we can't
8581 // replace it with NULL nor NullStmt as we need to keep for source location
8582 // range, for CoverageMapping
8583 Else = new (getSema().Context)
8584 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8585 }
8586
8587 if (!getDerived().AlwaysRebuild() &&
8588 Init.get() == S->getInit() &&
8589 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8590 Then.get() == S->getThen() &&
8591 Else.get() == S->getElse())
8592 return S;
8593
8594 return getDerived().RebuildIfStmt(
8595 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8596 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8597}
8598
8599template<typename Derived>
8600StmtResult
8601TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8602 // Transform the initialization statement
8603 StmtResult Init = getDerived().TransformStmt(S->getInit());
8604 if (Init.isInvalid())
8605 return StmtError();
8606
8607 // Transform the condition.
8608 Sema::ConditionResult Cond = getDerived().TransformCondition(
8609 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8610 Sema::ConditionKind::Switch);
8611 if (Cond.isInvalid())
8612 return StmtError();
8613
8614 // Rebuild the switch statement.
8615 StmtResult Switch =
8616 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8617 Init.get(), Cond, S->getRParenLoc());
8618 if (Switch.isInvalid())
8619 return StmtError();
8620
8621 // Transform the body of the switch statement.
8622 StmtResult Body = getDerived().TransformStmt(S->getBody());
8623
8624 // Complete the switch statement.
8625 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8626 Body.get());
8627}
8628
8629template<typename Derived>
8630StmtResult
8631TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8632 // Transform the condition
8633 Sema::ConditionResult Cond = getDerived().TransformCondition(
8634 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8635 Sema::ConditionKind::Boolean);
8636 if (Cond.isInvalid())
8637 return StmtError();
8638
8639 // OpenACC Restricts a while-loop inside of certain construct/clause
8640 // combinations, so diagnose that here in OpenACC mode.
8641 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8642 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8643
8644 // Transform the body
8645 StmtResult Body = getDerived().TransformStmt(S->getBody());
8646 if (Body.isInvalid())
8647 return StmtError();
8648
8649 if (!getDerived().AlwaysRebuild() &&
8650 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8651 Body.get() == S->getBody())
8652 return Owned(S);
8653
8654 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8655 Cond, S->getRParenLoc(), Body.get());
8656}
8657
8658template<typename Derived>
8659StmtResult
8660TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8661 // OpenACC Restricts a do-loop inside of certain construct/clause
8662 // combinations, so diagnose that here in OpenACC mode.
8663 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8664 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8665
8666 // Transform the body
8667 StmtResult Body = getDerived().TransformStmt(S->getBody());
8668 if (Body.isInvalid())
8669 return StmtError();
8670
8671 // Transform the condition
8672 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8673 if (Cond.isInvalid())
8674 return StmtError();
8675
8676 if (!getDerived().AlwaysRebuild() &&
8677 Cond.get() == S->getCond() &&
8678 Body.get() == S->getBody())
8679 return S;
8680
8681 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8682 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8683 S->getRParenLoc());
8684}
8685
8686template<typename Derived>
8687StmtResult
8688TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8689 if (getSema().getLangOpts().getOpenMPVersion())
8690 getSema().OpenMP().startOpenMPLoop();
8691
8692 // Transform the initialization statement
8693 StmtResult Init = getDerived().TransformStmt(S->getInit());
8694 if (Init.isInvalid())
8695 return StmtError();
8696
8697 // In OpenMP loop region loop control variable must be captured and be
8698 // private. Perform analysis of first part (if any).
8699 if (getSema().getLangOpts().getOpenMPVersion() && Init.isUsable())
8700 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8701 Init.get());
8702
8703 // Transform the condition
8704 Sema::ConditionResult Cond = getDerived().TransformCondition(
8705 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8706 Sema::ConditionKind::Boolean);
8707 if (Cond.isInvalid())
8708 return StmtError();
8709
8710 // Transform the increment
8711 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8712 if (Inc.isInvalid())
8713 return StmtError();
8714
8715 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8716 if (S->getInc() && !FullInc.get())
8717 return StmtError();
8718
8719 // OpenACC Restricts a for-loop inside of certain construct/clause
8720 // combinations, so diagnose that here in OpenACC mode.
8721 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8722 SemaRef.OpenACC().ActOnForStmtBegin(
8723 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8724 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8725
8726 // Transform the body
8727 StmtResult Body = getDerived().TransformStmt(S->getBody());
8728 if (Body.isInvalid())
8729 return StmtError();
8730
8731 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8732
8733 if (!getDerived().AlwaysRebuild() &&
8734 Init.get() == S->getInit() &&
8735 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8736 Inc.get() == S->getInc() &&
8737 Body.get() == S->getBody())
8738 return S;
8739
8740 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8741 Init.get(), Cond, FullInc,
8742 S->getRParenLoc(), Body.get());
8743}
8744
8745template<typename Derived>
8746StmtResult
8747TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8748 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8749 S->getLabel());
8750 if (!LD)
8751 return StmtError();
8752
8753 // Goto statements must always be rebuilt, to resolve the label.
8754 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8755 cast<LabelDecl>(Val: LD));
8756}
8757
8758template<typename Derived>
8759StmtResult
8760TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8761 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8762 if (Target.isInvalid())
8763 return StmtError();
8764 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8765
8766 if (!getDerived().AlwaysRebuild() &&
8767 Target.get() == S->getTarget())
8768 return S;
8769
8770 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8771 Target.get());
8772}
8773
8774template<typename Derived>
8775StmtResult
8776TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8777 if (!S->hasLabelTarget())
8778 return S;
8779
8780 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8781 S->getLabelDecl());
8782 if (!LD)
8783 return StmtError();
8784
8785 return new (SemaRef.Context)
8786 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8787}
8788
8789template<typename Derived>
8790StmtResult
8791TreeTransform<Derived>::TransformBreakStmt(BreakStmt *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 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8802}
8803
8804template <typename Derived>
8805StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8806 StmtResult Result = getDerived().TransformStmt(S->getBody());
8807 if (!Result.isUsable())
8808 return StmtError();
8809 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8810}
8811
8812template<typename Derived>
8813StmtResult
8814TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8815 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8816 /*NotCopyInit*/false);
8817 if (Result.isInvalid())
8818 return StmtError();
8819
8820 // FIXME: We always rebuild the return statement because there is no way
8821 // to tell whether the return type of the function has changed.
8822 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8823}
8824
8825template<typename Derived>
8826StmtResult
8827TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8828 bool DeclChanged = false;
8829 SmallVector<Decl *, 4> Decls;
8830 LambdaScopeInfo *LSI = getSema().getCurLambda();
8831 for (auto *D : S->decls()) {
8832 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8833 if (!Transformed)
8834 return StmtError();
8835
8836 if (Transformed != D)
8837 DeclChanged = true;
8838
8839 if (LSI) {
8840 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8841 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8842 LSI->ContainsUnexpandedParameterPack |=
8843 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8844 } else {
8845 LSI->ContainsUnexpandedParameterPack |=
8846 getSema()
8847 .getASTContext()
8848 .getTypeDeclType(TD)
8849 ->containsUnexpandedParameterPack();
8850 }
8851 }
8852 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8853 LSI->ContainsUnexpandedParameterPack |=
8854 VD->getType()->containsUnexpandedParameterPack();
8855 }
8856
8857 Decls.push_back(Elt: Transformed);
8858 }
8859
8860 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8861 return S;
8862
8863 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8864}
8865
8866template<typename Derived>
8867StmtResult
8868TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8869
8870 SmallVector<Expr*, 8> Constraints;
8871 SmallVector<Expr*, 8> Exprs;
8872 SmallVector<IdentifierInfo *, 4> Names;
8873
8874 SmallVector<Expr*, 8> Clobbers;
8875
8876 bool ExprsChanged = false;
8877
8878 auto RebuildString = [&](Expr *E) {
8879 ExprResult Result = getDerived().TransformExpr(E);
8880 if (!Result.isUsable())
8881 return Result;
8882 if (Result.get() != E) {
8883 ExprsChanged = true;
8884 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8885 }
8886 return Result;
8887 };
8888
8889 // Go through the outputs.
8890 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8891 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8892
8893 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8894 if (Result.isInvalid())
8895 return StmtError();
8896
8897 Constraints.push_back(Elt: Result.get());
8898
8899 // Transform the output expr.
8900 Expr *OutputExpr = S->getOutputExpr(i: I);
8901 Result = getDerived().TransformExpr(OutputExpr);
8902 if (Result.isInvalid())
8903 return StmtError();
8904
8905 ExprsChanged |= Result.get() != OutputExpr;
8906
8907 Exprs.push_back(Elt: Result.get());
8908 }
8909
8910 // Go through the inputs.
8911 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8912 Names.push_back(Elt: S->getInputIdentifier(i: I));
8913
8914 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8915 if (Result.isInvalid())
8916 return StmtError();
8917
8918 Constraints.push_back(Elt: Result.get());
8919
8920 // Transform the input expr.
8921 Expr *InputExpr = S->getInputExpr(i: I);
8922 Result = getDerived().TransformExpr(InputExpr);
8923 if (Result.isInvalid())
8924 return StmtError();
8925
8926 ExprsChanged |= Result.get() != InputExpr;
8927
8928 Exprs.push_back(Elt: Result.get());
8929 }
8930
8931 // Go through the Labels.
8932 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8933 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8934
8935 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8936 if (Result.isInvalid())
8937 return StmtError();
8938 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8939 Exprs.push_back(Elt: Result.get());
8940 }
8941
8942 // Go through the clobbers.
8943 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8944 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8945 if (Result.isInvalid())
8946 return StmtError();
8947 Clobbers.push_back(Elt: Result.get());
8948 }
8949
8950 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8951 if (AsmString.isInvalid())
8952 return StmtError();
8953
8954 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8955 return S;
8956
8957 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8958 S->isVolatile(), S->getNumOutputs(),
8959 S->getNumInputs(), Names.data(),
8960 Constraints, Exprs, AsmString.get(),
8961 Clobbers, S->getNumLabels(),
8962 S->getRParenLoc());
8963}
8964
8965template<typename Derived>
8966StmtResult
8967TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8968 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8969
8970 bool HadError = false, HadChange = false;
8971
8972 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8973 SmallVector<Expr*, 8> TransformedExprs;
8974 TransformedExprs.reserve(N: SrcExprs.size());
8975 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8976 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8977 if (!Result.isUsable()) {
8978 HadError = true;
8979 } else {
8980 HadChange |= (Result.get() != SrcExprs[i]);
8981 TransformedExprs.push_back(Elt: Result.get());
8982 }
8983 }
8984
8985 if (HadError) return StmtError();
8986 if (!HadChange && !getDerived().AlwaysRebuild())
8987 return Owned(S);
8988
8989 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8990 AsmToks, S->getAsmString(),
8991 S->getNumOutputs(), S->getNumInputs(),
8992 S->getAllConstraints(), S->getClobbers(),
8993 TransformedExprs, S->getEndLoc());
8994}
8995
8996// C++ Coroutines
8997template<typename Derived>
8998StmtResult
8999TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
9000 auto *ScopeInfo = SemaRef.getCurFunction();
9001 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
9002 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
9003 ScopeInfo->NeedsCoroutineSuspends &&
9004 ScopeInfo->CoroutineSuspends.first == nullptr &&
9005 ScopeInfo->CoroutineSuspends.second == nullptr &&
9006 "expected clean scope info");
9007
9008 // Set that we have (possibly-invalid) suspend points before we do anything
9009 // that may fail.
9010 ScopeInfo->setNeedsCoroutineSuspends(false);
9011
9012 // We re-build the coroutine promise object (and the coroutine parameters its
9013 // type and constructor depend on) based on the types used in our current
9014 // function. We must do so, and set it on the current FunctionScopeInfo,
9015 // before attempting to transform the other parts of the coroutine body
9016 // statement, such as the implicit suspend statements (because those
9017 // statements reference the FunctionScopeInfo::CoroutinePromise).
9018 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
9019 return StmtError();
9020 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
9021 if (!Promise)
9022 return StmtError();
9023 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
9024 ScopeInfo->CoroutinePromise = Promise;
9025
9026 // Transform the implicit coroutine statements constructed using dependent
9027 // types during the previous parse: initial and final suspensions, the return
9028 // object, and others. We also transform the coroutine function's body.
9029 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
9030 if (InitSuspend.isInvalid())
9031 return StmtError();
9032 StmtResult FinalSuspend =
9033 getDerived().TransformStmt(S->getFinalSuspendStmt());
9034 if (FinalSuspend.isInvalid() ||
9035 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
9036 return StmtError();
9037 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
9038 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
9039
9040 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
9041 if (BodyRes.isInvalid())
9042 return StmtError();
9043
9044 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
9045 if (Builder.isInvalid())
9046 return StmtError();
9047
9048 Expr *ReturnObject = S->getReturnValueInit();
9049 assert(ReturnObject && "the return object is expected to be valid");
9050 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
9051 /*NoCopyInit*/ false);
9052 if (Res.isInvalid())
9053 return StmtError();
9054 Builder.ReturnValue = Res.get();
9055
9056 // If during the previous parse the coroutine still had a dependent promise
9057 // statement, we may need to build some implicit coroutine statements
9058 // (such as exception and fallthrough handlers) for the first time.
9059 if (S->hasDependentPromiseType()) {
9060 // We can only build these statements, however, if the current promise type
9061 // is not dependent.
9062 if (!Promise->getType()->isDependentType()) {
9063 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
9064 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
9065 "these nodes should not have been built yet");
9066 if (!Builder.buildDependentStatements())
9067 return StmtError();
9068 }
9069 } else {
9070 if (auto *OnFallthrough = S->getFallthroughHandler()) {
9071 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
9072 if (Res.isInvalid())
9073 return StmtError();
9074 Builder.OnFallthrough = Res.get();
9075 }
9076
9077 if (auto *OnException = S->getExceptionHandler()) {
9078 StmtResult Res = getDerived().TransformStmt(OnException);
9079 if (Res.isInvalid())
9080 return StmtError();
9081 Builder.OnException = Res.get();
9082 }
9083
9084 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
9085 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
9086 if (Res.isInvalid())
9087 return StmtError();
9088 Builder.ReturnStmtOnAllocFailure = Res.get();
9089 }
9090
9091 // Transform any additional statements we may have already built
9092 assert(S->getAllocate() && S->getDeallocate() &&
9093 "allocation and deallocation calls must already be built");
9094 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
9095 if (AllocRes.isInvalid())
9096 return StmtError();
9097 Builder.Allocate = AllocRes.get();
9098
9099 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
9100 if (DeallocRes.isInvalid())
9101 return StmtError();
9102 Builder.Deallocate = DeallocRes.get();
9103
9104 if (auto *ResultDecl = S->getResultDecl()) {
9105 StmtResult Res = getDerived().TransformStmt(ResultDecl);
9106 if (Res.isInvalid())
9107 return StmtError();
9108 Builder.ResultDecl = Res.get();
9109 }
9110
9111 if (auto *ReturnStmt = S->getReturnStmt()) {
9112 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
9113 if (Res.isInvalid())
9114 return StmtError();
9115 Builder.ReturnStmt = Res.get();
9116 }
9117 }
9118
9119 return getDerived().RebuildCoroutineBodyStmt(Builder);
9120}
9121
9122template<typename Derived>
9123StmtResult
9124TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
9125 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
9126 /*NotCopyInit*/false);
9127 if (Result.isInvalid())
9128 return StmtError();
9129
9130 // Always rebuild; we don't know if this needs to be injected into a new
9131 // context or if the promise type has changed.
9132 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
9133 S->isImplicit());
9134}
9135
9136template <typename Derived>
9137ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
9138 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
9139 /*NotCopyInit*/ false);
9140 if (Operand.isInvalid())
9141 return ExprError();
9142
9143 // Rebuild the common-expr from the operand rather than transforming it
9144 // separately.
9145
9146 // FIXME: getCurScope() should not be used during template instantiation.
9147 // We should pick up the set of unqualified lookup results for operator
9148 // co_await during the initial parse.
9149 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
9150 getSema().getCurScope(), E->getKeywordLoc());
9151
9152 // Always rebuild; we don't know if this needs to be injected into a new
9153 // context or if the promise type has changed.
9154 return getDerived().RebuildCoawaitExpr(
9155 E->getKeywordLoc(), Operand.get(),
9156 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
9157}
9158
9159template <typename Derived>
9160ExprResult
9161TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9162 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9163 /*NotCopyInit*/ false);
9164 if (OperandResult.isInvalid())
9165 return ExprError();
9166
9167 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9168 E->getOperatorCoawaitLookup());
9169
9170 if (LookupResult.isInvalid())
9171 return ExprError();
9172
9173 // Always rebuild; we don't know if this needs to be injected into a new
9174 // context or if the promise type has changed.
9175 return getDerived().RebuildDependentCoawaitExpr(
9176 E->getKeywordLoc(), OperandResult.get(),
9177 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9178}
9179
9180template<typename Derived>
9181ExprResult
9182TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9183 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9184 /*NotCopyInit*/false);
9185 if (Result.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().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9191}
9192
9193// Objective-C Statements.
9194
9195template<typename Derived>
9196StmtResult
9197TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9198 // Transform the body of the @try.
9199 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9200 if (TryBody.isInvalid())
9201 return StmtError();
9202
9203 // Transform the @catch statements (if present).
9204 bool AnyCatchChanged = false;
9205 SmallVector<Stmt*, 8> CatchStmts;
9206 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9207 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9208 if (Catch.isInvalid())
9209 return StmtError();
9210 if (Catch.get() != S->getCatchStmt(I))
9211 AnyCatchChanged = true;
9212 CatchStmts.push_back(Elt: Catch.get());
9213 }
9214
9215 // Transform the @finally statement (if present).
9216 StmtResult Finally;
9217 if (S->getFinallyStmt()) {
9218 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9219 if (Finally.isInvalid())
9220 return StmtError();
9221 }
9222
9223 // If nothing changed, just retain this statement.
9224 if (!getDerived().AlwaysRebuild() &&
9225 TryBody.get() == S->getTryBody() &&
9226 !AnyCatchChanged &&
9227 Finally.get() == S->getFinallyStmt())
9228 return S;
9229
9230 // Build a new statement.
9231 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9232 CatchStmts, Finally.get());
9233}
9234
9235template<typename Derived>
9236StmtResult
9237TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9238 // Transform the @catch parameter, if there is one.
9239 VarDecl *Var = nullptr;
9240 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9241 TypeSourceInfo *TSInfo = nullptr;
9242 if (FromVar->getTypeSourceInfo()) {
9243 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9244 if (!TSInfo)
9245 return StmtError();
9246 }
9247
9248 QualType T;
9249 if (TSInfo)
9250 T = TSInfo->getType();
9251 else {
9252 T = getDerived().TransformType(FromVar->getType());
9253 if (T.isNull())
9254 return StmtError();
9255 }
9256
9257 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9258 if (!Var)
9259 return StmtError();
9260 }
9261
9262 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9263 if (Body.isInvalid())
9264 return StmtError();
9265
9266 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9267 S->getRParenLoc(),
9268 Var, Body.get());
9269}
9270
9271template<typename Derived>
9272StmtResult
9273TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9274 // Transform the body.
9275 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9276 if (Body.isInvalid())
9277 return StmtError();
9278
9279 // If nothing changed, just retain this statement.
9280 if (!getDerived().AlwaysRebuild() &&
9281 Body.get() == S->getFinallyBody())
9282 return S;
9283
9284 // Build a new statement.
9285 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9286 Body.get());
9287}
9288
9289template<typename Derived>
9290StmtResult
9291TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9292 ExprResult Operand;
9293 if (S->getThrowExpr()) {
9294 Operand = getDerived().TransformExpr(S->getThrowExpr());
9295 if (Operand.isInvalid())
9296 return StmtError();
9297 }
9298
9299 if (!getDerived().AlwaysRebuild() &&
9300 Operand.get() == S->getThrowExpr())
9301 return S;
9302
9303 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9304}
9305
9306template<typename Derived>
9307StmtResult
9308TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9309 ObjCAtSynchronizedStmt *S) {
9310 // Transform the object we are locking.
9311 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9312 if (Object.isInvalid())
9313 return StmtError();
9314 Object =
9315 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9316 Object.get());
9317 if (Object.isInvalid())
9318 return StmtError();
9319
9320 // Transform the body.
9321 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9322 if (Body.isInvalid())
9323 return StmtError();
9324
9325 // If nothing change, just retain the current statement.
9326 if (!getDerived().AlwaysRebuild() &&
9327 Object.get() == S->getSynchExpr() &&
9328 Body.get() == S->getSynchBody())
9329 return S;
9330
9331 // Build a new statement.
9332 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9333 Object.get(), Body.get());
9334}
9335
9336template<typename Derived>
9337StmtResult
9338TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9339 ObjCAutoreleasePoolStmt *S) {
9340 // Transform the body.
9341 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9342 if (Body.isInvalid())
9343 return StmtError();
9344
9345 // If nothing changed, just retain this statement.
9346 if (!getDerived().AlwaysRebuild() &&
9347 Body.get() == S->getSubStmt())
9348 return S;
9349
9350 // Build a new statement.
9351 return getDerived().RebuildObjCAutoreleasePoolStmt(
9352 S->getAtLoc(), Body.get());
9353}
9354
9355template<typename Derived>
9356StmtResult
9357TreeTransform<Derived>::TransformObjCForCollectionStmt(
9358 ObjCForCollectionStmt *S) {
9359 // Transform the element statement.
9360 StmtResult Element = getDerived().TransformStmt(
9361 S->getElement(), StmtDiscardKind::NotDiscarded);
9362 if (Element.isInvalid())
9363 return StmtError();
9364
9365 // Transform the collection expression.
9366 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9367 if (Collection.isInvalid())
9368 return StmtError();
9369
9370 // Transform the body.
9371 StmtResult Body = getDerived().TransformStmt(S->getBody());
9372 if (Body.isInvalid())
9373 return StmtError();
9374
9375 // If nothing changed, just retain this statement.
9376 if (!getDerived().AlwaysRebuild() &&
9377 Element.get() == S->getElement() &&
9378 Collection.get() == S->getCollection() &&
9379 Body.get() == S->getBody())
9380 return S;
9381
9382 // Build a new statement.
9383 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9384 Element.get(),
9385 Collection.get(),
9386 S->getRParenLoc(),
9387 Body.get());
9388}
9389
9390template <typename Derived>
9391StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9392 // Transform the exception declaration, if any.
9393 VarDecl *Var = nullptr;
9394 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9395 TypeSourceInfo *T =
9396 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9397 if (!T)
9398 return StmtError();
9399
9400 Var = getDerived().RebuildExceptionDecl(
9401 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9402 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9403 if (!Var || Var->isInvalidDecl())
9404 return StmtError();
9405 }
9406
9407 // Transform the actual exception handler.
9408 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9409 if (Handler.isInvalid())
9410 return StmtError();
9411
9412 if (!getDerived().AlwaysRebuild() && !Var &&
9413 Handler.get() == S->getHandlerBlock())
9414 return S;
9415
9416 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9417}
9418
9419template <typename Derived>
9420StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9421 // Transform the try block itself.
9422 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9423 if (TryBlock.isInvalid())
9424 return StmtError();
9425
9426 // Transform the handlers.
9427 bool HandlerChanged = false;
9428 SmallVector<Stmt *, 8> Handlers;
9429 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9430 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9431 if (Handler.isInvalid())
9432 return StmtError();
9433
9434 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9435 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9436 }
9437
9438 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9439
9440 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9441 !HandlerChanged)
9442 return S;
9443
9444 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9445 Handlers);
9446}
9447
9448template<typename Derived>
9449StmtResult
9450TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9451 EnterExpressionEvaluationContext ForRangeInitContext(
9452 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9453 /*LambdaContextDecl=*/nullptr,
9454 Sema::ExpressionEvaluationContextRecord::EK_Other,
9455 getSema().getLangOpts().CPlusPlus23);
9456
9457 // P2718R0 - Lifetime extension in range-based for loops.
9458 if (getSema().getLangOpts().CPlusPlus23) {
9459 auto &LastRecord = getSema().currentEvaluationContext();
9460 LastRecord.InLifetimeExtendingContext = true;
9461 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9462 }
9463 StmtResult Init =
9464 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9465 if (Init.isInvalid())
9466 return StmtError();
9467
9468 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9469 if (Range.isInvalid())
9470 return StmtError();
9471
9472 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9473 assert(getSema().getLangOpts().CPlusPlus23 ||
9474 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9475 auto ForRangeLifetimeExtendTemps =
9476 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9477
9478 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9479 if (Begin.isInvalid())
9480 return StmtError();
9481 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9482 if (End.isInvalid())
9483 return StmtError();
9484
9485 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9486 if (Cond.isInvalid())
9487 return StmtError();
9488 if (Cond.get())
9489 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9490 if (Cond.isInvalid())
9491 return StmtError();
9492 if (Cond.get())
9493 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9494
9495 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9496 if (Inc.isInvalid())
9497 return StmtError();
9498 if (Inc.get())
9499 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9500
9501 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9502 if (LoopVar.isInvalid())
9503 return StmtError();
9504
9505 StmtResult NewStmt = S;
9506 if (getDerived().AlwaysRebuild() ||
9507 Init.get() != S->getInit() ||
9508 Range.get() != S->getRangeStmt() ||
9509 Begin.get() != S->getBeginStmt() ||
9510 End.get() != S->getEndStmt() ||
9511 Cond.get() != S->getCond() ||
9512 Inc.get() != S->getInc() ||
9513 LoopVar.get() != S->getLoopVarStmt()) {
9514 NewStmt = getDerived().RebuildCXXForRangeStmt(
9515 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9516 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9517 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9518 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9519 // Might not have attached any initializer to the loop variable.
9520 getSema().ActOnInitializerError(
9521 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9522 return StmtError();
9523 }
9524 }
9525
9526 // OpenACC Restricts a while-loop inside of certain construct/clause
9527 // combinations, so diagnose that here in OpenACC mode.
9528 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9529 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9530
9531 StmtResult Body = getDerived().TransformStmt(S->getBody());
9532 if (Body.isInvalid())
9533 return StmtError();
9534
9535 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9536
9537 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9538 // it now so we have a new statement to attach the body to.
9539 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9540 NewStmt = getDerived().RebuildCXXForRangeStmt(
9541 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9542 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9543 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9544 if (NewStmt.isInvalid())
9545 return StmtError();
9546 }
9547
9548 if (NewStmt.get() == S)
9549 return S;
9550
9551 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9552}
9553
9554template <typename Derived>
9555StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
9556 CXXExpansionStmtPattern *S) {
9557 assert(SemaRef.CurContext->isExpansionStmt());
9558
9559 Decl *ESD =
9560 getDerived().TransformDecl(S->getDecl()->getLocation(), S->getDecl());
9561 if (!ESD || ESD->isInvalidDecl())
9562 return StmtError();
9563 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9564
9565 // This is required because some parts of an expansion statement (e.g. the
9566 // init-statement) are not in a dependent context and must thus be transformed
9567 // in the parent context.
9568 auto TransformStmtInParentContext = [&](Stmt *SubStmt) -> StmtResult {
9569 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9570 /*NewThis=*/false);
9571 return getDerived().TransformStmt(SubStmt);
9572 };
9573
9574 Stmt *Init = S->getInit();
9575 if (Init) {
9576 StmtResult SR = TransformStmtInParentContext(Init);
9577 if (SR.isInvalid())
9578 return StmtError();
9579 Init = SR.get();
9580 }
9581
9582 // Collect lifetime-extended temporaries in case this ends up being a
9583 // destructuring or iterating expansion statement.
9584 //
9585 // CWG 3140: Additionally, for iterating expansions statements, we need to
9586 // apply lifetime extension to the initializer of the range.
9587 ExprResult ExpansionInitializer;
9588 StmtResult Range;
9589 SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
9590 if (S->isDependent() || S->isIterating()) {
9591 EnterExpressionEvaluationContext ExprEvalCtx(
9592 SemaRef, SemaRef.currentEvaluationContext().Context);
9593 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9594 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9595
9596 if (S->isDependent()) {
9597 // The expansion initializer should not be in the context of the expansion
9598 // statement because it isn't instantiated when the expansion statement is
9599 // expanded.
9600 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9601 /*NewThis=*/false);
9602 ExpansionInitializer =
9603 getDerived().TransformExpr(S->getExpansionInitializer());
9604 if (ExpansionInitializer.isInvalid())
9605 return StmtError();
9606 } else if (S->isIterating()) {
9607 Range = TransformStmtInParentContext(S->getRangeVarStmt());
9608 if (Range.isInvalid())
9609 return StmtError();
9610 }
9611
9612 ExpansionInitializer =
9613 SemaRef.MaybeCreateExprWithCleanups(SubExpr: ExpansionInitializer);
9614
9615 LifetimeExtendTemps =
9616 SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps;
9617 }
9618
9619 CXXExpansionStmtPattern *NewPattern = nullptr;
9620 if (S->isEnumerating()) {
9621 StmtResult ExpansionVar =
9622 getDerived().TransformStmt(S->getExpansionVarStmt());
9623 if (ExpansionVar.isInvalid())
9624 return StmtError();
9625
9626 NewPattern = CXXExpansionStmtPattern::CreateEnumerating(
9627 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9628 LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(), RParenLoc: S->getRParenLoc());
9629 } else if (S->isIterating()) {
9630 StmtResult Begin = TransformStmtInParentContext(S->getBeginVarStmt());
9631 StmtResult Iter = TransformStmtInParentContext(S->getIterVarStmt());
9632 if (Begin.isInvalid() || Iter.isInvalid())
9633 return StmtError();
9634
9635 // The expansion variable is part of the pattern only and never ends
9636 // up in the instantiations, so keep it in the expansion statement's
9637 // DeclContext.
9638 StmtResult ExpansionVar =
9639 getDerived().TransformStmt(S->getExpansionVarStmt());
9640 if (ExpansionVar.isInvalid())
9641 return StmtError();
9642
9643 NewPattern = CXXExpansionStmtPattern::CreateIterating(
9644 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9645 Range: Range.getAs<DeclStmt>(), Begin: Begin.getAs<DeclStmt>(),
9646 Iter: Iter.getAs<DeclStmt>(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9647 RParenLoc: S->getRParenLoc());
9648
9649 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9650 RangeVar: NewPattern->getRangeVar(), Temporaries: LifetimeExtendTemps);
9651 } else if (S->isDependent()) {
9652 StmtResult ExpansionVar =
9653 getDerived().TransformStmt(S->getExpansionVarStmt());
9654 if (ExpansionVar.isInvalid())
9655 return StmtError();
9656
9657 StmtResult Res = SemaRef.BuildNonEnumeratingCXXExpansionStmtPattern(
9658 ESD: NewESD, Init, ExpansionVarStmt: ExpansionVar.getAs<DeclStmt>(),
9659 ExpansionInitializer: ExpansionInitializer.get(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9660 RParenLoc: S->getRParenLoc(), LifetimeExtendTemps);
9661
9662 if (Res.isInvalid())
9663 return StmtError();
9664
9665 NewPattern = cast<CXXExpansionStmtPattern>(Val: Res.get());
9666 } else {
9667 // The only time we instantiate an expansion statement is if its expansion
9668 // size is dependent (otherwise, we only instantiate the expansions and
9669 // leave the underlying CXXExpansionStmtPattern as-is). Since destructuring
9670 // expansion statements never have a dependent size, we should never get
9671 // here.
9672 llvm_unreachable("destructuring pattern should never be instantiated");
9673 }
9674
9675 StmtResult Body = getDerived().TransformStmt(S->getBody());
9676 if (Body.isInvalid())
9677 return StmtError();
9678
9679 return SemaRef.FinishCXXExpansionStmt(Expansion: NewPattern, Body: Body.get());
9680}
9681
9682template <typename Derived>
9683StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
9684 CXXExpansionStmtInstantiation *S) {
9685 bool SubStmtChanged = false;
9686 auto TransformStmts = [&](SmallVectorImpl<Stmt *> &NewStmts,
9687 ArrayRef<Stmt *> OldStmts) {
9688 for (Stmt *OldDS : OldStmts) {
9689 StmtResult NewDS = getDerived().TransformStmt(OldDS);
9690 if (NewDS.isInvalid())
9691 return true;
9692
9693 SubStmtChanged |= NewDS.get() != OldDS;
9694 NewStmts.push_back(Elt: NewDS.get());
9695 }
9696
9697 return false;
9698 };
9699
9700 Decl *ESD =
9701 getDerived().TransformDecl(S->getParent()->getLocation(), S->getParent());
9702 if (!ESD || ESD->isInvalidDecl())
9703 return StmtError();
9704 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9705
9706 SmallVector<Stmt *> PreambleStmts;
9707 SmallVector<Stmt *> Instantiations;
9708
9709 // Apply lifetime extension to the preamble statements if this was a
9710 // destructuring expansion statement.
9711 {
9712 EnterExpressionEvaluationContext ExprEvalCtx(
9713 SemaRef, SemaRef.currentEvaluationContext().Context);
9714 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9715 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9716 if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
9717 return StmtError();
9718
9719 if (S->shouldApplyLifetimeExtensionToPreamble()) {
9720 auto *VD =
9721 cast<VarDecl>(Val: cast<DeclStmt>(Val: PreambleStmts.front())->getSingleDecl());
9722 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9723 RangeVar: VD, Temporaries: SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps);
9724 }
9725 }
9726
9727 if (TransformStmts(Instantiations, S->getInstantiations()))
9728 return StmtError();
9729
9730 if (!getDerived().AlwaysRebuild() && !SubStmtChanged)
9731 return S;
9732
9733 return CXXExpansionStmtInstantiation::Create(
9734 C&: SemaRef.Context, Parent: NewESD, Instantiations, PreambleStmts,
9735 ShouldApplyLifetimeExtensionToPreamble: S->shouldApplyLifetimeExtensionToPreamble());
9736}
9737
9738template <typename Derived>
9739ExprResult TreeTransform<Derived>::TransformCXXExpansionSelectExpr(
9740 CXXExpansionSelectExpr *E) {
9741 ExprResult Range = getDerived().TransformExpr(E->getRangeExpr());
9742 ExprResult Idx = getDerived().TransformExpr(E->getIndexExpr());
9743 if (Range.isInvalid() || Idx.isInvalid())
9744 return ExprError();
9745
9746 if (!getDerived().AlwaysRebuild() && Range.get() == E->getRangeExpr() &&
9747 Idx.get() == E->getIndexExpr())
9748 return E;
9749
9750 return SemaRef.BuildCXXExpansionSelectExpr(Range: Range.getAs<InitListExpr>(),
9751 Idx: Idx.get());
9752}
9753
9754template<typename Derived>
9755StmtResult
9756TreeTransform<Derived>::TransformMSDependentExistsStmt(
9757 MSDependentExistsStmt *S) {
9758 // Transform the nested-name-specifier, if any.
9759 NestedNameSpecifierLoc QualifierLoc;
9760 if (S->getQualifierLoc()) {
9761 QualifierLoc
9762 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9763 if (!QualifierLoc)
9764 return StmtError();
9765 }
9766
9767 // Transform the declaration name.
9768 DeclarationNameInfo NameInfo = S->getNameInfo();
9769 if (NameInfo.getName()) {
9770 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9771 if (!NameInfo.getName())
9772 return StmtError();
9773 }
9774
9775 // Check whether anything changed.
9776 if (!getDerived().AlwaysRebuild() &&
9777 QualifierLoc == S->getQualifierLoc() &&
9778 NameInfo.getName() == S->getNameInfo().getName())
9779 return S;
9780
9781 // Determine whether this name exists, if we can.
9782 CXXScopeSpec SS;
9783 SS.Adopt(Other: QualifierLoc);
9784 bool Dependent = false;
9785 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9786 case IfExistsResult::Exists:
9787 if (S->isIfExists())
9788 break;
9789
9790 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9791
9792 case IfExistsResult::DoesNotExist:
9793 if (S->isIfNotExists())
9794 break;
9795
9796 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9797
9798 case IfExistsResult::Dependent:
9799 Dependent = true;
9800 break;
9801
9802 case IfExistsResult::Error:
9803 return StmtError();
9804 }
9805
9806 // We need to continue with the instantiation, so do so now.
9807 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9808 if (SubStmt.isInvalid())
9809 return StmtError();
9810
9811 // If we have resolved the name, just transform to the substatement.
9812 if (!Dependent)
9813 return SubStmt;
9814
9815 // The name is still dependent, so build a dependent expression again.
9816 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9817 S->isIfExists(),
9818 QualifierLoc,
9819 NameInfo,
9820 SubStmt.get());
9821}
9822
9823template<typename Derived>
9824ExprResult
9825TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9826 NestedNameSpecifierLoc QualifierLoc;
9827 if (E->getQualifierLoc()) {
9828 QualifierLoc
9829 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9830 if (!QualifierLoc)
9831 return ExprError();
9832 }
9833
9834 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9835 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9836 if (!PD)
9837 return ExprError();
9838
9839 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9840 if (Base.isInvalid())
9841 return ExprError();
9842
9843 return new (SemaRef.getASTContext())
9844 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9845 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9846 QualifierLoc, E->getMemberLoc());
9847}
9848
9849template <typename Derived>
9850ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9851 MSPropertySubscriptExpr *E) {
9852 auto BaseRes = getDerived().TransformExpr(E->getBase());
9853 if (BaseRes.isInvalid())
9854 return ExprError();
9855 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9856 if (IdxRes.isInvalid())
9857 return ExprError();
9858
9859 if (!getDerived().AlwaysRebuild() &&
9860 BaseRes.get() == E->getBase() &&
9861 IdxRes.get() == E->getIdx())
9862 return E;
9863
9864 return getDerived().RebuildArraySubscriptExpr(
9865 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9866}
9867
9868template <typename Derived>
9869StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9870 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9871 if (TryBlock.isInvalid())
9872 return StmtError();
9873
9874 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9875 if (Handler.isInvalid())
9876 return StmtError();
9877
9878 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9879 Handler.get() == S->getHandler())
9880 return S;
9881
9882 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9883 TryBlock.get(), Handler.get());
9884}
9885
9886template <typename Derived>
9887StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9888 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9889 if (Block.isInvalid())
9890 return StmtError();
9891
9892 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9893}
9894
9895template <typename Derived>
9896StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9897 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9898 if (FilterExpr.isInvalid())
9899 return StmtError();
9900
9901 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9902 if (Block.isInvalid())
9903 return StmtError();
9904
9905 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9906 Block.get());
9907}
9908
9909template <typename Derived>
9910StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9911 if (isa<SEHFinallyStmt>(Val: Handler))
9912 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9913 else
9914 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9915}
9916
9917template<typename Derived>
9918StmtResult
9919TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9920 return S;
9921}
9922
9923//===----------------------------------------------------------------------===//
9924// OpenMP directive transformation
9925//===----------------------------------------------------------------------===//
9926
9927template <typename Derived>
9928StmtResult
9929TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9930 // OMPCanonicalLoops are eliminated during transformation, since they will be
9931 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9932 // after transformation.
9933 return getDerived().TransformStmt(L->getLoopStmt());
9934}
9935
9936template <typename Derived>
9937StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9938 OMPExecutableDirective *D) {
9939
9940 // Transform the clauses
9941 llvm::SmallVector<OMPClause *, 16> TClauses;
9942 ArrayRef<OMPClause *> Clauses = D->clauses();
9943 TClauses.reserve(N: Clauses.size());
9944 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9945 I != E; ++I) {
9946 if (*I) {
9947 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9948 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9949 getDerived().getSema().OpenMP().EndOpenMPClause();
9950 if (Clause)
9951 TClauses.push_back(Elt: Clause);
9952 } else {
9953 TClauses.push_back(Elt: nullptr);
9954 }
9955 }
9956 StmtResult AssociatedStmt;
9957 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9958 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9959 D->getDirectiveKind(),
9960 /*CurScope=*/nullptr);
9961 StmtResult Body;
9962 {
9963 Sema::CompoundScopeRAII CompoundScope(getSema());
9964 Stmt *CS;
9965 if (D->getDirectiveKind() == OMPD_atomic ||
9966 D->getDirectiveKind() == OMPD_critical ||
9967 D->getDirectiveKind() == OMPD_section ||
9968 D->getDirectiveKind() == OMPD_master)
9969 CS = D->getAssociatedStmt();
9970 else
9971 CS = D->getRawStmt();
9972 Body = getDerived().TransformStmt(CS);
9973 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9974 getSema().getLangOpts().OpenMPIRBuilder)
9975 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9976 }
9977 AssociatedStmt =
9978 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9979 if (AssociatedStmt.isInvalid()) {
9980 return StmtError();
9981 }
9982 }
9983 if (TClauses.size() != Clauses.size()) {
9984 return StmtError();
9985 }
9986
9987 // Transform directive name for 'omp critical' directive.
9988 DeclarationNameInfo DirName;
9989 if (D->getDirectiveKind() == OMPD_critical) {
9990 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9991 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9992 }
9993 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9994 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9995 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9996 } else if (D->getDirectiveKind() == OMPD_cancel) {
9997 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9998 }
9999
10000 return getDerived().RebuildOMPExecutableDirective(
10001 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
10002 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
10003}
10004
10005/// This is mostly the same as above, but allows 'informational' class
10006/// directives when rebuilding the stmt. It still takes an
10007/// OMPExecutableDirective-type argument because we're reusing that as the
10008/// superclass for the 'assume' directive at present, instead of defining a
10009/// mostly-identical OMPInformationalDirective parent class.
10010template <typename Derived>
10011StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
10012 OMPExecutableDirective *D) {
10013
10014 // Transform the clauses
10015 llvm::SmallVector<OMPClause *, 16> TClauses;
10016 ArrayRef<OMPClause *> Clauses = D->clauses();
10017 TClauses.reserve(N: Clauses.size());
10018 for (OMPClause *C : Clauses) {
10019 if (C) {
10020 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
10021 OMPClause *Clause = getDerived().TransformOMPClause(C);
10022 getDerived().getSema().OpenMP().EndOpenMPClause();
10023 if (Clause)
10024 TClauses.push_back(Elt: Clause);
10025 } else {
10026 TClauses.push_back(Elt: nullptr);
10027 }
10028 }
10029 StmtResult AssociatedStmt;
10030 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
10031 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
10032 D->getDirectiveKind(),
10033 /*CurScope=*/nullptr);
10034 StmtResult Body;
10035 {
10036 Sema::CompoundScopeRAII CompoundScope(getSema());
10037 assert(D->getDirectiveKind() == OMPD_assume &&
10038 "Unexpected informational directive");
10039 Stmt *CS = D->getAssociatedStmt();
10040 Body = getDerived().TransformStmt(CS);
10041 }
10042 AssociatedStmt =
10043 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
10044 if (AssociatedStmt.isInvalid())
10045 return StmtError();
10046 }
10047 if (TClauses.size() != Clauses.size())
10048 return StmtError();
10049
10050 DeclarationNameInfo DirName;
10051
10052 return getDerived().RebuildOMPInformationalDirective(
10053 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
10054 D->getBeginLoc(), D->getEndLoc());
10055}
10056
10057template <typename Derived>
10058StmtResult
10059TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
10060 // TODO: Fix This
10061 llvm::omp::Version OMPVersion =
10062 getDerived().getSema().getLangOpts().getOpenMPVersion();
10063 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
10064 << getOpenMPDirectiveName(D: D->getDirectiveKind(), V: OMPVersion);
10065 return StmtError();
10066}
10067
10068template <typename Derived>
10069StmtResult
10070TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
10071 DeclarationNameInfo DirName;
10072 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10073 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
10074 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10075 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10076 return Res;
10077}
10078
10079template <typename Derived>
10080StmtResult
10081TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
10082 DeclarationNameInfo DirName;
10083 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10084 OMPD_simd, DirName, nullptr, D->getBeginLoc());
10085 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10086 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10087 return Res;
10088}
10089
10090template <typename Derived>
10091StmtResult
10092TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
10093 DeclarationNameInfo DirName;
10094 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10095 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10096 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10097 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10098 return Res;
10099}
10100
10101template <typename Derived>
10102StmtResult
10103TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
10104 DeclarationNameInfo DirName;
10105 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10106 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10107 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10108 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10109 return Res;
10110}
10111
10112template <typename Derived>
10113StmtResult
10114TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
10115 DeclarationNameInfo DirName;
10116 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10117 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10118 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10119 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10120 return Res;
10121}
10122
10123template <typename Derived>
10124StmtResult
10125TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
10126 DeclarationNameInfo DirName;
10127 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10128 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10129 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10130 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10131 return Res;
10132}
10133
10134template <typename Derived>
10135StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
10136 OMPInterchangeDirective *D) {
10137 DeclarationNameInfo DirName;
10138 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10139 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10140 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10141 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10142 return Res;
10143}
10144
10145template <typename Derived>
10146StmtResult
10147TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
10148 DeclarationNameInfo DirName;
10149 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10150 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10151 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10152 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10153 return Res;
10154}
10155
10156template <typename Derived>
10157StmtResult
10158TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
10159 DeclarationNameInfo DirName;
10160 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10161 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10162 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10163 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10164 return Res;
10165}
10166
10167template <typename Derived>
10168StmtResult
10169TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
10170 DeclarationNameInfo DirName;
10171 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10172 OMPD_for, DirName, nullptr, D->getBeginLoc());
10173 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10174 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10175 return Res;
10176}
10177
10178template <typename Derived>
10179StmtResult
10180TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
10181 DeclarationNameInfo DirName;
10182 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10183 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
10184 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10185 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10186 return Res;
10187}
10188
10189template <typename Derived>
10190StmtResult
10191TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
10192 DeclarationNameInfo DirName;
10193 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10194 OMPD_sections, DirName, nullptr, D->getBeginLoc());
10195 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10196 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10197 return Res;
10198}
10199
10200template <typename Derived>
10201StmtResult
10202TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
10203 DeclarationNameInfo DirName;
10204 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10205 OMPD_section, DirName, nullptr, D->getBeginLoc());
10206 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10207 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10208 return Res;
10209}
10210
10211template <typename Derived>
10212StmtResult
10213TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
10214 DeclarationNameInfo DirName;
10215 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10216 OMPD_scope, DirName, nullptr, D->getBeginLoc());
10217 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10218 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10219 return Res;
10220}
10221
10222template <typename Derived>
10223StmtResult
10224TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
10225 DeclarationNameInfo DirName;
10226 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10227 OMPD_single, DirName, nullptr, D->getBeginLoc());
10228 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10229 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10230 return Res;
10231}
10232
10233template <typename Derived>
10234StmtResult
10235TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
10236 DeclarationNameInfo DirName;
10237 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10238 OMPD_master, DirName, nullptr, D->getBeginLoc());
10239 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10240 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10241 return Res;
10242}
10243
10244template <typename Derived>
10245StmtResult
10246TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
10247 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10248 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
10249 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10250 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10251 return Res;
10252}
10253
10254template <typename Derived>
10255StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
10256 OMPParallelForDirective *D) {
10257 DeclarationNameInfo DirName;
10258 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10259 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
10260 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10261 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10262 return Res;
10263}
10264
10265template <typename Derived>
10266StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
10267 OMPParallelForSimdDirective *D) {
10268 DeclarationNameInfo DirName;
10269 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10270 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10271 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10272 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10273 return Res;
10274}
10275
10276template <typename Derived>
10277StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
10278 OMPParallelMasterDirective *D) {
10279 DeclarationNameInfo DirName;
10280 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10281 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
10282 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10283 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10284 return Res;
10285}
10286
10287template <typename Derived>
10288StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
10289 OMPParallelMaskedDirective *D) {
10290 DeclarationNameInfo DirName;
10291 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10292 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
10293 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10294 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10295 return Res;
10296}
10297
10298template <typename Derived>
10299StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
10300 OMPParallelSectionsDirective *D) {
10301 DeclarationNameInfo DirName;
10302 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10303 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
10304 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10305 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10306 return Res;
10307}
10308
10309template <typename Derived>
10310StmtResult
10311TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
10312 DeclarationNameInfo DirName;
10313 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10314 OMPD_task, DirName, nullptr, D->getBeginLoc());
10315 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10316 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10317 return Res;
10318}
10319
10320template <typename Derived>
10321StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
10322 OMPTaskyieldDirective *D) {
10323 DeclarationNameInfo DirName;
10324 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10325 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
10326 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10327 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10328 return Res;
10329}
10330
10331template <typename Derived>
10332StmtResult
10333TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
10334 DeclarationNameInfo DirName;
10335 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10336 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
10337 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10338 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10339 return Res;
10340}
10341
10342template <typename Derived>
10343StmtResult
10344TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
10345 DeclarationNameInfo DirName;
10346 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10347 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
10348 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10349 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10350 return Res;
10351}
10352
10353template <typename Derived>
10354StmtResult
10355TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
10356 DeclarationNameInfo DirName;
10357 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10358 OMPD_assume, DirName, nullptr, D->getBeginLoc());
10359 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
10360 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10361 return Res;
10362}
10363
10364template <typename Derived>
10365StmtResult
10366TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10367 DeclarationNameInfo DirName;
10368 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10369 OMPD_error, DirName, nullptr, D->getBeginLoc());
10370 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10371 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10372 return Res;
10373}
10374
10375template <typename Derived>
10376StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10377 OMPTaskgroupDirective *D) {
10378 DeclarationNameInfo DirName;
10379 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10380 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10381 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10382 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10383 return Res;
10384}
10385
10386template <typename Derived>
10387StmtResult
10388TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10389 DeclarationNameInfo DirName;
10390 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10391 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10392 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10393 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10394 return Res;
10395}
10396
10397template <typename Derived>
10398StmtResult
10399TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10400 DeclarationNameInfo DirName;
10401 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10402 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10403 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10404 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10405 return Res;
10406}
10407
10408template <typename Derived>
10409StmtResult
10410TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10411 DeclarationNameInfo DirName;
10412 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10413 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10414 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10415 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10416 return Res;
10417}
10418
10419template <typename Derived>
10420StmtResult TreeTransform<Derived>::TransformOMPOrderedStandaloneDirective(
10421 OMPOrderedStandaloneDirective *D) {
10422 DeclarationNameInfo DirName;
10423 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10424 OMPD_ordered_standalone, DirName, nullptr, D->getBeginLoc());
10425 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10426 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10427 return Res;
10428}
10429
10430template <typename Derived>
10431StmtResult TreeTransform<Derived>::TransformOMPOrderedBlockAssocDirective(
10432 OMPOrderedBlockAssocDirective *D) {
10433 DeclarationNameInfo DirName;
10434 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10435 OMPD_ordered_blockassoc, DirName, nullptr, D->getBeginLoc());
10436 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10437 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10438 return Res;
10439}
10440
10441template <typename Derived>
10442StmtResult
10443TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10444 DeclarationNameInfo DirName;
10445 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10446 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10447 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10448 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10449 return Res;
10450}
10451
10452template <typename Derived>
10453StmtResult
10454TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10455 DeclarationNameInfo DirName;
10456 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10457 OMPD_target, DirName, nullptr, D->getBeginLoc());
10458 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10459 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10460 return Res;
10461}
10462
10463template <typename Derived>
10464StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10465 OMPTargetDataDirective *D) {
10466 DeclarationNameInfo DirName;
10467 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10468 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10469 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10470 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10471 return Res;
10472}
10473
10474template <typename Derived>
10475StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10476 OMPTargetEnterDataDirective *D) {
10477 DeclarationNameInfo DirName;
10478 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10479 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10480 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10481 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10482 return Res;
10483}
10484
10485template <typename Derived>
10486StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10487 OMPTargetExitDataDirective *D) {
10488 DeclarationNameInfo DirName;
10489 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10490 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10491 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10492 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10493 return Res;
10494}
10495
10496template <typename Derived>
10497StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10498 OMPTargetParallelDirective *D) {
10499 DeclarationNameInfo DirName;
10500 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10501 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10502 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10503 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10504 return Res;
10505}
10506
10507template <typename Derived>
10508StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10509 OMPTargetParallelForDirective *D) {
10510 DeclarationNameInfo DirName;
10511 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10512 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10513 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10514 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10515 return Res;
10516}
10517
10518template <typename Derived>
10519StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10520 OMPTargetUpdateDirective *D) {
10521 DeclarationNameInfo DirName;
10522 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10523 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10524 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10525 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10526 return Res;
10527}
10528
10529template <typename Derived>
10530StmtResult
10531TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10532 DeclarationNameInfo DirName;
10533 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10534 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10535 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10536 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10537 return Res;
10538}
10539
10540template <typename Derived>
10541StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10542 OMPCancellationPointDirective *D) {
10543 DeclarationNameInfo DirName;
10544 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10545 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10546 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10547 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10548 return Res;
10549}
10550
10551template <typename Derived>
10552StmtResult
10553TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10554 DeclarationNameInfo DirName;
10555 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10556 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10557 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10558 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10559 return Res;
10560}
10561
10562template <typename Derived>
10563StmtResult
10564TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10565 DeclarationNameInfo DirName;
10566 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10567 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10568 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10569 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10570 return Res;
10571}
10572
10573template <typename Derived>
10574StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10575 OMPTaskLoopSimdDirective *D) {
10576 DeclarationNameInfo DirName;
10577 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10578 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10579 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10580 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10581 return Res;
10582}
10583
10584template <typename Derived>
10585StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10586 OMPMasterTaskLoopDirective *D) {
10587 DeclarationNameInfo DirName;
10588 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10589 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10590 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10591 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10592 return Res;
10593}
10594
10595template <typename Derived>
10596StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10597 OMPMaskedTaskLoopDirective *D) {
10598 DeclarationNameInfo DirName;
10599 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10600 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10601 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10602 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10603 return Res;
10604}
10605
10606template <typename Derived>
10607StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10608 OMPMasterTaskLoopSimdDirective *D) {
10609 DeclarationNameInfo DirName;
10610 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10611 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10612 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10613 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10614 return Res;
10615}
10616
10617template <typename Derived>
10618StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10619 OMPMaskedTaskLoopSimdDirective *D) {
10620 DeclarationNameInfo DirName;
10621 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10622 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10623 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10624 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10625 return Res;
10626}
10627
10628template <typename Derived>
10629StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10630 OMPParallelMasterTaskLoopDirective *D) {
10631 DeclarationNameInfo DirName;
10632 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10633 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10634 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10635 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10636 return Res;
10637}
10638
10639template <typename Derived>
10640StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10641 OMPParallelMaskedTaskLoopDirective *D) {
10642 DeclarationNameInfo DirName;
10643 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10644 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10645 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10646 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10647 return Res;
10648}
10649
10650template <typename Derived>
10651StmtResult
10652TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10653 OMPParallelMasterTaskLoopSimdDirective *D) {
10654 DeclarationNameInfo DirName;
10655 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10656 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10657 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10658 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10659 return Res;
10660}
10661
10662template <typename Derived>
10663StmtResult
10664TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10665 OMPParallelMaskedTaskLoopSimdDirective *D) {
10666 DeclarationNameInfo DirName;
10667 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10668 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10669 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10670 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10671 return Res;
10672}
10673
10674template <typename Derived>
10675StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10676 OMPDistributeDirective *D) {
10677 DeclarationNameInfo DirName;
10678 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10679 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10680 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10681 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10682 return Res;
10683}
10684
10685template <typename Derived>
10686StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10687 OMPDistributeParallelForDirective *D) {
10688 DeclarationNameInfo DirName;
10689 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10690 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10691 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10692 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10693 return Res;
10694}
10695
10696template <typename Derived>
10697StmtResult
10698TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10699 OMPDistributeParallelForSimdDirective *D) {
10700 DeclarationNameInfo DirName;
10701 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10702 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10703 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10704 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10705 return Res;
10706}
10707
10708template <typename Derived>
10709StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10710 OMPDistributeSimdDirective *D) {
10711 DeclarationNameInfo DirName;
10712 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10713 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10714 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10715 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10716 return Res;
10717}
10718
10719template <typename Derived>
10720StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10721 OMPTargetParallelForSimdDirective *D) {
10722 DeclarationNameInfo DirName;
10723 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10724 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10725 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10726 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10727 return Res;
10728}
10729
10730template <typename Derived>
10731StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10732 OMPTargetSimdDirective *D) {
10733 DeclarationNameInfo DirName;
10734 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10735 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10736 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10737 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10738 return Res;
10739}
10740
10741template <typename Derived>
10742StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10743 OMPTeamsDistributeDirective *D) {
10744 DeclarationNameInfo DirName;
10745 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10746 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10747 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10748 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10749 return Res;
10750}
10751
10752template <typename Derived>
10753StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10754 OMPTeamsDistributeSimdDirective *D) {
10755 DeclarationNameInfo DirName;
10756 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10757 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10758 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10759 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10760 return Res;
10761}
10762
10763template <typename Derived>
10764StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10765 OMPTeamsDistributeParallelForSimdDirective *D) {
10766 DeclarationNameInfo DirName;
10767 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10768 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10769 D->getBeginLoc());
10770 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10771 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10772 return Res;
10773}
10774
10775template <typename Derived>
10776StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10777 OMPTeamsDistributeParallelForDirective *D) {
10778 DeclarationNameInfo DirName;
10779 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10780 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10781 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10782 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10783 return Res;
10784}
10785
10786template <typename Derived>
10787StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10788 OMPTargetTeamsDirective *D) {
10789 DeclarationNameInfo DirName;
10790 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10791 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10792 auto Res = getDerived().TransformOMPExecutableDirective(D);
10793 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10794 return Res;
10795}
10796
10797template <typename Derived>
10798StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10799 OMPTargetTeamsDistributeDirective *D) {
10800 DeclarationNameInfo DirName;
10801 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10802 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10803 auto Res = getDerived().TransformOMPExecutableDirective(D);
10804 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10805 return Res;
10806}
10807
10808template <typename Derived>
10809StmtResult
10810TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10811 OMPTargetTeamsDistributeParallelForDirective *D) {
10812 DeclarationNameInfo DirName;
10813 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10814 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10815 D->getBeginLoc());
10816 auto Res = getDerived().TransformOMPExecutableDirective(D);
10817 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10818 return Res;
10819}
10820
10821template <typename Derived>
10822StmtResult TreeTransform<Derived>::
10823 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10824 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10825 DeclarationNameInfo DirName;
10826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10827 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10828 D->getBeginLoc());
10829 auto Res = getDerived().TransformOMPExecutableDirective(D);
10830 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10831 return Res;
10832}
10833
10834template <typename Derived>
10835StmtResult
10836TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10837 OMPTargetTeamsDistributeSimdDirective *D) {
10838 DeclarationNameInfo DirName;
10839 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10840 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10841 auto Res = getDerived().TransformOMPExecutableDirective(D);
10842 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10843 return Res;
10844}
10845
10846template <typename Derived>
10847StmtResult
10848TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10849 DeclarationNameInfo DirName;
10850 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10851 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10852 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10853 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10854 return Res;
10855}
10856
10857template <typename Derived>
10858StmtResult
10859TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10860 DeclarationNameInfo DirName;
10861 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10862 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10863 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10864 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10865 return Res;
10866}
10867
10868template <typename Derived>
10869StmtResult
10870TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10871 DeclarationNameInfo DirName;
10872 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10873 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10874 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10875 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10876 return Res;
10877}
10878
10879template <typename Derived>
10880StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10881 OMPGenericLoopDirective *D) {
10882 DeclarationNameInfo DirName;
10883 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10884 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10885 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10886 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10887 return Res;
10888}
10889
10890template <typename Derived>
10891StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10892 OMPTeamsGenericLoopDirective *D) {
10893 DeclarationNameInfo DirName;
10894 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10895 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10896 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10897 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10898 return Res;
10899}
10900
10901template <typename Derived>
10902StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10903 OMPTargetTeamsGenericLoopDirective *D) {
10904 DeclarationNameInfo DirName;
10905 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10906 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10907 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10908 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10909 return Res;
10910}
10911
10912template <typename Derived>
10913StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10914 OMPParallelGenericLoopDirective *D) {
10915 DeclarationNameInfo DirName;
10916 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10917 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10918 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10919 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10920 return Res;
10921}
10922
10923template <typename Derived>
10924StmtResult
10925TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10926 OMPTargetParallelGenericLoopDirective *D) {
10927 DeclarationNameInfo DirName;
10928 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10929 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10930 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10931 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10932 return Res;
10933}
10934
10935//===----------------------------------------------------------------------===//
10936// OpenMP clause transformation
10937//===----------------------------------------------------------------------===//
10938template <typename Derived>
10939OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10940 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10941 if (Cond.isInvalid())
10942 return nullptr;
10943 return getDerived().RebuildOMPIfClause(
10944 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10945 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10946}
10947
10948template <typename Derived>
10949OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10950 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10951 if (Cond.isInvalid())
10952 return nullptr;
10953 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10954 C->getLParenLoc(), C->getEndLoc());
10955}
10956
10957template <typename Derived>
10958OMPClause *
10959TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10960 llvm::SmallVector<Expr *, 3> Vars;
10961 Vars.reserve(N: C->varlist_size());
10962 for (auto *VE : C->varlist()) {
10963 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10964 if (EVar.isInvalid())
10965 return nullptr;
10966 Vars.push_back(Elt: EVar.get());
10967 }
10968 Expr *DimsModifierExpr = C->getDimsModifierExpr();
10969 if (DimsModifierExpr) {
10970 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: DimsModifierExpr));
10971 if (EVar.isInvalid())
10972 return nullptr;
10973 DimsModifierExpr = EVar.get();
10974 }
10975 return getDerived().RebuildOMPNumThreadsClause(
10976 Vars, C->getPrescriptivenessModifier(),
10977 C->getPrescriptivenessModifierLoc(), C->getDimsModifier(),
10978 DimsModifierExpr, C->getDimsModifierLoc(), C->getBeginLoc(),
10979 C->getLParenLoc(), C->getEndLoc());
10980}
10981
10982template <typename Derived>
10983OMPClause *
10984TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10985 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10986 if (E.isInvalid())
10987 return nullptr;
10988 return getDerived().RebuildOMPSafelenClause(
10989 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10990}
10991
10992template <typename Derived>
10993OMPClause *
10994TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10995 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10996 if (E.isInvalid())
10997 return nullptr;
10998 return getDerived().RebuildOMPAllocatorClause(
10999 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11000}
11001
11002template <typename Derived>
11003OMPClause *
11004TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
11005 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
11006 if (E.isInvalid())
11007 return nullptr;
11008 return getDerived().RebuildOMPSimdlenClause(
11009 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11010}
11011
11012template <typename Derived>
11013OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
11014 SmallVector<Expr *, 4> TransformedSizes;
11015 TransformedSizes.reserve(N: C->getNumSizes());
11016 bool Changed = false;
11017 for (Expr *E : C->getSizesRefs()) {
11018 if (!E) {
11019 TransformedSizes.push_back(Elt: nullptr);
11020 continue;
11021 }
11022
11023 ExprResult T = getDerived().TransformExpr(E);
11024 if (T.isInvalid())
11025 return nullptr;
11026 if (E != T.get())
11027 Changed = true;
11028 TransformedSizes.push_back(Elt: T.get());
11029 }
11030
11031 if (!Changed && !getDerived().AlwaysRebuild())
11032 return C;
11033 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
11034 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11035}
11036
11037template <typename Derived>
11038OMPClause *
11039TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
11040 SmallVector<Expr *, 4> TransformedCounts;
11041 TransformedCounts.reserve(N: C->getNumCounts());
11042 for (Expr *E : C->getCountsRefs()) {
11043 if (!E) {
11044 TransformedCounts.push_back(Elt: nullptr);
11045 continue;
11046 }
11047
11048 ExprResult T = getDerived().TransformExpr(E);
11049 if (T.isInvalid())
11050 return nullptr;
11051 TransformedCounts.push_back(Elt: T.get());
11052 }
11053
11054 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
11055 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
11056 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
11057}
11058
11059template <typename Derived>
11060OMPClause *
11061TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
11062 SmallVector<Expr *> TransformedArgs;
11063 TransformedArgs.reserve(N: C->getNumLoops());
11064 bool Changed = false;
11065 for (Expr *E : C->getArgsRefs()) {
11066 if (!E) {
11067 TransformedArgs.push_back(Elt: nullptr);
11068 continue;
11069 }
11070
11071 ExprResult T = getDerived().TransformExpr(E);
11072 if (T.isInvalid())
11073 return nullptr;
11074 if (E != T.get())
11075 Changed = true;
11076 TransformedArgs.push_back(Elt: T.get());
11077 }
11078
11079 if (!Changed && !getDerived().AlwaysRebuild())
11080 return C;
11081 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
11082 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
11083}
11084
11085template <typename Derived>
11086OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
11087 if (!getDerived().AlwaysRebuild())
11088 return C;
11089 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
11090}
11091
11092template <typename Derived>
11093OMPClause *
11094TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
11095 ExprResult T = getDerived().TransformExpr(C->getFactor());
11096 if (T.isInvalid())
11097 return nullptr;
11098 Expr *Factor = T.get();
11099 bool Changed = Factor != C->getFactor();
11100
11101 if (!Changed && !getDerived().AlwaysRebuild())
11102 return C;
11103 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
11104 EndLoc: C->getEndLoc());
11105}
11106
11107template <typename Derived>
11108OMPClause *
11109TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
11110 ExprResult F = getDerived().TransformExpr(C->getFirst());
11111 if (F.isInvalid())
11112 return nullptr;
11113
11114 ExprResult Cn = getDerived().TransformExpr(C->getCount());
11115 if (Cn.isInvalid())
11116 return nullptr;
11117
11118 Expr *First = F.get();
11119 Expr *Count = Cn.get();
11120
11121 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
11122
11123 // If no changes and AlwaysRebuild() is false, return the original clause
11124 if (!Changed && !getDerived().AlwaysRebuild())
11125 return C;
11126
11127 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
11128 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
11129 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
11130}
11131
11132template <typename Derived>
11133OMPClause *
11134TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
11135 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
11136 if (E.isInvalid())
11137 return nullptr;
11138 return getDerived().RebuildOMPCollapseClause(
11139 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11140}
11141
11142template <typename Derived>
11143OMPClause *
11144TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
11145 return getDerived().RebuildOMPDefaultClause(
11146 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
11147 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
11148 C->getEndLoc());
11149}
11150
11151template <typename Derived>
11152OMPClause *
11153TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
11154 // No need to rebuild this clause, no template-dependent parameters.
11155 return C;
11156}
11157
11158template <typename Derived>
11159OMPClause *
11160TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
11161 Expr *Impex = C->getImpexType();
11162 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
11163
11164 if (TransformedImpex.isInvalid())
11165 return nullptr;
11166
11167 return getDerived().RebuildOMPTransparentClause(
11168 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
11169 C->getEndLoc());
11170}
11171
11172template <typename Derived>
11173OMPClause *
11174TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
11175 return getDerived().RebuildOMPProcBindClause(
11176 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
11177 C->getLParenLoc(), C->getEndLoc());
11178}
11179
11180template <typename Derived>
11181OMPClause *
11182TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
11183 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11184 if (E.isInvalid())
11185 return nullptr;
11186 return getDerived().RebuildOMPScheduleClause(
11187 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
11188 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11189 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
11190 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11191}
11192
11193template <typename Derived>
11194OMPClause *
11195TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
11196 ExprResult E;
11197 if (auto *Num = C->getNumForLoops()) {
11198 E = getDerived().TransformExpr(Num);
11199 if (E.isInvalid())
11200 return nullptr;
11201 }
11202 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
11203 C->getLParenLoc(), E.get());
11204}
11205
11206template <typename Derived>
11207OMPClause *
11208TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
11209 ExprResult E;
11210 if (Expr *Evt = C->getEventHandler()) {
11211 E = getDerived().TransformExpr(Evt);
11212 if (E.isInvalid())
11213 return nullptr;
11214 }
11215 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
11216 C->getLParenLoc(), C->getEndLoc());
11217}
11218
11219template <typename Derived>
11220OMPClause *
11221TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
11222 ExprResult Cond;
11223 if (auto *Condition = C->getCondition()) {
11224 Cond = getDerived().TransformExpr(Condition);
11225 if (Cond.isInvalid())
11226 return nullptr;
11227 }
11228 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
11229 C->getLParenLoc(), C->getEndLoc());
11230}
11231
11232template <typename Derived>
11233OMPClause *
11234TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
11235 // No need to rebuild this clause, no template-dependent parameters.
11236 return C;
11237}
11238
11239template <typename Derived>
11240OMPClause *
11241TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
11242 // No need to rebuild this clause, no template-dependent parameters.
11243 return C;
11244}
11245
11246template <typename Derived>
11247OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
11248 // No need to rebuild this clause, no template-dependent parameters.
11249 return C;
11250}
11251
11252template <typename Derived>
11253OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
11254 // No need to rebuild this clause, no template-dependent parameters.
11255 return C;
11256}
11257
11258template <typename Derived>
11259OMPClause *
11260TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
11261 // No need to rebuild this clause, no template-dependent parameters.
11262 return C;
11263}
11264
11265template <typename Derived>
11266OMPClause *TreeTransform<Derived>::TransformOMPUpdateDependObjectsClause(
11267 OMPUpdateDependObjectsClause *C) {
11268 // No need to rebuild this clause, no template-dependent parameters.
11269 return C;
11270}
11271
11272template <typename Derived>
11273OMPClause *
11274TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
11275 // No need to rebuild this clause, no template-dependent parameters.
11276 return C;
11277}
11278
11279template <typename Derived>
11280OMPClause *
11281TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
11282 // No need to rebuild this clause, no template-dependent parameters.
11283 return C;
11284}
11285
11286template <typename Derived>
11287OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
11288 // No need to rebuild this clause, no template-dependent parameters.
11289 return C;
11290}
11291
11292template <typename Derived>
11293OMPClause *
11294TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
11295 return C;
11296}
11297
11298template <typename Derived>
11299OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
11300 ExprResult E = getDerived().TransformExpr(C->getExpr());
11301 if (E.isInvalid())
11302 return nullptr;
11303 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
11304 C->getLParenLoc(), C->getEndLoc());
11305}
11306
11307template <typename Derived>
11308OMPClause *
11309TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
11310 return C;
11311}
11312
11313template <typename Derived>
11314OMPClause *
11315TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
11316 return C;
11317}
11318template <typename Derived>
11319OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
11320 OMPNoOpenMPRoutinesClause *C) {
11321 return C;
11322}
11323template <typename Derived>
11324OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
11325 OMPNoOpenMPConstructsClause *C) {
11326 return C;
11327}
11328template <typename Derived>
11329OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
11330 OMPNoParallelismClause *C) {
11331 return C;
11332}
11333
11334template <typename Derived>
11335OMPClause *
11336TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
11337 // No need to rebuild this clause, no template-dependent parameters.
11338 return C;
11339}
11340
11341template <typename Derived>
11342OMPClause *
11343TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
11344 // No need to rebuild this clause, no template-dependent parameters.
11345 return C;
11346}
11347
11348template <typename Derived>
11349OMPClause *
11350TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
11351 // No need to rebuild this clause, no template-dependent parameters.
11352 return C;
11353}
11354
11355template <typename Derived>
11356OMPClause *
11357TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
11358 // No need to rebuild this clause, no template-dependent parameters.
11359 return C;
11360}
11361
11362template <typename Derived>
11363OMPClause *
11364TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
11365 // No need to rebuild this clause, no template-dependent parameters.
11366 return C;
11367}
11368
11369template <typename Derived>
11370OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
11371 // No need to rebuild this clause, no template-dependent parameters.
11372 return C;
11373}
11374
11375template <typename Derived>
11376OMPClause *
11377TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
11378 // No need to rebuild this clause, no template-dependent parameters.
11379 return C;
11380}
11381
11382template <typename Derived>
11383OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
11384 // No need to rebuild this clause, no template-dependent parameters.
11385 return C;
11386}
11387
11388template <typename Derived>
11389OMPClause *
11390TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
11391 // No need to rebuild this clause, no template-dependent parameters.
11392 return C;
11393}
11394
11395template <typename Derived>
11396OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11397 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11398 if (IVR.isInvalid())
11399 return nullptr;
11400
11401 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11402 for (OMPInitClause::PrefView P : C->prefs()) {
11403 Expr *NewFr = nullptr;
11404 if (P.Fr) {
11405 ExprResult ER = getDerived().TransformExpr(P.Fr);
11406 if (ER.isInvalid())
11407 return nullptr;
11408 NewFr = ER.get();
11409 }
11410 SmallVector<Expr *, 2> NewAttrs;
11411 NewAttrs.reserve(N: P.Attrs.size());
11412 for (Expr *A : P.Attrs) {
11413 ExprResult ER = getDerived().TransformExpr(A);
11414 if (ER.isInvalid())
11415 return nullptr;
11416 NewAttrs.push_back(Elt: ER.get());
11417 }
11418 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11419 }
11420 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11421 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11422 C->getBeginLoc(), C->getLParenLoc(),
11423 C->getVarLoc(), C->getEndLoc());
11424}
11425
11426template <typename Derived>
11427OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11428 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11429 if (ER.isInvalid())
11430 return nullptr;
11431 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11432 C->getLParenLoc(), C->getVarLoc(),
11433 C->getEndLoc());
11434}
11435
11436template <typename Derived>
11437OMPClause *
11438TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11439 ExprResult ER;
11440 if (Expr *IV = C->getInteropVar()) {
11441 ER = getDerived().TransformExpr(IV);
11442 if (ER.isInvalid())
11443 return nullptr;
11444 }
11445 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11446 C->getLParenLoc(), C->getVarLoc(),
11447 C->getEndLoc());
11448}
11449
11450template <typename Derived>
11451OMPClause *
11452TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11453 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11454 if (Cond.isInvalid())
11455 return nullptr;
11456 return getDerived().RebuildOMPNovariantsClause(
11457 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11458}
11459
11460template <typename Derived>
11461OMPClause *
11462TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11463 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11464 if (Cond.isInvalid())
11465 return nullptr;
11466 return getDerived().RebuildOMPNocontextClause(
11467 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11468}
11469
11470template <typename Derived>
11471OMPClause *
11472TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11473 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11474 if (ThreadID.isInvalid())
11475 return nullptr;
11476 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11477 C->getLParenLoc(), C->getEndLoc());
11478}
11479
11480template <typename Derived>
11481OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11482 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11483 if (E.isInvalid())
11484 return nullptr;
11485 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11486 C->getLParenLoc(), C->getEndLoc());
11487}
11488
11489template <typename Derived>
11490OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11491 OMPUnifiedAddressClause *C) {
11492 llvm_unreachable("unified_address clause cannot appear in dependent context");
11493}
11494
11495template <typename Derived>
11496OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11497 OMPUnifiedSharedMemoryClause *C) {
11498 llvm_unreachable(
11499 "unified_shared_memory clause cannot appear in dependent context");
11500}
11501
11502template <typename Derived>
11503OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11504 OMPReverseOffloadClause *C) {
11505 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11506}
11507
11508template <typename Derived>
11509OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11510 OMPDynamicAllocatorsClause *C) {
11511 llvm_unreachable(
11512 "dynamic_allocators clause cannot appear in dependent context");
11513}
11514
11515template <typename Derived>
11516OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11517 OMPAtomicDefaultMemOrderClause *C) {
11518 llvm_unreachable(
11519 "atomic_default_mem_order clause cannot appear in dependent context");
11520}
11521
11522template <typename Derived>
11523OMPClause *
11524TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11525 llvm_unreachable("self_maps clause cannot appear in dependent context");
11526}
11527
11528template <typename Derived>
11529OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11530 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11531 C->getBeginLoc(), C->getLParenLoc(),
11532 C->getEndLoc());
11533}
11534
11535template <typename Derived>
11536OMPClause *
11537TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11538 return getDerived().RebuildOMPSeverityClause(
11539 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11540 C->getLParenLoc(), C->getEndLoc());
11541}
11542
11543template <typename Derived>
11544OMPClause *
11545TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11546 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11547 if (E.isInvalid())
11548 return nullptr;
11549 return getDerived().RebuildOMPMessageClause(
11550 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11551}
11552
11553template <typename Derived>
11554OMPClause *
11555TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11556 llvm::SmallVector<Expr *, 16> Vars;
11557 Vars.reserve(N: C->varlist_size());
11558 for (auto *VE : C->varlist()) {
11559 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11560 if (EVar.isInvalid())
11561 return nullptr;
11562 Vars.push_back(Elt: EVar.get());
11563 }
11564 return getDerived().RebuildOMPPrivateClause(
11565 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11566}
11567
11568template <typename Derived>
11569OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11570 OMPFirstprivateClause *C) {
11571 llvm::SmallVector<Expr *, 16> Vars;
11572 Vars.reserve(N: C->varlist_size());
11573 for (auto *VE : C->varlist()) {
11574 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11575 if (EVar.isInvalid())
11576 return nullptr;
11577 Vars.push_back(Elt: EVar.get());
11578 }
11579 return getDerived().RebuildOMPFirstprivateClause(
11580 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11581}
11582
11583template <typename Derived>
11584OMPClause *
11585TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11586 llvm::SmallVector<Expr *, 16> Vars;
11587 Vars.reserve(N: C->varlist_size());
11588 for (auto *VE : C->varlist()) {
11589 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11590 if (EVar.isInvalid())
11591 return nullptr;
11592 Vars.push_back(Elt: EVar.get());
11593 }
11594 return getDerived().RebuildOMPLastprivateClause(
11595 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11596 C->getLParenLoc(), C->getEndLoc());
11597}
11598
11599template <typename Derived>
11600OMPClause *
11601TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11602 llvm::SmallVector<Expr *, 16> Vars;
11603 Vars.reserve(N: C->varlist_size());
11604 for (auto *VE : C->varlist()) {
11605 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11606 if (EVar.isInvalid())
11607 return nullptr;
11608 Vars.push_back(Elt: EVar.get());
11609 }
11610 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11611 C->getLParenLoc(), C->getEndLoc());
11612}
11613
11614template <typename Derived>
11615OMPClause *
11616TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11617 llvm::SmallVector<Expr *, 16> Vars;
11618 Vars.reserve(N: C->varlist_size());
11619 for (auto *VE : C->varlist()) {
11620 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11621 if (EVar.isInvalid())
11622 return nullptr;
11623 Vars.push_back(Elt: EVar.get());
11624 }
11625 CXXScopeSpec ReductionIdScopeSpec;
11626 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11627
11628 DeclarationNameInfo NameInfo = C->getNameInfo();
11629 if (NameInfo.getName()) {
11630 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11631 if (!NameInfo.getName())
11632 return nullptr;
11633 }
11634 // Build a list of all UDR decls with the same names ranged by the Scopes.
11635 // The Scope boundary is a duplication of the previous decl.
11636 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11637 for (auto *E : C->reduction_ops()) {
11638 // Transform all the decls.
11639 if (E) {
11640 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11641 UnresolvedSet<8> Decls;
11642 for (auto *D : ULE->decls()) {
11643 NamedDecl *InstD =
11644 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11645 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11646 }
11647 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11648 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11649 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11650 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11651 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11652 } else
11653 UnresolvedReductions.push_back(Elt: nullptr);
11654 }
11655 return getDerived().RebuildOMPReductionClause(
11656 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11657 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11658 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11659}
11660
11661template <typename Derived>
11662OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11663 OMPTaskReductionClause *C) {
11664 llvm::SmallVector<Expr *, 16> Vars;
11665 Vars.reserve(N: C->varlist_size());
11666 for (auto *VE : C->varlist()) {
11667 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11668 if (EVar.isInvalid())
11669 return nullptr;
11670 Vars.push_back(Elt: EVar.get());
11671 }
11672 CXXScopeSpec ReductionIdScopeSpec;
11673 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11674
11675 DeclarationNameInfo NameInfo = C->getNameInfo();
11676 if (NameInfo.getName()) {
11677 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11678 if (!NameInfo.getName())
11679 return nullptr;
11680 }
11681 // Build a list of all UDR decls with the same names ranged by the Scopes.
11682 // The Scope boundary is a duplication of the previous decl.
11683 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11684 for (auto *E : C->reduction_ops()) {
11685 // Transform all the decls.
11686 if (E) {
11687 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11688 UnresolvedSet<8> Decls;
11689 for (auto *D : ULE->decls()) {
11690 NamedDecl *InstD =
11691 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11692 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11693 }
11694 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11695 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11696 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11697 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11698 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11699 } else
11700 UnresolvedReductions.push_back(Elt: nullptr);
11701 }
11702 return getDerived().RebuildOMPTaskReductionClause(
11703 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11704 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11705}
11706
11707template <typename Derived>
11708OMPClause *
11709TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11710 llvm::SmallVector<Expr *, 16> Vars;
11711 Vars.reserve(N: C->varlist_size());
11712 for (auto *VE : C->varlist()) {
11713 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11714 if (EVar.isInvalid())
11715 return nullptr;
11716 Vars.push_back(Elt: EVar.get());
11717 }
11718 CXXScopeSpec ReductionIdScopeSpec;
11719 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11720
11721 DeclarationNameInfo NameInfo = C->getNameInfo();
11722 if (NameInfo.getName()) {
11723 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11724 if (!NameInfo.getName())
11725 return nullptr;
11726 }
11727 // Build a list of all UDR decls with the same names ranged by the Scopes.
11728 // The Scope boundary is a duplication of the previous decl.
11729 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11730 for (auto *E : C->reduction_ops()) {
11731 // Transform all the decls.
11732 if (E) {
11733 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11734 UnresolvedSet<8> Decls;
11735 for (auto *D : ULE->decls()) {
11736 NamedDecl *InstD =
11737 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11738 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11739 }
11740 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11741 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11742 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11743 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11744 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11745 } else
11746 UnresolvedReductions.push_back(Elt: nullptr);
11747 }
11748 return getDerived().RebuildOMPInReductionClause(
11749 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11750 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11751}
11752
11753template <typename Derived>
11754OMPClause *
11755TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11756 llvm::SmallVector<Expr *, 16> Vars;
11757 Vars.reserve(N: C->varlist_size());
11758 for (auto *VE : C->varlist()) {
11759 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11760 if (EVar.isInvalid())
11761 return nullptr;
11762 Vars.push_back(Elt: EVar.get());
11763 }
11764 ExprResult Step = getDerived().TransformExpr(C->getStep());
11765 if (Step.isInvalid())
11766 return nullptr;
11767 return getDerived().RebuildOMPLinearClause(
11768 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11769 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11770 C->getEndLoc());
11771}
11772
11773template <typename Derived>
11774OMPClause *
11775TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11776 llvm::SmallVector<Expr *, 16> Vars;
11777 Vars.reserve(N: C->varlist_size());
11778 for (auto *VE : C->varlist()) {
11779 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11780 if (EVar.isInvalid())
11781 return nullptr;
11782 Vars.push_back(Elt: EVar.get());
11783 }
11784 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11785 if (Alignment.isInvalid())
11786 return nullptr;
11787 return getDerived().RebuildOMPAlignedClause(
11788 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11789 C->getColonLoc(), C->getEndLoc());
11790}
11791
11792template <typename Derived>
11793OMPClause *
11794TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11795 llvm::SmallVector<Expr *, 16> Vars;
11796 Vars.reserve(N: C->varlist_size());
11797 for (auto *VE : C->varlist()) {
11798 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11799 if (EVar.isInvalid())
11800 return nullptr;
11801 Vars.push_back(Elt: EVar.get());
11802 }
11803 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11804 C->getLParenLoc(), C->getEndLoc());
11805}
11806
11807template <typename Derived>
11808OMPClause *
11809TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11810 llvm::SmallVector<Expr *, 16> Vars;
11811 Vars.reserve(N: C->varlist_size());
11812 for (auto *VE : C->varlist()) {
11813 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11814 if (EVar.isInvalid())
11815 return nullptr;
11816 Vars.push_back(Elt: EVar.get());
11817 }
11818 return getDerived().RebuildOMPCopyprivateClause(
11819 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11820}
11821
11822template <typename Derived>
11823OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11824 llvm::SmallVector<Expr *, 16> Vars;
11825 Vars.reserve(N: C->varlist_size());
11826 for (auto *VE : C->varlist()) {
11827 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11828 if (EVar.isInvalid())
11829 return nullptr;
11830 Vars.push_back(Elt: EVar.get());
11831 }
11832 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11833 C->getLParenLoc(), C->getEndLoc());
11834}
11835
11836template <typename Derived>
11837OMPClause *
11838TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11839 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11840 if (E.isInvalid())
11841 return nullptr;
11842 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11843 C->getLParenLoc(), C->getEndLoc());
11844}
11845
11846template <typename Derived>
11847OMPClause *
11848TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11849 llvm::SmallVector<Expr *, 16> Vars;
11850 Expr *DepModifier = C->getModifier();
11851 if (DepModifier) {
11852 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11853 if (DepModRes.isInvalid())
11854 return nullptr;
11855 DepModifier = DepModRes.get();
11856 }
11857 Vars.reserve(N: C->varlist_size());
11858 for (auto *VE : C->varlist()) {
11859 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11860 if (EVar.isInvalid())
11861 return nullptr;
11862 Vars.push_back(Elt: EVar.get());
11863 }
11864 return getDerived().RebuildOMPDependClause(
11865 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11866 C->getOmpAllMemoryLoc()},
11867 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11868}
11869
11870template <typename Derived>
11871OMPClause *
11872TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11873 ExprResult E = getDerived().TransformExpr(C->getDevice());
11874 if (E.isInvalid())
11875 return nullptr;
11876 return getDerived().RebuildOMPDeviceClause(
11877 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11878 C->getModifierLoc(), C->getEndLoc());
11879}
11880
11881template <typename Derived, class T>
11882bool transformOMPMappableExprListClause(
11883 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11884 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11885 DeclarationNameInfo &MapperIdInfo,
11886 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11887 // Transform expressions in the list.
11888 Vars.reserve(N: C->varlist_size());
11889 for (auto *VE : C->varlist()) {
11890 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11891 if (EVar.isInvalid())
11892 return true;
11893 Vars.push_back(Elt: EVar.get());
11894 }
11895 // Transform mapper scope specifier and identifier.
11896 NestedNameSpecifierLoc QualifierLoc;
11897 if (C->getMapperQualifierLoc()) {
11898 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11899 C->getMapperQualifierLoc());
11900 if (!QualifierLoc)
11901 return true;
11902 }
11903 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11904 MapperIdInfo = C->getMapperIdInfo();
11905 if (MapperIdInfo.getName()) {
11906 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11907 if (!MapperIdInfo.getName())
11908 return true;
11909 }
11910 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11911 // the previous user-defined mapper lookup in dependent environment.
11912 for (auto *E : C->mapperlists()) {
11913 // Transform all the decls.
11914 if (E) {
11915 auto *ULE = cast<UnresolvedLookupExpr>(E);
11916 UnresolvedSet<8> Decls;
11917 for (auto *D : ULE->decls()) {
11918 NamedDecl *InstD =
11919 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11920 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11921 }
11922 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11923 TT.getSema().Context, /*NamingClass=*/nullptr,
11924 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11925 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11926 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11927 } else {
11928 UnresolvedMappers.push_back(Elt: nullptr);
11929 }
11930 }
11931 return false;
11932}
11933
11934template <typename Derived>
11935OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11936 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11937 llvm::SmallVector<Expr *, 16> Vars;
11938 Expr *IteratorModifier = C->getIteratorModifier();
11939 if (IteratorModifier) {
11940 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11941 if (MapModRes.isInvalid())
11942 return nullptr;
11943 IteratorModifier = MapModRes.get();
11944 }
11945 CXXScopeSpec MapperIdScopeSpec;
11946 DeclarationNameInfo MapperIdInfo;
11947 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11948 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11949 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11950 return nullptr;
11951 return getDerived().RebuildOMPMapClause(
11952 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11953 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11954 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11955}
11956
11957template <typename Derived>
11958OMPClause *
11959TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11960 Expr *Allocator = C->getAllocator();
11961 if (Allocator) {
11962 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11963 if (AllocatorRes.isInvalid())
11964 return nullptr;
11965 Allocator = AllocatorRes.get();
11966 }
11967 Expr *Alignment = C->getAlignment();
11968 if (Alignment) {
11969 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11970 if (AlignmentRes.isInvalid())
11971 return nullptr;
11972 Alignment = AlignmentRes.get();
11973 }
11974 llvm::SmallVector<Expr *, 16> Vars;
11975 Vars.reserve(N: C->varlist_size());
11976 for (auto *VE : C->varlist()) {
11977 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11978 if (EVar.isInvalid())
11979 return nullptr;
11980 Vars.push_back(Elt: EVar.get());
11981 }
11982 return getDerived().RebuildOMPAllocateClause(
11983 Allocator, Alignment, C->getFirstAllocateModifier(),
11984 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11985 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11986 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11987}
11988
11989template <typename Derived>
11990OMPClause *
11991TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11992 llvm::SmallVector<Expr *, 3> Vars;
11993 Vars.reserve(N: C->varlist_size());
11994 for (auto *VE : C->varlist()) {
11995 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11996 if (EVar.isInvalid())
11997 return nullptr;
11998 Vars.push_back(Elt: EVar.get());
11999 }
12000 Expr *ModifierExpr = C->getModifierExpr();
12001 if (ModifierExpr) {
12002 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12003 if (EVar.isInvalid())
12004 return nullptr;
12005 ModifierExpr = EVar.get();
12006 }
12007 return getDerived().RebuildOMPNumTeamsClause(
12008 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12009 OMPC_NUMTEAMS_unknown, nullptr, SourceLocation(), C->getBeginLoc(),
12010 C->getLParenLoc(), C->getEndLoc());
12011}
12012
12013template <typename Derived>
12014OMPClause *
12015TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
12016 llvm::SmallVector<Expr *, 3> Vars;
12017 Vars.reserve(N: C->varlist_size());
12018 for (auto *VE : C->varlist()) {
12019 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12020 if (EVar.isInvalid())
12021 return nullptr;
12022 Vars.push_back(Elt: EVar.get());
12023 }
12024 Expr *ModifierExpr = C->getModifierExpr();
12025 if (ModifierExpr) {
12026 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
12027 if (EVar.isInvalid())
12028 return nullptr;
12029 ModifierExpr = EVar.get();
12030 }
12031 return getDerived().RebuildOMPThreadLimitClause(
12032 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
12033 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12034}
12035
12036template <typename Derived>
12037OMPClause *
12038TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
12039 ExprResult E = getDerived().TransformExpr(C->getPriority());
12040 if (E.isInvalid())
12041 return nullptr;
12042 return getDerived().RebuildOMPPriorityClause(
12043 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12044}
12045
12046template <typename Derived>
12047OMPClause *
12048TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
12049 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
12050 if (E.isInvalid())
12051 return nullptr;
12052 return getDerived().RebuildOMPGrainsizeClause(
12053 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12054 C->getModifierLoc(), C->getEndLoc());
12055}
12056
12057template <typename Derived>
12058OMPClause *
12059TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
12060 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
12061 if (E.isInvalid())
12062 return nullptr;
12063 return getDerived().RebuildOMPNumTasksClause(
12064 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12065 C->getModifierLoc(), C->getEndLoc());
12066}
12067
12068template <typename Derived>
12069OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
12070 ExprResult E = getDerived().TransformExpr(C->getHint());
12071 if (E.isInvalid())
12072 return nullptr;
12073 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
12074 C->getLParenLoc(), C->getEndLoc());
12075}
12076
12077template <typename Derived>
12078OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
12079 OMPDistScheduleClause *C) {
12080 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
12081 if (E.isInvalid())
12082 return nullptr;
12083 return getDerived().RebuildOMPDistScheduleClause(
12084 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
12085 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
12086}
12087
12088template <typename Derived>
12089OMPClause *
12090TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
12091 // Rebuild Defaultmap Clause since we need to invoke the checking of
12092 // defaultmap(none:variable-category) after template initialization.
12093 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
12094 C->getDefaultmapKind(),
12095 C->getBeginLoc(),
12096 C->getLParenLoc(),
12097 C->getDefaultmapModifierLoc(),
12098 C->getDefaultmapKindLoc(),
12099 C->getEndLoc());
12100}
12101
12102template <typename Derived>
12103OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
12104 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12105 llvm::SmallVector<Expr *, 16> Vars;
12106 Expr *IteratorModifier = C->getIteratorModifier();
12107 if (IteratorModifier) {
12108 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12109 if (MapModRes.isInvalid())
12110 return nullptr;
12111 IteratorModifier = MapModRes.get();
12112 }
12113 CXXScopeSpec MapperIdScopeSpec;
12114 DeclarationNameInfo MapperIdInfo;
12115 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12116 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
12117 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12118 return nullptr;
12119 return getDerived().RebuildOMPToClause(
12120 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12121 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12122 UnresolvedMappers);
12123}
12124
12125template <typename Derived>
12126OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
12127 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12128 llvm::SmallVector<Expr *, 16> Vars;
12129 Expr *IteratorModifier = C->getIteratorModifier();
12130 if (IteratorModifier) {
12131 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
12132 if (MapModRes.isInvalid())
12133 return nullptr;
12134 IteratorModifier = MapModRes.get();
12135 }
12136 CXXScopeSpec MapperIdScopeSpec;
12137 DeclarationNameInfo MapperIdInfo;
12138 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
12139 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
12140 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
12141 return nullptr;
12142 return getDerived().RebuildOMPFromClause(
12143 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
12144 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
12145 UnresolvedMappers);
12146}
12147
12148template <typename Derived>
12149OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
12150 OMPUseDevicePtrClause *C) {
12151 llvm::SmallVector<Expr *, 16> Vars;
12152 Vars.reserve(N: C->varlist_size());
12153 for (auto *VE : C->varlist()) {
12154 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12155 if (EVar.isInvalid())
12156 return nullptr;
12157 Vars.push_back(Elt: EVar.get());
12158 }
12159 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12160 return getDerived().RebuildOMPUseDevicePtrClause(
12161 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
12162}
12163
12164template <typename Derived>
12165OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
12166 OMPUseDeviceAddrClause *C) {
12167 llvm::SmallVector<Expr *, 16> Vars;
12168 Vars.reserve(N: C->varlist_size());
12169 for (auto *VE : C->varlist()) {
12170 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12171 if (EVar.isInvalid())
12172 return nullptr;
12173 Vars.push_back(Elt: EVar.get());
12174 }
12175 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12176 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
12177}
12178
12179template <typename Derived>
12180OMPClause *
12181TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
12182 llvm::SmallVector<Expr *, 16> Vars;
12183 Vars.reserve(N: C->varlist_size());
12184 for (auto *VE : C->varlist()) {
12185 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12186 if (EVar.isInvalid())
12187 return nullptr;
12188 Vars.push_back(Elt: EVar.get());
12189 }
12190 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12191 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
12192}
12193
12194template <typename Derived>
12195OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
12196 OMPHasDeviceAddrClause *C) {
12197 llvm::SmallVector<Expr *, 16> Vars;
12198 Vars.reserve(N: C->varlist_size());
12199 for (auto *VE : C->varlist()) {
12200 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12201 if (EVar.isInvalid())
12202 return nullptr;
12203 Vars.push_back(Elt: EVar.get());
12204 }
12205 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12206 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
12207}
12208
12209template <typename Derived>
12210OMPClause *
12211TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
12212 llvm::SmallVector<Expr *, 16> Vars;
12213 Vars.reserve(N: C->varlist_size());
12214 for (auto *VE : C->varlist()) {
12215 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12216 if (EVar.isInvalid())
12217 return nullptr;
12218 Vars.push_back(Elt: EVar.get());
12219 }
12220 return getDerived().RebuildOMPNontemporalClause(
12221 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12222}
12223
12224template <typename Derived>
12225OMPClause *
12226TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
12227 llvm::SmallVector<Expr *, 16> Vars;
12228 Vars.reserve(N: C->varlist_size());
12229 for (auto *VE : C->varlist()) {
12230 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12231 if (EVar.isInvalid())
12232 return nullptr;
12233 Vars.push_back(Elt: EVar.get());
12234 }
12235 return getDerived().RebuildOMPInclusiveClause(
12236 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12237}
12238
12239template <typename Derived>
12240OMPClause *
12241TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
12242 llvm::SmallVector<Expr *, 16> Vars;
12243 Vars.reserve(N: C->varlist_size());
12244 for (auto *VE : C->varlist()) {
12245 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12246 if (EVar.isInvalid())
12247 return nullptr;
12248 Vars.push_back(Elt: EVar.get());
12249 }
12250 return getDerived().RebuildOMPExclusiveClause(
12251 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12252}
12253
12254template <typename Derived>
12255OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
12256 OMPUsesAllocatorsClause *C) {
12257 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
12258 Data.reserve(N: C->getNumberOfAllocators());
12259 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
12260 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
12261 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
12262 if (Allocator.isInvalid())
12263 continue;
12264 ExprResult AllocatorTraits;
12265 if (Expr *AT = D.AllocatorTraits) {
12266 AllocatorTraits = getDerived().TransformExpr(AT);
12267 if (AllocatorTraits.isInvalid())
12268 continue;
12269 }
12270 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
12271 NewD.Allocator = Allocator.get();
12272 NewD.AllocatorTraits = AllocatorTraits.get();
12273 NewD.LParenLoc = D.LParenLoc;
12274 NewD.RParenLoc = D.RParenLoc;
12275 }
12276 return getDerived().RebuildOMPUsesAllocatorsClause(
12277 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12278}
12279
12280template <typename Derived>
12281OMPClause *
12282TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
12283 SmallVector<Expr *, 4> Locators;
12284 Locators.reserve(N: C->varlist_size());
12285 ExprResult ModifierRes;
12286 if (Expr *Modifier = C->getModifier()) {
12287 ModifierRes = getDerived().TransformExpr(Modifier);
12288 if (ModifierRes.isInvalid())
12289 return nullptr;
12290 }
12291 for (Expr *E : C->varlist()) {
12292 ExprResult Locator = getDerived().TransformExpr(E);
12293 if (Locator.isInvalid())
12294 continue;
12295 Locators.push_back(Elt: Locator.get());
12296 }
12297 return getDerived().RebuildOMPAffinityClause(
12298 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
12299 ModifierRes.get(), Locators);
12300}
12301
12302template <typename Derived>
12303OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
12304 return getDerived().RebuildOMPOrderClause(
12305 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
12306 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
12307}
12308
12309template <typename Derived>
12310OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
12311 return getDerived().RebuildOMPBindClause(
12312 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
12313 C->getLParenLoc(), C->getEndLoc());
12314}
12315
12316template <typename Derived>
12317OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
12318 OMPXDynCGroupMemClause *C) {
12319 ExprResult Size = getDerived().TransformExpr(C->getSize());
12320 if (Size.isInvalid())
12321 return nullptr;
12322 return getDerived().RebuildOMPXDynCGroupMemClause(
12323 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12324}
12325
12326template <typename Derived>
12327OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
12328 OMPDynGroupprivateClause *C) {
12329 ExprResult Size = getDerived().TransformExpr(C->getSize());
12330 if (Size.isInvalid())
12331 return nullptr;
12332 return getDerived().RebuildOMPDynGroupprivateClause(
12333 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
12334 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
12335 C->getDynGroupprivateModifierLoc(),
12336 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
12337}
12338
12339template <typename Derived>
12340OMPClause *
12341TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
12342 llvm::SmallVector<Expr *, 16> Vars;
12343 Vars.reserve(N: C->varlist_size());
12344 for (auto *VE : C->varlist()) {
12345 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12346 if (EVar.isInvalid())
12347 return nullptr;
12348 Vars.push_back(Elt: EVar.get());
12349 }
12350 return getDerived().RebuildOMPDoacrossClause(
12351 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
12352 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12353}
12354
12355template <typename Derived>
12356OMPClause *
12357TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
12358 SmallVector<const Attr *> NewAttrs;
12359 for (auto *A : C->getAttrs())
12360 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
12361 return getDerived().RebuildOMPXAttributeClause(
12362 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12363}
12364
12365template <typename Derived>
12366OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
12367 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
12368}
12369
12370//===----------------------------------------------------------------------===//
12371// OpenACC transformation
12372//===----------------------------------------------------------------------===//
12373namespace {
12374template <typename Derived>
12375class OpenACCClauseTransform final
12376 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
12377 TreeTransform<Derived> &Self;
12378 ArrayRef<const OpenACCClause *> ExistingClauses;
12379 SemaOpenACC::OpenACCParsedClause &ParsedClause;
12380 OpenACCClause *NewClause = nullptr;
12381
12382 ExprResult VisitVar(Expr *VarRef) {
12383 ExprResult Res = Self.TransformExpr(VarRef);
12384
12385 if (!Res.isUsable())
12386 return Res;
12387
12388 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12389 ParsedClause.getClauseKind(),
12390 Res.get());
12391
12392 return Res;
12393 }
12394
12395 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
12396 llvm::SmallVector<Expr *> InstantiatedVarList;
12397 for (Expr *CurVar : VarList) {
12398 ExprResult VarRef = VisitVar(VarRef: CurVar);
12399
12400 if (VarRef.isUsable())
12401 InstantiatedVarList.push_back(Elt: VarRef.get());
12402 }
12403
12404 return InstantiatedVarList;
12405 }
12406
12407public:
12408 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12409 ArrayRef<const OpenACCClause *> ExistingClauses,
12410 SemaOpenACC::OpenACCParsedClause &PC)
12411 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12412
12413 OpenACCClause *CreatedClause() const { return NewClause; }
12414
12415#define VISIT_CLAUSE(CLAUSE_NAME) \
12416 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12417#include "clang/Basic/OpenACCClauses.def"
12418};
12419
12420template <typename Derived>
12421void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12422 const OpenACCDefaultClause &C) {
12423 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12424
12425 NewClause = OpenACCDefaultClause::Create(
12426 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12427 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12428 EndLoc: ParsedClause.getEndLoc());
12429}
12430
12431template <typename Derived>
12432void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12433 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12434 assert(Cond && "If constructed with invalid Condition");
12435 Sema::ConditionResult Res = Self.TransformCondition(
12436 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12437
12438 if (Res.isInvalid() || !Res.get().second)
12439 return;
12440
12441 ParsedClause.setConditionDetails(Res.get().second);
12442
12443 NewClause = OpenACCIfClause::Create(
12444 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12445 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12446 EndLoc: ParsedClause.getEndLoc());
12447}
12448
12449template <typename Derived>
12450void OpenACCClauseTransform<Derived>::VisitSelfClause(
12451 const OpenACCSelfClause &C) {
12452
12453 // If this is an 'update' 'self' clause, this is actually a var list instead.
12454 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12455 llvm::SmallVector<Expr *> InstantiatedVarList;
12456 for (Expr *CurVar : C.getVarList()) {
12457 ExprResult Res = Self.TransformExpr(CurVar);
12458
12459 if (!Res.isUsable())
12460 continue;
12461
12462 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12463 ParsedClause.getClauseKind(),
12464 Res.get());
12465
12466 if (Res.isUsable())
12467 InstantiatedVarList.push_back(Elt: Res.get());
12468 }
12469
12470 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12471 ModKind: OpenACCModifierKind::Invalid);
12472
12473 NewClause = OpenACCSelfClause::Create(
12474 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12475 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12476 ParsedClause.getEndLoc());
12477 } else {
12478
12479 if (C.hasConditionExpr()) {
12480 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12481 Sema::ConditionResult Res =
12482 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12483 Sema::ConditionKind::Boolean);
12484
12485 if (Res.isInvalid() || !Res.get().second)
12486 return;
12487
12488 ParsedClause.setConditionDetails(Res.get().second);
12489 }
12490
12491 NewClause = OpenACCSelfClause::Create(
12492 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12493 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12494 ParsedClause.getEndLoc());
12495 }
12496}
12497
12498template <typename Derived>
12499void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12500 const OpenACCNumGangsClause &C) {
12501 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12502
12503 for (Expr *CurIntExpr : C.getIntExprs()) {
12504 ExprResult Res = Self.TransformExpr(CurIntExpr);
12505
12506 if (!Res.isUsable())
12507 return;
12508
12509 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12510 C.getClauseKind(),
12511 C.getBeginLoc(), Res.get());
12512 if (!Res.isUsable())
12513 return;
12514
12515 InstantiatedIntExprs.push_back(Elt: Res.get());
12516 }
12517
12518 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12519 NewClause = OpenACCNumGangsClause::Create(
12520 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12521 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12522 EndLoc: ParsedClause.getEndLoc());
12523}
12524
12525template <typename Derived>
12526void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12527 const OpenACCPrivateClause &C) {
12528 llvm::SmallVector<Expr *> InstantiatedVarList;
12529 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12530
12531 for (const auto [RefExpr, InitRecipe] :
12532 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12533 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12534
12535 if (VarRef.isUsable()) {
12536 InstantiatedVarList.push_back(Elt: VarRef.get());
12537
12538 // We only have to create a new one if it is dependent, and Sema won't
12539 // make one of these unless the type is non-dependent.
12540 if (InitRecipe.isSet())
12541 InitRecipes.push_back(Elt: InitRecipe);
12542 else
12543 InitRecipes.push_back(
12544 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12545 }
12546 }
12547 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12548 ModKind: OpenACCModifierKind::Invalid);
12549
12550 NewClause = OpenACCPrivateClause::Create(
12551 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12552 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12553 EndLoc: ParsedClause.getEndLoc());
12554}
12555
12556template <typename Derived>
12557void OpenACCClauseTransform<Derived>::VisitHostClause(
12558 const OpenACCHostClause &C) {
12559 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12560 OpenACCModifierKind::Invalid);
12561
12562 NewClause = OpenACCHostClause::Create(
12563 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12564 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12565 EndLoc: ParsedClause.getEndLoc());
12566}
12567
12568template <typename Derived>
12569void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12570 const OpenACCDeviceClause &C) {
12571 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12572 OpenACCModifierKind::Invalid);
12573
12574 NewClause = OpenACCDeviceClause::Create(
12575 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12576 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12577 EndLoc: ParsedClause.getEndLoc());
12578}
12579
12580template <typename Derived>
12581void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12582 const OpenACCFirstPrivateClause &C) {
12583 llvm::SmallVector<Expr *> InstantiatedVarList;
12584 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12585
12586 for (const auto [RefExpr, InitRecipe] :
12587 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12588 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12589
12590 if (VarRef.isUsable()) {
12591 InstantiatedVarList.push_back(Elt: VarRef.get());
12592
12593 // We only have to create a new one if it is dependent, and Sema won't
12594 // make one of these unless the type is non-dependent.
12595 if (InitRecipe.isSet())
12596 InitRecipes.push_back(Elt: InitRecipe);
12597 else
12598 InitRecipes.push_back(
12599 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12600 VarRef.get()));
12601 }
12602 }
12603 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12604 ModKind: OpenACCModifierKind::Invalid);
12605
12606 NewClause = OpenACCFirstPrivateClause::Create(
12607 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12608 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12609 EndLoc: ParsedClause.getEndLoc());
12610}
12611
12612template <typename Derived>
12613void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12614 const OpenACCNoCreateClause &C) {
12615 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12616 OpenACCModifierKind::Invalid);
12617
12618 NewClause = OpenACCNoCreateClause::Create(
12619 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12620 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12621 EndLoc: ParsedClause.getEndLoc());
12622}
12623
12624template <typename Derived>
12625void OpenACCClauseTransform<Derived>::VisitPresentClause(
12626 const OpenACCPresentClause &C) {
12627 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12628 OpenACCModifierKind::Invalid);
12629
12630 NewClause = OpenACCPresentClause::Create(
12631 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12632 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12633 EndLoc: ParsedClause.getEndLoc());
12634}
12635
12636template <typename Derived>
12637void OpenACCClauseTransform<Derived>::VisitCopyClause(
12638 const OpenACCCopyClause &C) {
12639 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12640 C.getModifierList());
12641
12642 NewClause = OpenACCCopyClause::Create(
12643 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12644 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12645 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12646 EndLoc: ParsedClause.getEndLoc());
12647}
12648
12649template <typename Derived>
12650void OpenACCClauseTransform<Derived>::VisitLinkClause(
12651 const OpenACCLinkClause &C) {
12652 llvm_unreachable("link clause not valid unless a decl transform");
12653}
12654
12655template <typename Derived>
12656void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12657 const OpenACCDeviceResidentClause &C) {
12658 llvm_unreachable("device_resident clause not valid unless a decl transform");
12659}
12660template <typename Derived>
12661void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12662 const OpenACCNoHostClause &C) {
12663 llvm_unreachable("nohost clause not valid unless a decl transform");
12664}
12665template <typename Derived>
12666void OpenACCClauseTransform<Derived>::VisitBindClause(
12667 const OpenACCBindClause &C) {
12668 llvm_unreachable("bind clause not valid unless a decl transform");
12669}
12670
12671template <typename Derived>
12672void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12673 const OpenACCCopyInClause &C) {
12674 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12675 C.getModifierList());
12676
12677 NewClause = OpenACCCopyInClause::Create(
12678 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12679 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12680 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12681 EndLoc: ParsedClause.getEndLoc());
12682}
12683
12684template <typename Derived>
12685void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12686 const OpenACCCopyOutClause &C) {
12687 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12688 C.getModifierList());
12689
12690 NewClause = OpenACCCopyOutClause::Create(
12691 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12692 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12693 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12694 EndLoc: ParsedClause.getEndLoc());
12695}
12696
12697template <typename Derived>
12698void OpenACCClauseTransform<Derived>::VisitCreateClause(
12699 const OpenACCCreateClause &C) {
12700 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12701 C.getModifierList());
12702
12703 NewClause = OpenACCCreateClause::Create(
12704 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12705 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12706 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12707 EndLoc: ParsedClause.getEndLoc());
12708}
12709template <typename Derived>
12710void OpenACCClauseTransform<Derived>::VisitAttachClause(
12711 const OpenACCAttachClause &C) {
12712 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12713
12714 // Ensure each var is a pointer type.
12715 llvm::erase_if(VarList, [&](Expr *E) {
12716 return Self.getSema().OpenACC().CheckVarIsPointerType(
12717 OpenACCClauseKind::Attach, E);
12718 });
12719
12720 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12721 NewClause = OpenACCAttachClause::Create(
12722 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12723 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12724 EndLoc: ParsedClause.getEndLoc());
12725}
12726
12727template <typename Derived>
12728void OpenACCClauseTransform<Derived>::VisitDetachClause(
12729 const OpenACCDetachClause &C) {
12730 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12731
12732 // Ensure each var is a pointer type.
12733 llvm::erase_if(VarList, [&](Expr *E) {
12734 return Self.getSema().OpenACC().CheckVarIsPointerType(
12735 OpenACCClauseKind::Detach, E);
12736 });
12737
12738 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12739 NewClause = OpenACCDetachClause::Create(
12740 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12741 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12742 EndLoc: ParsedClause.getEndLoc());
12743}
12744
12745template <typename Derived>
12746void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12747 const OpenACCDeleteClause &C) {
12748 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12749 OpenACCModifierKind::Invalid);
12750 NewClause = OpenACCDeleteClause::Create(
12751 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12752 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12753 EndLoc: ParsedClause.getEndLoc());
12754}
12755
12756template <typename Derived>
12757void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12758 const OpenACCUseDeviceClause &C) {
12759 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12760 OpenACCModifierKind::Invalid);
12761 NewClause = OpenACCUseDeviceClause::Create(
12762 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12763 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12764 EndLoc: ParsedClause.getEndLoc());
12765}
12766
12767template <typename Derived>
12768void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12769 const OpenACCDevicePtrClause &C) {
12770 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12771
12772 // Ensure each var is a pointer type.
12773 llvm::erase_if(VarList, [&](Expr *E) {
12774 return Self.getSema().OpenACC().CheckVarIsPointerType(
12775 OpenACCClauseKind::DevicePtr, E);
12776 });
12777
12778 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12779 NewClause = OpenACCDevicePtrClause::Create(
12780 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12781 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12782 EndLoc: ParsedClause.getEndLoc());
12783}
12784
12785template <typename Derived>
12786void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12787 const OpenACCNumWorkersClause &C) {
12788 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12789 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12790
12791 ExprResult Res = Self.TransformExpr(IntExpr);
12792 if (!Res.isUsable())
12793 return;
12794
12795 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12796 C.getClauseKind(),
12797 C.getBeginLoc(), Res.get());
12798 if (!Res.isUsable())
12799 return;
12800
12801 ParsedClause.setIntExprDetails(Res.get());
12802 NewClause = OpenACCNumWorkersClause::Create(
12803 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12804 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12805 EndLoc: ParsedClause.getEndLoc());
12806}
12807
12808template <typename Derived>
12809void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12810 const OpenACCDeviceNumClause &C) {
12811 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12812 assert(IntExpr && "device_num clause constructed with invalid int expr");
12813
12814 ExprResult Res = Self.TransformExpr(IntExpr);
12815 if (!Res.isUsable())
12816 return;
12817
12818 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12819 C.getClauseKind(),
12820 C.getBeginLoc(), Res.get());
12821 if (!Res.isUsable())
12822 return;
12823
12824 ParsedClause.setIntExprDetails(Res.get());
12825 NewClause = OpenACCDeviceNumClause::Create(
12826 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12827 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12828 EndLoc: ParsedClause.getEndLoc());
12829}
12830
12831template <typename Derived>
12832void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12833 const OpenACCDefaultAsyncClause &C) {
12834 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12835 assert(IntExpr && "default_async clause constructed with invalid int expr");
12836
12837 ExprResult Res = Self.TransformExpr(IntExpr);
12838 if (!Res.isUsable())
12839 return;
12840
12841 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12842 C.getClauseKind(),
12843 C.getBeginLoc(), Res.get());
12844 if (!Res.isUsable())
12845 return;
12846
12847 ParsedClause.setIntExprDetails(Res.get());
12848 NewClause = OpenACCDefaultAsyncClause::Create(
12849 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12850 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12851 EndLoc: ParsedClause.getEndLoc());
12852}
12853
12854template <typename Derived>
12855void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12856 const OpenACCVectorLengthClause &C) {
12857 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12858 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12859
12860 ExprResult Res = Self.TransformExpr(IntExpr);
12861 if (!Res.isUsable())
12862 return;
12863
12864 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12865 C.getClauseKind(),
12866 C.getBeginLoc(), Res.get());
12867 if (!Res.isUsable())
12868 return;
12869
12870 ParsedClause.setIntExprDetails(Res.get());
12871 NewClause = OpenACCVectorLengthClause::Create(
12872 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12873 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12874 EndLoc: ParsedClause.getEndLoc());
12875}
12876
12877template <typename Derived>
12878void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12879 const OpenACCAsyncClause &C) {
12880 if (C.hasIntExpr()) {
12881 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12882 if (!Res.isUsable())
12883 return;
12884
12885 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12886 C.getClauseKind(),
12887 C.getBeginLoc(), Res.get());
12888 if (!Res.isUsable())
12889 return;
12890 ParsedClause.setIntExprDetails(Res.get());
12891 }
12892
12893 NewClause = OpenACCAsyncClause::Create(
12894 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12895 LParenLoc: ParsedClause.getLParenLoc(),
12896 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12897 : nullptr,
12898 EndLoc: ParsedClause.getEndLoc());
12899}
12900
12901template <typename Derived>
12902void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12903 const OpenACCWorkerClause &C) {
12904 if (C.hasIntExpr()) {
12905 // restrictions on this expression are all "does it exist in certain
12906 // situations" that are not possible to be dependent, so the only check we
12907 // have is that it transforms, and is an int expression.
12908 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12909 if (!Res.isUsable())
12910 return;
12911
12912 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12913 C.getClauseKind(),
12914 C.getBeginLoc(), Res.get());
12915 if (!Res.isUsable())
12916 return;
12917 ParsedClause.setIntExprDetails(Res.get());
12918 }
12919
12920 NewClause = OpenACCWorkerClause::Create(
12921 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12922 LParenLoc: ParsedClause.getLParenLoc(),
12923 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12924 : nullptr,
12925 EndLoc: ParsedClause.getEndLoc());
12926}
12927
12928template <typename Derived>
12929void OpenACCClauseTransform<Derived>::VisitVectorClause(
12930 const OpenACCVectorClause &C) {
12931 if (C.hasIntExpr()) {
12932 // restrictions on this expression are all "does it exist in certain
12933 // situations" that are not possible to be dependent, so the only check we
12934 // have is that it transforms, and is an int expression.
12935 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12936 if (!Res.isUsable())
12937 return;
12938
12939 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12940 C.getClauseKind(),
12941 C.getBeginLoc(), Res.get());
12942 if (!Res.isUsable())
12943 return;
12944 ParsedClause.setIntExprDetails(Res.get());
12945 }
12946
12947 NewClause = OpenACCVectorClause::Create(
12948 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12949 LParenLoc: ParsedClause.getLParenLoc(),
12950 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12951 : nullptr,
12952 EndLoc: ParsedClause.getEndLoc());
12953}
12954
12955template <typename Derived>
12956void OpenACCClauseTransform<Derived>::VisitWaitClause(
12957 const OpenACCWaitClause &C) {
12958 if (C.hasExprs()) {
12959 Expr *DevNumExpr = nullptr;
12960 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12961
12962 // Instantiate devnum expr if it exists.
12963 if (C.getDevNumExpr()) {
12964 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12965 if (!Res.isUsable())
12966 return;
12967 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12968 C.getClauseKind(),
12969 C.getBeginLoc(), Res.get());
12970 if (!Res.isUsable())
12971 return;
12972
12973 DevNumExpr = Res.get();
12974 }
12975
12976 // Instantiate queue ids.
12977 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12978 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12979 if (!Res.isUsable())
12980 return;
12981 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12982 C.getClauseKind(),
12983 C.getBeginLoc(), Res.get());
12984 if (!Res.isUsable())
12985 return;
12986
12987 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12988 }
12989
12990 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12991 IntExprs: std::move(InstantiatedQueueIdExprs));
12992 }
12993
12994 NewClause = OpenACCWaitClause::Create(
12995 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12996 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12997 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12998 EndLoc: ParsedClause.getEndLoc());
12999}
13000
13001template <typename Derived>
13002void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
13003 const OpenACCDeviceTypeClause &C) {
13004 // Nothing to transform here, just create a new version of 'C'.
13005 NewClause = OpenACCDeviceTypeClause::Create(
13006 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
13007 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
13008 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
13009}
13010
13011template <typename Derived>
13012void OpenACCClauseTransform<Derived>::VisitAutoClause(
13013 const OpenACCAutoClause &C) {
13014 // Nothing to do, so just create a new node.
13015 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
13016 BeginLoc: ParsedClause.getBeginLoc(),
13017 EndLoc: ParsedClause.getEndLoc());
13018}
13019
13020template <typename Derived>
13021void OpenACCClauseTransform<Derived>::VisitIndependentClause(
13022 const OpenACCIndependentClause &C) {
13023 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
13024 BeginLoc: ParsedClause.getBeginLoc(),
13025 EndLoc: ParsedClause.getEndLoc());
13026}
13027
13028template <typename Derived>
13029void OpenACCClauseTransform<Derived>::VisitSeqClause(
13030 const OpenACCSeqClause &C) {
13031 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
13032 BeginLoc: ParsedClause.getBeginLoc(),
13033 EndLoc: ParsedClause.getEndLoc());
13034}
13035template <typename Derived>
13036void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
13037 const OpenACCFinalizeClause &C) {
13038 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
13039 BeginLoc: ParsedClause.getBeginLoc(),
13040 EndLoc: ParsedClause.getEndLoc());
13041}
13042
13043template <typename Derived>
13044void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
13045 const OpenACCIfPresentClause &C) {
13046 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
13047 BeginLoc: ParsedClause.getBeginLoc(),
13048 EndLoc: ParsedClause.getEndLoc());
13049}
13050
13051template <typename Derived>
13052void OpenACCClauseTransform<Derived>::VisitReductionClause(
13053 const OpenACCReductionClause &C) {
13054 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
13055 SmallVector<Expr *> ValidVars;
13056 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
13057
13058 for (const auto [Var, OrigRecipe] :
13059 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
13060 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
13061 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
13062 if (Res.isUsable()) {
13063 ValidVars.push_back(Elt: Res.get());
13064
13065 if (OrigRecipe.isSet())
13066 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
13067 else
13068 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
13069 C.getReductionOp(), Res.get()));
13070 }
13071 }
13072
13073 NewClause = Self.getSema().OpenACC().CheckReductionClause(
13074 ExistingClauses, ParsedClause.getDirectiveKind(),
13075 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13076 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
13077}
13078
13079template <typename Derived>
13080void OpenACCClauseTransform<Derived>::VisitCollapseClause(
13081 const OpenACCCollapseClause &C) {
13082 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
13083 assert(LoopCount && "collapse clause constructed with invalid loop count");
13084
13085 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
13086
13087 if (!NewLoopCount.isUsable())
13088 return;
13089
13090 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
13091 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13092 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
13093
13094 // FIXME: It isn't clear whether this is properly tested here, we should
13095 // probably see if we can come up with a test for this.
13096 if (!NewLoopCount.isUsable())
13097 return;
13098
13099 NewLoopCount =
13100 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
13101
13102 // FIXME: It isn't clear whether this is properly tested here, we should
13103 // probably see if we can come up with a test for this.
13104 if (!NewLoopCount.isUsable())
13105 return;
13106
13107 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
13108 NewClause = OpenACCCollapseClause::Create(
13109 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13110 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
13111 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
13112}
13113
13114template <typename Derived>
13115void OpenACCClauseTransform<Derived>::VisitTileClause(
13116 const OpenACCTileClause &C) {
13117
13118 llvm::SmallVector<Expr *> TransformedExprs;
13119
13120 for (Expr *E : C.getSizeExprs()) {
13121 ExprResult NewSizeExpr = Self.TransformExpr(E);
13122
13123 if (!NewSizeExpr.isUsable())
13124 return;
13125
13126 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
13127 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
13128 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
13129
13130 // FIXME: It isn't clear whether this is properly tested here, we should
13131 // probably see if we can come up with a test for this.
13132 if (!NewSizeExpr.isUsable())
13133 return;
13134
13135 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
13136
13137 if (!NewSizeExpr.isUsable())
13138 return;
13139 TransformedExprs.push_back(Elt: NewSizeExpr.get());
13140 }
13141
13142 ParsedClause.setIntExprDetails(TransformedExprs);
13143 NewClause = OpenACCTileClause::Create(
13144 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
13145 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
13146 EndLoc: ParsedClause.getEndLoc());
13147}
13148template <typename Derived>
13149void OpenACCClauseTransform<Derived>::VisitGangClause(
13150 const OpenACCGangClause &C) {
13151 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
13152 llvm::SmallVector<Expr *> TransformedIntExprs;
13153
13154 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
13155 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
13156 if (!ER.isUsable())
13157 continue;
13158
13159 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
13160 ParsedClause.getDirectiveKind(),
13161 C.getExpr(I).first, ER.get());
13162 if (!ER.isUsable())
13163 continue;
13164 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
13165 TransformedIntExprs.push_back(Elt: ER.get());
13166 }
13167
13168 NewClause = Self.getSema().OpenACC().CheckGangClause(
13169 ParsedClause.getDirectiveKind(), ExistingClauses,
13170 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
13171 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
13172}
13173} // namespace
13174template <typename Derived>
13175OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
13176 ArrayRef<const OpenACCClause *> ExistingClauses,
13177 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
13178
13179 SemaOpenACC::OpenACCParsedClause ParsedClause(
13180 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
13181 ParsedClause.setEndLoc(OldClause->getEndLoc());
13182
13183 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
13184 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
13185
13186 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
13187 ParsedClause};
13188 Transform.Visit(OldClause);
13189
13190 return Transform.CreatedClause();
13191}
13192
13193template <typename Derived>
13194llvm::SmallVector<OpenACCClause *>
13195TreeTransform<Derived>::TransformOpenACCClauseList(
13196 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
13197 llvm::SmallVector<OpenACCClause *> TransformedClauses;
13198 for (const auto *Clause : OldClauses) {
13199 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
13200 TransformedClauses, DirKind, Clause))
13201 TransformedClauses.push_back(Elt: TransformedClause);
13202 }
13203 return TransformedClauses;
13204}
13205
13206template <typename Derived>
13207StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
13208 OpenACCComputeConstruct *C) {
13209 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13210
13211 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13212 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13213 C->clauses());
13214
13215 if (getSema().OpenACC().ActOnStartStmtDirective(
13216 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13217 return StmtError();
13218
13219 // Transform Structured Block.
13220 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13221 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13222 C->clauses(), TransformedClauses);
13223 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13224 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13225 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13226
13227 return getDerived().RebuildOpenACCComputeConstruct(
13228 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13229 C->getEndLoc(), TransformedClauses, StrBlock);
13230}
13231
13232template <typename Derived>
13233StmtResult
13234TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
13235
13236 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13237
13238 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13239 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13240 C->clauses());
13241
13242 if (getSema().OpenACC().ActOnStartStmtDirective(
13243 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13244 return StmtError();
13245
13246 // Transform Loop.
13247 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13248 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13249 C->clauses(), TransformedClauses);
13250 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13251 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13252 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13253
13254 return getDerived().RebuildOpenACCLoopConstruct(
13255 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13256 TransformedClauses, Loop);
13257}
13258
13259template <typename Derived>
13260StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
13261 OpenACCCombinedConstruct *C) {
13262 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13263
13264 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13265 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13266 C->clauses());
13267
13268 if (getSema().OpenACC().ActOnStartStmtDirective(
13269 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13270 return StmtError();
13271
13272 // Transform Loop.
13273 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13274 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13275 C->clauses(), TransformedClauses);
13276 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13277 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13278 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13279
13280 return getDerived().RebuildOpenACCCombinedConstruct(
13281 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13282 C->getEndLoc(), TransformedClauses, Loop);
13283}
13284
13285template <typename Derived>
13286StmtResult
13287TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
13288 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13289
13290 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13291 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13292 C->clauses());
13293 if (getSema().OpenACC().ActOnStartStmtDirective(
13294 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13295 return StmtError();
13296
13297 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13298 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13299 C->clauses(), TransformedClauses);
13300 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13301 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13302 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13303
13304 return getDerived().RebuildOpenACCDataConstruct(
13305 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13306 TransformedClauses, StrBlock);
13307}
13308
13309template <typename Derived>
13310StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
13311 OpenACCEnterDataConstruct *C) {
13312 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13313
13314 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13315 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13316 C->clauses());
13317 if (getSema().OpenACC().ActOnStartStmtDirective(
13318 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13319 return StmtError();
13320
13321 return getDerived().RebuildOpenACCEnterDataConstruct(
13322 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13323 TransformedClauses);
13324}
13325
13326template <typename Derived>
13327StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
13328 OpenACCExitDataConstruct *C) {
13329 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13330
13331 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13332 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13333 C->clauses());
13334 if (getSema().OpenACC().ActOnStartStmtDirective(
13335 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13336 return StmtError();
13337
13338 return getDerived().RebuildOpenACCExitDataConstruct(
13339 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13340 TransformedClauses);
13341}
13342
13343template <typename Derived>
13344StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
13345 OpenACCHostDataConstruct *C) {
13346 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13347
13348 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13349 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13350 C->clauses());
13351 if (getSema().OpenACC().ActOnStartStmtDirective(
13352 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13353 return StmtError();
13354
13355 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13356 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13357 C->clauses(), TransformedClauses);
13358 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13359 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13360 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13361
13362 return getDerived().RebuildOpenACCHostDataConstruct(
13363 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13364 TransformedClauses, StrBlock);
13365}
13366
13367template <typename Derived>
13368StmtResult
13369TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
13370 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13371
13372 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13373 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13374 C->clauses());
13375 if (getSema().OpenACC().ActOnStartStmtDirective(
13376 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13377 return StmtError();
13378
13379 return getDerived().RebuildOpenACCInitConstruct(
13380 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13381 TransformedClauses);
13382}
13383
13384template <typename Derived>
13385StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
13386 OpenACCShutdownConstruct *C) {
13387 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13388
13389 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13390 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13391 C->clauses());
13392 if (getSema().OpenACC().ActOnStartStmtDirective(
13393 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13394 return StmtError();
13395
13396 return getDerived().RebuildOpenACCShutdownConstruct(
13397 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13398 TransformedClauses);
13399}
13400template <typename Derived>
13401StmtResult
13402TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
13403 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13404
13405 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13406 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13407 C->clauses());
13408 if (getSema().OpenACC().ActOnStartStmtDirective(
13409 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13410 return StmtError();
13411
13412 return getDerived().RebuildOpenACCSetConstruct(
13413 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13414 TransformedClauses);
13415}
13416
13417template <typename Derived>
13418StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13419 OpenACCUpdateConstruct *C) {
13420 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13421
13422 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13423 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13424 C->clauses());
13425 if (getSema().OpenACC().ActOnStartStmtDirective(
13426 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13427 return StmtError();
13428
13429 return getDerived().RebuildOpenACCUpdateConstruct(
13430 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13431 TransformedClauses);
13432}
13433
13434template <typename Derived>
13435StmtResult
13436TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13437 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13438
13439 ExprResult DevNumExpr;
13440 if (C->hasDevNumExpr()) {
13441 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13442
13443 if (DevNumExpr.isUsable())
13444 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13445 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13446 C->getBeginLoc(), DevNumExpr.get());
13447 }
13448
13449 llvm::SmallVector<Expr *> QueueIdExprs;
13450
13451 for (Expr *QE : C->getQueueIdExprs()) {
13452 assert(QE && "Null queue id expr?");
13453 ExprResult NewEQ = getDerived().TransformExpr(QE);
13454
13455 if (!NewEQ.isUsable())
13456 break;
13457 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13458 OpenACCClauseKind::Invalid,
13459 C->getBeginLoc(), NewEQ.get());
13460 if (NewEQ.isUsable())
13461 QueueIdExprs.push_back(Elt: NewEQ.get());
13462 }
13463
13464 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13465 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13466 C->clauses());
13467
13468 if (getSema().OpenACC().ActOnStartStmtDirective(
13469 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13470 return StmtError();
13471
13472 return getDerived().RebuildOpenACCWaitConstruct(
13473 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13474 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13475 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13476}
13477template <typename Derived>
13478StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13479 OpenACCCacheConstruct *C) {
13480 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13481
13482 llvm::SmallVector<Expr *> TransformedVarList;
13483 for (Expr *Var : C->getVarList()) {
13484 assert(Var && "Null var listexpr?");
13485
13486 ExprResult NewVar = getDerived().TransformExpr(Var);
13487
13488 if (!NewVar.isUsable())
13489 break;
13490
13491 NewVar = getSema().OpenACC().ActOnVar(
13492 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13493 if (!NewVar.isUsable())
13494 break;
13495
13496 TransformedVarList.push_back(Elt: NewVar.get());
13497 }
13498
13499 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13500 C->getBeginLoc(), {}))
13501 return StmtError();
13502
13503 return getDerived().RebuildOpenACCCacheConstruct(
13504 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13505 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13506 C->getEndLoc());
13507}
13508
13509template <typename Derived>
13510StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13511 OpenACCAtomicConstruct *C) {
13512 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13513
13514 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13515 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13516 C->clauses());
13517
13518 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13519 C->getBeginLoc(), {}))
13520 return StmtError();
13521
13522 // Transform Associated Stmt.
13523 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13524 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13525
13526 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13527 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13528 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13529 AssocStmt);
13530
13531 return getDerived().RebuildOpenACCAtomicConstruct(
13532 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13533 C->getEndLoc(), TransformedClauses, AssocStmt);
13534}
13535
13536template <typename Derived>
13537ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13538 OpenACCAsteriskSizeExpr *E) {
13539 if (getDerived().AlwaysRebuild())
13540 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13541 // Nothing can ever change, so there is never anything to transform.
13542 return E;
13543}
13544
13545//===----------------------------------------------------------------------===//
13546// Expression transformation
13547//===----------------------------------------------------------------------===//
13548template<typename Derived>
13549ExprResult
13550TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13551 return TransformExpr(E: E->getSubExpr());
13552}
13553
13554template <typename Derived>
13555ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13556 SYCLUniqueStableNameExpr *E) {
13557 if (!E->isTypeDependent())
13558 return E;
13559
13560 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13561
13562 if (!NewT)
13563 return ExprError();
13564
13565 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13566 return E;
13567
13568 return getDerived().RebuildSYCLUniqueStableNameExpr(
13569 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13570}
13571
13572template <typename Derived>
13573StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13574 UnresolvedSYCLKernelCallStmt *S) {
13575 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13576 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13577 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13578 return StmtError();
13579
13580 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13581 if (IdExpr.isInvalid())
13582 return StmtError();
13583
13584 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13585 if (Body.isInvalid())
13586 return StmtError();
13587
13588 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13589 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13590 LaunchIdExpr: IdExpr.get());
13591 if (SR.isInvalid())
13592 return StmtError();
13593
13594 return SR;
13595}
13596
13597template <typename Derived>
13598ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13599 // TODO(reflection): Implement its transform
13600 assert(false && "not implemented yet");
13601 return ExprError();
13602}
13603
13604template<typename Derived>
13605ExprResult
13606TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13607 if (!E->isTypeDependent())
13608 return E;
13609
13610 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13611 E->getIdentKind());
13612}
13613
13614template<typename Derived>
13615ExprResult
13616TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13617 NestedNameSpecifierLoc QualifierLoc;
13618 if (E->getQualifierLoc()) {
13619 QualifierLoc
13620 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13621 if (!QualifierLoc)
13622 return ExprError();
13623 }
13624
13625 ValueDecl *ND
13626 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13627 E->getDecl()));
13628 if (!ND || ND->isInvalidDecl())
13629 return ExprError();
13630
13631 NamedDecl *Found = ND;
13632 if (E->getFoundDecl() != E->getDecl()) {
13633 Found = cast_or_null<NamedDecl>(
13634 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13635 if (!Found)
13636 return ExprError();
13637 }
13638
13639 DeclarationNameInfo NameInfo = E->getNameInfo();
13640 if (NameInfo.getName()) {
13641 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13642 if (!NameInfo.getName())
13643 return ExprError();
13644 }
13645
13646 if (!getDerived().AlwaysRebuild() &&
13647 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13648 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13649 Found == E->getFoundDecl() &&
13650 NameInfo.getName() == E->getDecl()->getDeclName() &&
13651 !E->hasExplicitTemplateArgs()) {
13652
13653 // Mark it referenced in the new context regardless.
13654 // FIXME: this is a bit instantiation-specific.
13655 SemaRef.MarkDeclRefReferenced(E);
13656
13657 return E;
13658 }
13659
13660 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13661 if (E->hasExplicitTemplateArgs()) {
13662 TemplateArgs = &TransArgs;
13663 TransArgs.setLAngleLoc(E->getLAngleLoc());
13664 TransArgs.setRAngleLoc(E->getRAngleLoc());
13665 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13666 E->getNumTemplateArgs(),
13667 TransArgs))
13668 return ExprError();
13669 }
13670
13671 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13672 Found, TemplateArgs);
13673}
13674
13675template<typename Derived>
13676ExprResult
13677TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13678 return E;
13679}
13680
13681template <typename Derived>
13682ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13683 FixedPointLiteral *E) {
13684 return E;
13685}
13686
13687template<typename Derived>
13688ExprResult
13689TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13690 return E;
13691}
13692
13693template<typename Derived>
13694ExprResult
13695TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13696 return E;
13697}
13698
13699template<typename Derived>
13700ExprResult
13701TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13702 return E;
13703}
13704
13705template<typename Derived>
13706ExprResult
13707TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13708 return E;
13709}
13710
13711template<typename Derived>
13712ExprResult
13713TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13714 return getDerived().TransformCallExpr(E);
13715}
13716
13717template<typename Derived>
13718ExprResult
13719TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13720 ExprResult ControllingExpr;
13721 TypeSourceInfo *ControllingType = nullptr;
13722 if (E->isExprPredicate())
13723 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13724 else
13725 ControllingType = getDerived().TransformType(E->getControllingType());
13726
13727 if (ControllingExpr.isInvalid() && !ControllingType)
13728 return ExprError();
13729
13730 SmallVector<Expr *, 4> AssocExprs;
13731 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13732 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13733 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13734 if (TSI) {
13735 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13736 if (!AssocType)
13737 return ExprError();
13738 AssocTypes.push_back(Elt: AssocType);
13739 } else {
13740 AssocTypes.push_back(Elt: nullptr);
13741 }
13742
13743 ExprResult AssocExpr =
13744 getDerived().TransformExpr(Assoc.getAssociationExpr());
13745 if (AssocExpr.isInvalid())
13746 return ExprError();
13747 AssocExprs.push_back(Elt: AssocExpr.get());
13748 }
13749
13750 if (!ControllingType)
13751 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13752 E->getDefaultLoc(),
13753 E->getRParenLoc(),
13754 ControllingExpr.get(),
13755 AssocTypes,
13756 AssocExprs);
13757 return getDerived().RebuildGenericSelectionExpr(
13758 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13759 ControllingType, AssocTypes, AssocExprs);
13760}
13761
13762template<typename Derived>
13763ExprResult
13764TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13765 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13766 if (SubExpr.isInvalid())
13767 return ExprError();
13768
13769 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13770 return E;
13771
13772 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13773 E->getRParen());
13774}
13775
13776/// The operand of a unary address-of operator has special rules: it's
13777/// allowed to refer to a non-static member of a class even if there's no 'this'
13778/// object available.
13779template<typename Derived>
13780ExprResult
13781TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13782 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13783 return getDerived().TransformDependentScopeDeclRefExpr(
13784 DRE, /*IsAddressOfOperand=*/true, nullptr);
13785 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13786 return getDerived().TransformUnresolvedLookupExpr(
13787 ULE, /*IsAddressOfOperand=*/true);
13788 else
13789 return getDerived().TransformExpr(E);
13790}
13791
13792template<typename Derived>
13793ExprResult
13794TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13795 ExprResult SubExpr;
13796 if (E->getOpcode() == UO_AddrOf)
13797 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13798 else
13799 SubExpr = TransformExpr(E: E->getSubExpr());
13800 if (SubExpr.isInvalid())
13801 return ExprError();
13802
13803 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13804 return E;
13805
13806 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13807 E->getOpcode(),
13808 SubExpr.get());
13809}
13810
13811template<typename Derived>
13812ExprResult
13813TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13814 // Transform the type.
13815 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13816 if (!Type)
13817 return ExprError();
13818
13819 // Transform all of the components into a Designation similar to what the
13820 // parser builds.
13821 // FIXME: It would be slightly more efficient in the non-dependent case to
13822 // just map FieldDecls, rather than requiring the rebuilder to look for
13823 // the fields again. However, __builtin_offsetof is rare enough in
13824 // template code that we don't care.
13825 bool ExprChanged = false;
13826 Designation Desig;
13827 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13828 const OffsetOfNode &ON = E->getComponent(Idx: I);
13829 switch (ON.getKind()) {
13830 case OffsetOfNode::Array: {
13831 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13832 ExprResult Index = getDerived().TransformExpr(FromIndex);
13833 if (Index.isInvalid())
13834 return ExprError();
13835
13836 ExprChanged = ExprChanged || Index.get() != FromIndex;
13837 Designator AD =
13838 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13839 AD.setRBracketLoc(ON.getEndLoc());
13840 Desig.AddDesignator(D: AD);
13841 break;
13842 }
13843
13844 case OffsetOfNode::Field:
13845 case OffsetOfNode::Identifier: {
13846 const IdentifierInfo *Name = ON.getFieldName();
13847 if (!Name)
13848 continue;
13849 // The leading designator has no '.'; subsequent ones do.
13850 SourceLocation DotLoc =
13851 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13852 Desig.AddDesignator(
13853 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13854 break;
13855 }
13856
13857 case OffsetOfNode::Base:
13858 // Will be recomputed during the rebuild.
13859 continue;
13860 }
13861 }
13862
13863 // If nothing changed, retain the existing expression.
13864 if (!getDerived().AlwaysRebuild() &&
13865 Type == E->getTypeSourceInfo() &&
13866 !ExprChanged)
13867 return E;
13868
13869 // Build a new offsetof expression.
13870 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13871 E->getRParenLoc());
13872}
13873
13874template<typename Derived>
13875ExprResult
13876TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13877 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13878 "opaque value expression requires transformation");
13879 return E;
13880}
13881
13882template <typename Derived>
13883ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13884 llvm::SmallVector<Expr *, 8> Children;
13885 bool Changed = false;
13886 for (Expr *C : E->subExpressions()) {
13887 ExprResult NewC = getDerived().TransformExpr(C);
13888 if (NewC.isInvalid())
13889 return ExprError();
13890 Children.push_back(Elt: NewC.get());
13891
13892 Changed |= NewC.get() != C;
13893 }
13894 if (!getDerived().AlwaysRebuild() && !Changed)
13895 return E;
13896 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13897 Children, E->getType());
13898}
13899
13900template<typename Derived>
13901ExprResult
13902TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13903 // Rebuild the syntactic form. The original syntactic form has
13904 // opaque-value expressions in it, so strip those away and rebuild
13905 // the result. This is a really awful way of doing this, but the
13906 // better solution (rebuilding the semantic expressions and
13907 // rebinding OVEs as necessary) doesn't work; we'd need
13908 // TreeTransform to not strip away implicit conversions.
13909 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13910 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13911 if (result.isInvalid()) return ExprError();
13912
13913 // If that gives us a pseudo-object result back, the pseudo-object
13914 // expression must have been an lvalue-to-rvalue conversion which we
13915 // should reapply.
13916 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13917 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13918
13919 return result;
13920}
13921
13922template<typename Derived>
13923ExprResult
13924TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13925 UnaryExprOrTypeTraitExpr *E) {
13926 if (E->isArgumentType()) {
13927 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13928
13929 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13930 if (!NewT)
13931 return ExprError();
13932
13933 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13934 return E;
13935
13936 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13937 E->getKind(),
13938 E->getSourceRange());
13939 }
13940
13941 // C++0x [expr.sizeof]p1:
13942 // The operand is either an expression, which is an unevaluated operand
13943 // [...]
13944 EnterExpressionEvaluationContext Unevaluated(
13945 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13946 Sema::ReuseLambdaContextDecl);
13947
13948 // Try to recover if we have something like sizeof(T::X) where X is a type.
13949 // Notably, there must be *exactly* one set of parens if X is a type.
13950 TypeSourceInfo *RecoveryTSI = nullptr;
13951 ExprResult SubExpr;
13952 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13953 if (auto *DRE =
13954 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13955 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13956 PE, DRE, false, &RecoveryTSI);
13957 else
13958 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13959
13960 if (RecoveryTSI) {
13961 return getDerived().RebuildUnaryExprOrTypeTrait(
13962 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13963 } else if (SubExpr.isInvalid())
13964 return ExprError();
13965
13966 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13967 return E;
13968
13969 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13970 E->getOperatorLoc(),
13971 E->getKind(),
13972 E->getSourceRange());
13973}
13974
13975template<typename Derived>
13976ExprResult
13977TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13978 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13979 if (LHS.isInvalid())
13980 return ExprError();
13981
13982 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13983 if (RHS.isInvalid())
13984 return ExprError();
13985
13986
13987 if (!getDerived().AlwaysRebuild() &&
13988 LHS.get() == E->getLHS() &&
13989 RHS.get() == E->getRHS())
13990 return E;
13991
13992 return getDerived().RebuildArraySubscriptExpr(
13993 LHS.get(),
13994 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13995}
13996
13997template <typename Derived>
13998ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13999 MatrixSingleSubscriptExpr *E) {
14000 ExprResult Base = getDerived().TransformExpr(E->getBase());
14001 if (Base.isInvalid())
14002 return ExprError();
14003
14004 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14005 if (RowIdx.isInvalid())
14006 return ExprError();
14007
14008 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14009 RowIdx.get() == E->getRowIdx())
14010 return E;
14011
14012 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
14013 E->getRBracketLoc());
14014}
14015
14016template <typename Derived>
14017ExprResult
14018TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
14019 ExprResult Base = getDerived().TransformExpr(E->getBase());
14020 if (Base.isInvalid())
14021 return ExprError();
14022
14023 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
14024 if (RowIdx.isInvalid())
14025 return ExprError();
14026
14027 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
14028 if (ColumnIdx.isInvalid())
14029 return ExprError();
14030
14031 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14032 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
14033 return E;
14034
14035 return getDerived().RebuildMatrixSubscriptExpr(
14036 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
14037}
14038
14039template <typename Derived>
14040ExprResult
14041TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
14042 ExprResult Base = getDerived().TransformExpr(E->getBase());
14043 if (Base.isInvalid())
14044 return ExprError();
14045
14046 ExprResult LowerBound;
14047 if (E->getLowerBound()) {
14048 LowerBound = getDerived().TransformExpr(E->getLowerBound());
14049 if (LowerBound.isInvalid())
14050 return ExprError();
14051 }
14052
14053 ExprResult Length;
14054 if (E->getLength()) {
14055 Length = getDerived().TransformExpr(E->getLength());
14056 if (Length.isInvalid())
14057 return ExprError();
14058 }
14059
14060 ExprResult Stride;
14061 if (E->isOMPArraySection()) {
14062 if (Expr *Str = E->getStride()) {
14063 Stride = getDerived().TransformExpr(Str);
14064 if (Stride.isInvalid())
14065 return ExprError();
14066 }
14067 }
14068
14069 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
14070 LowerBound.get() == E->getLowerBound() &&
14071 Length.get() == E->getLength() &&
14072 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
14073 return E;
14074
14075 return getDerived().RebuildArraySectionExpr(
14076 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
14077 LowerBound.get(), E->getColonLocFirst(),
14078 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
14079 Length.get(), Stride.get(), E->getRBracketLoc());
14080}
14081
14082template <typename Derived>
14083ExprResult
14084TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
14085 ExprResult Base = getDerived().TransformExpr(E->getBase());
14086 if (Base.isInvalid())
14087 return ExprError();
14088
14089 SmallVector<Expr *, 4> Dims;
14090 bool ErrorFound = false;
14091 for (Expr *Dim : E->getDimensions()) {
14092 ExprResult DimRes = getDerived().TransformExpr(Dim);
14093 if (DimRes.isInvalid()) {
14094 ErrorFound = true;
14095 continue;
14096 }
14097 Dims.push_back(Elt: DimRes.get());
14098 }
14099
14100 if (ErrorFound)
14101 return ExprError();
14102 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
14103 E->getRParenLoc(), Dims,
14104 E->getBracketsRanges());
14105}
14106
14107template <typename Derived>
14108ExprResult
14109TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
14110 unsigned NumIterators = E->numOfIterators();
14111 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
14112
14113 bool ErrorFound = false;
14114 bool NeedToRebuild = getDerived().AlwaysRebuild();
14115 for (unsigned I = 0; I < NumIterators; ++I) {
14116 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
14117 Data[I].DeclIdent = D->getIdentifier();
14118 Data[I].DeclIdentLoc = D->getLocation();
14119 if (D->getLocation() == D->getBeginLoc()) {
14120 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
14121 "Implicit type must be int.");
14122 } else {
14123 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
14124 QualType DeclTy = getDerived().TransformType(D->getType());
14125 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
14126 }
14127 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
14128 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
14129 ExprResult End = getDerived().TransformExpr(Range.End);
14130 ExprResult Step = getDerived().TransformExpr(Range.Step);
14131 ErrorFound = ErrorFound ||
14132 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
14133 !Data[I].Type.get().isNull())) ||
14134 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
14135 if (ErrorFound)
14136 continue;
14137 Data[I].Range.Begin = Begin.get();
14138 Data[I].Range.End = End.get();
14139 Data[I].Range.Step = Step.get();
14140 Data[I].AssignLoc = E->getAssignLoc(I);
14141 Data[I].ColonLoc = E->getColonLoc(I);
14142 Data[I].SecColonLoc = E->getSecondColonLoc(I);
14143 NeedToRebuild =
14144 NeedToRebuild ||
14145 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
14146 D->getType().getTypePtrOrNull()) ||
14147 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
14148 Range.Step != Data[I].Range.Step;
14149 }
14150 if (ErrorFound)
14151 return ExprError();
14152 if (!NeedToRebuild)
14153 return E;
14154
14155 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
14156 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
14157 if (!Res.isUsable())
14158 return Res;
14159 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
14160 for (unsigned I = 0; I < NumIterators; ++I)
14161 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
14162 IE->getIteratorDecl(I));
14163 return Res;
14164}
14165
14166template<typename Derived>
14167ExprResult
14168TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
14169 // Transform the callee.
14170 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14171 if (Callee.isInvalid())
14172 return ExprError();
14173
14174 // Transform arguments.
14175 bool ArgChanged = false;
14176 SmallVector<Expr*, 8> Args;
14177 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14178 &ArgChanged))
14179 return ExprError();
14180
14181 if (!getDerived().AlwaysRebuild() &&
14182 Callee.get() == E->getCallee() &&
14183 !ArgChanged)
14184 return SemaRef.MaybeBindToTemporary(E);
14185
14186 // FIXME: Wrong source location information for the '('.
14187 SourceLocation FakeLParenLoc
14188 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14189
14190 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14191 if (E->hasStoredFPFeatures()) {
14192 FPOptionsOverride NewOverrides = E->getFPFeatures();
14193 getSema().CurFPFeatures =
14194 NewOverrides.applyOverrides(getSema().getLangOpts());
14195 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14196 }
14197
14198 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14199 Args,
14200 E->getRParenLoc());
14201}
14202
14203template<typename Derived>
14204ExprResult
14205TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
14206 ExprResult Base = getDerived().TransformExpr(E->getBase());
14207 if (Base.isInvalid())
14208 return ExprError();
14209
14210 NestedNameSpecifierLoc QualifierLoc;
14211 if (E->hasQualifier()) {
14212 QualifierLoc
14213 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14214
14215 if (!QualifierLoc)
14216 return ExprError();
14217 }
14218 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14219
14220 ValueDecl *Member
14221 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
14222 E->getMemberDecl()));
14223 if (!Member)
14224 return ExprError();
14225
14226 NamedDecl *FoundDecl = E->getFoundDecl();
14227 if (FoundDecl == E->getMemberDecl()) {
14228 FoundDecl = Member;
14229 } else {
14230 FoundDecl = cast_or_null<NamedDecl>(
14231 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
14232 if (!FoundDecl)
14233 return ExprError();
14234 }
14235
14236 if (!getDerived().AlwaysRebuild() &&
14237 Base.get() == E->getBase() &&
14238 QualifierLoc == E->getQualifierLoc() &&
14239 Member == E->getMemberDecl() &&
14240 FoundDecl == E->getFoundDecl() &&
14241 !E->hasExplicitTemplateArgs()) {
14242
14243 // Skip for member expression of (this->f), rebuilt thisi->f is needed
14244 // for Openmp where the field need to be privatizized in the case.
14245 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
14246 getSema().OpenMP().isOpenMPRebuildMemberExpr(
14247 cast<ValueDecl>(Val: Member)))) {
14248 // Mark it referenced in the new context regardless.
14249 // FIXME: this is a bit instantiation-specific.
14250 SemaRef.MarkMemberReferenced(E);
14251 return E;
14252 }
14253 }
14254
14255 TemplateArgumentListInfo TransArgs;
14256 if (E->hasExplicitTemplateArgs()) {
14257 TransArgs.setLAngleLoc(E->getLAngleLoc());
14258 TransArgs.setRAngleLoc(E->getRAngleLoc());
14259 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14260 E->getNumTemplateArgs(),
14261 TransArgs))
14262 return ExprError();
14263 }
14264
14265 // FIXME: Bogus source location for the operator
14266 SourceLocation FakeOperatorLoc =
14267 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
14268
14269 // FIXME: to do this check properly, we will need to preserve the
14270 // first-qualifier-in-scope here, just in case we had a dependent
14271 // base (and therefore couldn't do the check) and a
14272 // nested-name-qualifier (and therefore could do the lookup).
14273 NamedDecl *FirstQualifierInScope = nullptr;
14274 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
14275 if (MemberNameInfo.getName()) {
14276 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
14277 if (!MemberNameInfo.getName())
14278 return ExprError();
14279 }
14280
14281 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
14282 E->isArrow(),
14283 QualifierLoc,
14284 TemplateKWLoc,
14285 MemberNameInfo,
14286 Member,
14287 FoundDecl,
14288 (E->hasExplicitTemplateArgs()
14289 ? &TransArgs : nullptr),
14290 FirstQualifierInScope);
14291}
14292
14293template<typename Derived>
14294ExprResult
14295TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
14296 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14297 if (LHS.isInvalid())
14298 return ExprError();
14299
14300 ExprResult RHS =
14301 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
14302 if (RHS.isInvalid())
14303 return ExprError();
14304
14305 if (!getDerived().AlwaysRebuild() &&
14306 LHS.get() == E->getLHS() &&
14307 RHS.get() == E->getRHS())
14308 return E;
14309
14310 if (E->isCompoundAssignmentOp())
14311 // FPFeatures has already been established from trailing storage
14312 return getDerived().RebuildBinaryOperator(
14313 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
14314 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14315 FPOptionsOverride NewOverrides(E->getFPFeatures());
14316 getSema().CurFPFeatures =
14317 NewOverrides.applyOverrides(getSema().getLangOpts());
14318 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14319 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
14320 LHS.get(), RHS.get());
14321}
14322
14323template <typename Derived>
14324ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
14325 CXXRewrittenBinaryOperator *E) {
14326 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
14327
14328 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
14329 if (LHS.isInvalid())
14330 return ExprError();
14331
14332 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
14333 if (RHS.isInvalid())
14334 return ExprError();
14335
14336 // Extract the already-resolved callee declarations so that we can restrict
14337 // ourselves to using them as the unqualified lookup results when rebuilding.
14338 UnresolvedSet<2> UnqualLookups;
14339 bool ChangedAnyLookups = false;
14340 Expr *PossibleBinOps[] = {E->getSemanticForm(),
14341 const_cast<Expr *>(Decomp.InnerBinOp)};
14342 for (Expr *PossibleBinOp : PossibleBinOps) {
14343 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
14344 if (!Op)
14345 continue;
14346 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
14347 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
14348 continue;
14349
14350 // Transform the callee in case we built a call to a local extern
14351 // declaration.
14352 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
14353 E->getOperatorLoc(), Callee->getFoundDecl()));
14354 if (!Found)
14355 return ExprError();
14356 if (Found != Callee->getFoundDecl())
14357 ChangedAnyLookups = true;
14358 UnqualLookups.addDecl(D: Found);
14359 }
14360
14361 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
14362 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
14363 // Mark all functions used in the rewrite as referenced. Note that when
14364 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
14365 // function calls, and/or there might be a user-defined conversion sequence
14366 // applied to the operands of the <.
14367 // FIXME: this is a bit instantiation-specific.
14368 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
14369 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
14370 return E;
14371 }
14372
14373 return getDerived().RebuildCXXRewrittenBinaryOperator(
14374 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
14375}
14376
14377template<typename Derived>
14378ExprResult
14379TreeTransform<Derived>::TransformCompoundAssignOperator(
14380 CompoundAssignOperator *E) {
14381 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14382 FPOptionsOverride NewOverrides(E->getFPFeatures());
14383 getSema().CurFPFeatures =
14384 NewOverrides.applyOverrides(getSema().getLangOpts());
14385 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14386 return getDerived().TransformBinaryOperator(E);
14387}
14388
14389template<typename Derived>
14390ExprResult TreeTransform<Derived>::
14391TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
14392 // Just rebuild the common and RHS expressions and see whether we
14393 // get any changes.
14394
14395 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
14396 if (commonExpr.isInvalid())
14397 return ExprError();
14398
14399 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
14400 if (rhs.isInvalid())
14401 return ExprError();
14402
14403 if (!getDerived().AlwaysRebuild() &&
14404 commonExpr.get() == e->getCommon() &&
14405 rhs.get() == e->getFalseExpr())
14406 return e;
14407
14408 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14409 e->getQuestionLoc(),
14410 nullptr,
14411 e->getColonLoc(),
14412 rhs.get());
14413}
14414
14415template<typename Derived>
14416ExprResult
14417TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14418 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14419 if (Cond.isInvalid())
14420 return ExprError();
14421
14422 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14423 if (LHS.isInvalid())
14424 return ExprError();
14425
14426 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14427 if (RHS.isInvalid())
14428 return ExprError();
14429
14430 if (!getDerived().AlwaysRebuild() &&
14431 Cond.get() == E->getCond() &&
14432 LHS.get() == E->getLHS() &&
14433 RHS.get() == E->getRHS())
14434 return E;
14435
14436 return getDerived().RebuildConditionalOperator(Cond.get(),
14437 E->getQuestionLoc(),
14438 LHS.get(),
14439 E->getColonLoc(),
14440 RHS.get());
14441}
14442
14443template<typename Derived>
14444ExprResult
14445TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14446 // Implicit casts are eliminated during transformation, since they
14447 // will be recomputed by semantic analysis after transformation.
14448 return getDerived().TransformExpr(E->getSubExprAsWritten());
14449}
14450
14451template<typename Derived>
14452ExprResult
14453TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14454 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14455 if (!Type)
14456 return ExprError();
14457
14458 ExprResult SubExpr
14459 = getDerived().TransformExpr(E->getSubExprAsWritten());
14460 if (SubExpr.isInvalid())
14461 return ExprError();
14462
14463 if (!getDerived().AlwaysRebuild() &&
14464 Type == E->getTypeInfoAsWritten() &&
14465 SubExpr.get() == E->getSubExpr())
14466 return E;
14467
14468 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14469 Type,
14470 E->getRParenLoc(),
14471 SubExpr.get());
14472}
14473
14474template<typename Derived>
14475ExprResult
14476TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14477 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14478 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14479 if (!NewT)
14480 return ExprError();
14481
14482 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14483 if (Init.isInvalid())
14484 return ExprError();
14485
14486 if (!getDerived().AlwaysRebuild() &&
14487 OldT == NewT &&
14488 Init.get() == E->getInitializer())
14489 return SemaRef.MaybeBindToTemporary(E);
14490
14491 // Note: the expression type doesn't necessarily match the
14492 // type-as-written, but that's okay, because it should always be
14493 // derivable from the initializer.
14494
14495 return getDerived().RebuildCompoundLiteralExpr(
14496 E->getLParenLoc(), NewT,
14497 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14498}
14499
14500template<typename Derived>
14501ExprResult
14502TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14503 ExprResult Base = getDerived().TransformExpr(E->getBase());
14504 if (Base.isInvalid())
14505 return ExprError();
14506
14507 if (!getDerived().AlwaysRebuild() &&
14508 Base.get() == E->getBase())
14509 return E;
14510
14511 // FIXME: Bad source location
14512 SourceLocation FakeOperatorLoc =
14513 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14514 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14515 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14516 E->getAccessor());
14517}
14518
14519template <typename Derived>
14520ExprResult
14521TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14522 ExprResult Base = getDerived().TransformExpr(E->getBase());
14523 if (Base.isInvalid())
14524 return ExprError();
14525
14526 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14527 return E;
14528
14529 // FIXME: Bad source location
14530 SourceLocation FakeOperatorLoc =
14531 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14532 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14533 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14534 E->getAccessor());
14535}
14536
14537template<typename Derived>
14538ExprResult
14539TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14540 if (InitListExpr *Syntactic = E->getSyntacticForm())
14541 E = Syntactic;
14542
14543 bool InitChanged = false;
14544
14545 EnterExpressionEvaluationContext Context(
14546 getSema(), EnterExpressionEvaluationContext::InitList);
14547
14548 SmallVector<Expr*, 4> Inits;
14549 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14550 Inits, &InitChanged))
14551 return ExprError();
14552
14553 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14554 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14555 // in some cases. We can't reuse it in general, because the syntactic and
14556 // semantic forms are linked, and we can't know that semantic form will
14557 // match even if the syntactic form does.
14558 }
14559
14560 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14561 E->getRBraceLoc(), E->isExplicit());
14562}
14563
14564template<typename Derived>
14565ExprResult
14566TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14567 Designation Desig;
14568
14569 // transform the initializer value
14570 ExprResult Init = getDerived().TransformExpr(E->getInit());
14571 if (Init.isInvalid())
14572 return ExprError();
14573
14574 // transform the designators.
14575 SmallVector<Expr*, 4> ArrayExprs;
14576 bool ExprChanged = false;
14577 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14578 if (D.isFieldDesignator()) {
14579 if (D.getFieldDecl()) {
14580 FieldDecl *Field = cast_or_null<FieldDecl>(
14581 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14582 if (Field != D.getFieldDecl())
14583 // Rebuild the expression when the transformed FieldDecl is
14584 // different to the already assigned FieldDecl.
14585 ExprChanged = true;
14586 if (Field->isAnonymousStructOrUnion())
14587 continue;
14588 } else {
14589 // Ensure that the designator expression is rebuilt when there isn't
14590 // a resolved FieldDecl in the designator as we don't want to assign
14591 // a FieldDecl to a pattern designator that will be instantiated again.
14592 ExprChanged = true;
14593 }
14594 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14595 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14596 continue;
14597 }
14598
14599 if (D.isArrayDesignator()) {
14600 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14601 if (Index.isInvalid())
14602 return ExprError();
14603
14604 Desig.AddDesignator(
14605 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14606
14607 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14608 ArrayExprs.push_back(Elt: Index.get());
14609 continue;
14610 }
14611
14612 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14613 ExprResult Start
14614 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14615 if (Start.isInvalid())
14616 return ExprError();
14617
14618 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14619 if (End.isInvalid())
14620 return ExprError();
14621
14622 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14623 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14624
14625 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14626 End.get() != E->getArrayRangeEnd(D);
14627
14628 ArrayExprs.push_back(Elt: Start.get());
14629 ArrayExprs.push_back(Elt: End.get());
14630 }
14631
14632 if (!getDerived().AlwaysRebuild() &&
14633 Init.get() == E->getInit() &&
14634 !ExprChanged)
14635 return E;
14636
14637 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14638 E->getEqualOrColonLoc(),
14639 E->usesGNUSyntax(), Init.get());
14640}
14641
14642// Seems that if TransformInitListExpr() only works on the syntactic form of an
14643// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14644template<typename Derived>
14645ExprResult
14646TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14647 DesignatedInitUpdateExpr *E) {
14648 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14649 "initializer");
14650 return ExprError();
14651}
14652
14653template<typename Derived>
14654ExprResult
14655TreeTransform<Derived>::TransformNoInitExpr(
14656 NoInitExpr *E) {
14657 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14658 return ExprError();
14659}
14660
14661template<typename Derived>
14662ExprResult
14663TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14664 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14665 return ExprError();
14666}
14667
14668template<typename Derived>
14669ExprResult
14670TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14671 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14672 return ExprError();
14673}
14674
14675template<typename Derived>
14676ExprResult
14677TreeTransform<Derived>::TransformImplicitValueInitExpr(
14678 ImplicitValueInitExpr *E) {
14679 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14680
14681 // FIXME: Will we ever have proper type location here? Will we actually
14682 // need to transform the type?
14683 QualType T = getDerived().TransformType(E->getType());
14684 if (T.isNull())
14685 return ExprError();
14686
14687 if (!getDerived().AlwaysRebuild() &&
14688 T == E->getType())
14689 return E;
14690
14691 return getDerived().RebuildImplicitValueInitExpr(T);
14692}
14693
14694template<typename Derived>
14695ExprResult
14696TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14697 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14698 if (!TInfo)
14699 return ExprError();
14700
14701 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14702 if (SubExpr.isInvalid())
14703 return ExprError();
14704
14705 if (!getDerived().AlwaysRebuild() &&
14706 TInfo == E->getWrittenTypeInfo() &&
14707 SubExpr.get() == E->getSubExpr())
14708 return E;
14709
14710 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14711 TInfo, E->getRParenLoc());
14712}
14713
14714template<typename Derived>
14715ExprResult
14716TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14717 bool ArgumentChanged = false;
14718 SmallVector<Expr*, 4> Inits;
14719 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14720 ArgChanged: &ArgumentChanged))
14721 return ExprError();
14722
14723 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14724 Inits,
14725 E->getRParenLoc());
14726}
14727
14728/// Transform an address-of-label expression.
14729///
14730/// By default, the transformation of an address-of-label expression always
14731/// rebuilds the expression, so that the label identifier can be resolved to
14732/// the corresponding label statement by semantic analysis.
14733template<typename Derived>
14734ExprResult
14735TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14736 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14737 E->getLabel());
14738 if (!LD)
14739 return ExprError();
14740
14741 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14742 cast<LabelDecl>(Val: LD));
14743}
14744
14745template<typename Derived>
14746ExprResult
14747TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14748 SemaRef.ActOnStartStmtExpr();
14749 StmtResult SubStmt
14750 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14751 if (SubStmt.isInvalid()) {
14752 SemaRef.ActOnStmtExprError();
14753 return ExprError();
14754 }
14755
14756 unsigned OldDepth = E->getTemplateDepth();
14757 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14758
14759 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14760 SubStmt.get() == E->getSubStmt()) {
14761 // Calling this an 'error' is unintuitive, but it does the right thing.
14762 SemaRef.ActOnStmtExprError();
14763 return SemaRef.MaybeBindToTemporary(E);
14764 }
14765
14766 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14767 E->getRParenLoc(), NewDepth);
14768}
14769
14770template<typename Derived>
14771ExprResult
14772TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14773 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14774 if (Cond.isInvalid())
14775 return ExprError();
14776
14777 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14778 if (LHS.isInvalid())
14779 return ExprError();
14780
14781 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14782 if (RHS.isInvalid())
14783 return ExprError();
14784
14785 if (!getDerived().AlwaysRebuild() &&
14786 Cond.get() == E->getCond() &&
14787 LHS.get() == E->getLHS() &&
14788 RHS.get() == E->getRHS())
14789 return E;
14790
14791 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14792 Cond.get(), LHS.get(), RHS.get(),
14793 E->getRParenLoc());
14794}
14795
14796template<typename Derived>
14797ExprResult
14798TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14799 return E;
14800}
14801
14802template<typename Derived>
14803ExprResult
14804TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14805 switch (E->getOperator()) {
14806 case OO_New:
14807 case OO_Delete:
14808 case OO_Array_New:
14809 case OO_Array_Delete:
14810 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14811
14812 case OO_Subscript:
14813 case OO_Call: {
14814 // This is a call to an object's operator().
14815 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14816
14817 // Transform the object itself.
14818 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14819 if (Object.isInvalid())
14820 return ExprError();
14821
14822 // FIXME: Poor location information. Also, if the location for the end of
14823 // the token is within a macro expansion, getLocForEndOfToken() will return
14824 // an invalid source location. If that happens and we have an otherwise
14825 // valid end location, use the valid one instead of the invalid one.
14826 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14827 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14828 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14829 FakeLParenLoc = EndLoc;
14830
14831 // Transform the call arguments.
14832 SmallVector<Expr*, 8> Args;
14833 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14834 Args))
14835 return ExprError();
14836
14837 if (E->getOperator() == OO_Subscript)
14838 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14839 Args, E->getEndLoc());
14840
14841 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14842 E->getEndLoc());
14843 }
14844
14845#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14846 case OO_##Name: \
14847 break;
14848
14849#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14850#include "clang/Basic/OperatorKinds.def"
14851
14852 case OO_Conditional:
14853 llvm_unreachable("conditional operator is not actually overloadable");
14854
14855 case OO_None:
14856 case NUM_OVERLOADED_OPERATORS:
14857 llvm_unreachable("not an overloaded operator?");
14858 }
14859
14860 ExprResult First;
14861 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14862 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14863 else
14864 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14865 if (First.isInvalid())
14866 return ExprError();
14867
14868 ExprResult Second;
14869 if (E->getNumArgs() == 2) {
14870 Second =
14871 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14872 if (Second.isInvalid())
14873 return ExprError();
14874 }
14875
14876 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14877 FPOptionsOverride NewOverrides(E->getFPFeatures());
14878 getSema().CurFPFeatures =
14879 NewOverrides.applyOverrides(getSema().getLangOpts());
14880 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14881
14882 Expr *Callee = E->getCallee();
14883 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14884 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14885 Sema::LookupOrdinaryName);
14886 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14887 return ExprError();
14888
14889 return getDerived().RebuildCXXOperatorCallExpr(
14890 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14891 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14892 }
14893
14894 UnresolvedSet<1> Functions;
14895 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14896 Callee = ICE->getSubExprAsWritten();
14897 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14898 ValueDecl *VD = cast_or_null<ValueDecl>(
14899 getDerived().TransformDecl(DR->getLocation(), DR));
14900 if (!VD)
14901 return ExprError();
14902
14903 if (!isa<CXXMethodDecl>(Val: VD))
14904 Functions.addDecl(D: VD);
14905
14906 return getDerived().RebuildCXXOperatorCallExpr(
14907 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14908 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14909}
14910
14911template<typename Derived>
14912ExprResult
14913TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14914 return getDerived().TransformCallExpr(E);
14915}
14916
14917template <typename Derived>
14918ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14919 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14920 getSema().CurContext != E->getParentContext();
14921
14922 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14923 return E;
14924
14925 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14926 E->getBeginLoc(), E->getEndLoc(),
14927 getSema().CurContext);
14928}
14929
14930template <typename Derived>
14931ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14932 return E;
14933}
14934
14935template<typename Derived>
14936ExprResult
14937TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14938 // Transform the callee.
14939 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14940 if (Callee.isInvalid())
14941 return ExprError();
14942
14943 // Transform exec config.
14944 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14945 if (EC.isInvalid())
14946 return ExprError();
14947
14948 // Transform arguments.
14949 bool ArgChanged = false;
14950 SmallVector<Expr*, 8> Args;
14951 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14952 &ArgChanged))
14953 return ExprError();
14954
14955 if (!getDerived().AlwaysRebuild() &&
14956 Callee.get() == E->getCallee() &&
14957 !ArgChanged)
14958 return SemaRef.MaybeBindToTemporary(E);
14959
14960 // FIXME: Wrong source location information for the '('.
14961 SourceLocation FakeLParenLoc
14962 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14963 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14964 Args,
14965 E->getRParenLoc(), EC.get());
14966}
14967
14968template<typename Derived>
14969ExprResult
14970TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14971 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14972 if (!Type)
14973 return ExprError();
14974
14975 ExprResult SubExpr
14976 = getDerived().TransformExpr(E->getSubExprAsWritten());
14977 if (SubExpr.isInvalid())
14978 return ExprError();
14979
14980 if (!getDerived().AlwaysRebuild() &&
14981 Type == E->getTypeInfoAsWritten() &&
14982 SubExpr.get() == E->getSubExpr())
14983 return E;
14984 return getDerived().RebuildCXXNamedCastExpr(
14985 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14986 Type, E->getAngleBrackets().getEnd(),
14987 // FIXME. this should be '(' location
14988 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14989}
14990
14991template<typename Derived>
14992ExprResult
14993TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14994 TypeSourceInfo *TSI =
14995 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14996 if (!TSI)
14997 return ExprError();
14998
14999 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
15000 if (Sub.isInvalid())
15001 return ExprError();
15002
15003 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
15004 Sub.get(), BCE->getEndLoc());
15005}
15006
15007template<typename Derived>
15008ExprResult
15009TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
15010 return getDerived().TransformCXXNamedCastExpr(E);
15011}
15012
15013template<typename Derived>
15014ExprResult
15015TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
15016 return getDerived().TransformCXXNamedCastExpr(E);
15017}
15018
15019template<typename Derived>
15020ExprResult
15021TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
15022 CXXReinterpretCastExpr *E) {
15023 return getDerived().TransformCXXNamedCastExpr(E);
15024}
15025
15026template<typename Derived>
15027ExprResult
15028TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
15029 return getDerived().TransformCXXNamedCastExpr(E);
15030}
15031
15032template<typename Derived>
15033ExprResult
15034TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
15035 return getDerived().TransformCXXNamedCastExpr(E);
15036}
15037
15038template<typename Derived>
15039ExprResult
15040TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
15041 CXXFunctionalCastExpr *E) {
15042 TypeSourceInfo *Type =
15043 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
15044 if (!Type)
15045 return ExprError();
15046
15047 ExprResult SubExpr
15048 = getDerived().TransformExpr(E->getSubExprAsWritten());
15049 if (SubExpr.isInvalid())
15050 return ExprError();
15051
15052 if (!getDerived().AlwaysRebuild() &&
15053 Type == E->getTypeInfoAsWritten() &&
15054 SubExpr.get() == E->getSubExpr())
15055 return E;
15056
15057 return getDerived().RebuildCXXFunctionalCastExpr(Type,
15058 E->getLParenLoc(),
15059 SubExpr.get(),
15060 E->getRParenLoc(),
15061 E->isListInitialization());
15062}
15063
15064template<typename Derived>
15065ExprResult
15066TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
15067 if (E->isTypeOperand()) {
15068 TypeSourceInfo *TInfo
15069 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15070 if (!TInfo)
15071 return ExprError();
15072
15073 if (!getDerived().AlwaysRebuild() &&
15074 TInfo == E->getTypeOperandSourceInfo())
15075 return E;
15076
15077 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15078 TInfo, E->getEndLoc());
15079 }
15080
15081 // Typeid's operand is an unevaluated context, unless it's a polymorphic
15082 // type. We must not unilaterally enter unevaluated context here, as then
15083 // semantic processing can re-transform an already transformed operand.
15084 Expr *Op = E->getExprOperand();
15085 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
15086 if (E->isGLValue()) {
15087 QualType OpType = Op->getType();
15088 if (auto *RD = OpType->getAsCXXRecordDecl()) {
15089 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
15090 DiagID: diag::err_incomplete_typeid))
15091 return ExprError();
15092
15093 if (RD->isPolymorphic())
15094 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
15095 }
15096 }
15097
15098 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
15099 Sema::ReuseLambdaContextDecl);
15100
15101 ExprResult SubExpr = getDerived().TransformExpr(Op);
15102 if (SubExpr.isInvalid())
15103 return ExprError();
15104
15105 if (!getDerived().AlwaysRebuild() &&
15106 SubExpr.get() == E->getExprOperand())
15107 return E;
15108
15109 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
15110 SubExpr.get(), E->getEndLoc());
15111}
15112
15113template<typename Derived>
15114ExprResult
15115TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
15116 if (E->isTypeOperand()) {
15117 TypeSourceInfo *TInfo
15118 = getDerived().TransformType(E->getTypeOperandSourceInfo());
15119 if (!TInfo)
15120 return ExprError();
15121
15122 if (!getDerived().AlwaysRebuild() &&
15123 TInfo == E->getTypeOperandSourceInfo())
15124 return E;
15125
15126 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15127 TInfo, E->getEndLoc());
15128 }
15129
15130 EnterExpressionEvaluationContext Unevaluated(
15131 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15132
15133 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
15134 if (SubExpr.isInvalid())
15135 return ExprError();
15136
15137 if (!getDerived().AlwaysRebuild() &&
15138 SubExpr.get() == E->getExprOperand())
15139 return E;
15140
15141 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
15142 SubExpr.get(), E->getEndLoc());
15143}
15144
15145template<typename Derived>
15146ExprResult
15147TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
15148 return E;
15149}
15150
15151template<typename Derived>
15152ExprResult
15153TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
15154 CXXNullPtrLiteralExpr *E) {
15155 return E;
15156}
15157
15158template<typename Derived>
15159ExprResult
15160TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
15161
15162 // In lambdas, the qualifiers of the type depends of where in
15163 // the call operator `this` appear, and we do not have a good way to
15164 // rebuild this information, so we transform the type.
15165 //
15166 // In other contexts, the type of `this` may be overrided
15167 // for type deduction, so we need to recompute it.
15168 //
15169 // Always recompute the type if we're in the body of a lambda, and
15170 // 'this' is dependent on a lambda's explicit object parameter; we
15171 // also need to always rebuild the expression in this case to clear
15172 // the flag.
15173 QualType T = [&]() {
15174 auto &S = getSema();
15175 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
15176 return S.getCurrentThisType();
15177 if (S.getCurLambda())
15178 return getDerived().TransformType(E->getType());
15179 return S.getCurrentThisType();
15180 }();
15181
15182 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
15183 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
15184 // Mark it referenced in the new context regardless.
15185 // FIXME: this is a bit instantiation-specific.
15186 getSema().MarkThisReferenced(E);
15187 return E;
15188 }
15189
15190 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
15191}
15192
15193template<typename Derived>
15194ExprResult
15195TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
15196 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15197 if (SubExpr.isInvalid())
15198 return ExprError();
15199
15200 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
15201
15202 if (!getDerived().AlwaysRebuild() &&
15203 SubExpr.get() == E->getSubExpr())
15204 return E;
15205
15206 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
15207 E->isThrownVariableInScope());
15208}
15209
15210template<typename Derived>
15211ExprResult
15212TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
15213 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
15214 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
15215 if (!Param)
15216 return ExprError();
15217
15218 ExprResult InitRes;
15219 if (E->hasRewrittenInit()) {
15220 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15221 if (InitRes.isInvalid())
15222 return ExprError();
15223 }
15224
15225 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
15226 E->getUsedContext() == SemaRef.CurContext &&
15227 InitRes.get() == E->getRewrittenExpr())
15228 return E;
15229
15230 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
15231 InitRes.get());
15232}
15233
15234template<typename Derived>
15235ExprResult
15236TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
15237 FieldDecl *Field = cast_or_null<FieldDecl>(
15238 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
15239 if (!Field)
15240 return ExprError();
15241
15242 ExprResult InitRes;
15243 if (E->hasRewrittenInit()) {
15244 // The initializer can refer to `this` and to other members, so it has to
15245 // be transformed in the scope of the field's class.
15246 Sema::CXXThisScopeRAII ThisScope(SemaRef, Field->getParent(), Qualifiers());
15247 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15248 if (InitRes.isInvalid())
15249 return ExprError();
15250 }
15251
15252 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
15253 E->getUsedContext() == SemaRef.CurContext &&
15254 InitRes.get() == E->getRewrittenExpr())
15255 return E;
15256
15257 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field,
15258 InitRes.get());
15259}
15260
15261template<typename Derived>
15262ExprResult
15263TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
15264 CXXScalarValueInitExpr *E) {
15265 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
15266 if (!T)
15267 return ExprError();
15268
15269 if (!getDerived().AlwaysRebuild() &&
15270 T == E->getTypeSourceInfo())
15271 return E;
15272
15273 return getDerived().RebuildCXXScalarValueInitExpr(T,
15274 /*FIXME:*/T->getTypeLoc().getEndLoc(),
15275 E->getRParenLoc());
15276}
15277
15278template<typename Derived>
15279ExprResult
15280TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
15281 // Transform the type that we're allocating
15282 TypeSourceInfo *AllocTypeInfo =
15283 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
15284 if (!AllocTypeInfo)
15285 return ExprError();
15286
15287 // Transform the size of the array we're allocating (if any).
15288 std::optional<Expr *> ArraySize;
15289 if (E->isArray()) {
15290 ExprResult NewArraySize;
15291 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
15292 NewArraySize = getDerived().TransformExpr(*OldArraySize);
15293 if (NewArraySize.isInvalid())
15294 return ExprError();
15295 }
15296 ArraySize = NewArraySize.get();
15297 }
15298
15299 // Transform the placement arguments (if any).
15300 bool ArgumentChanged = false;
15301 SmallVector<Expr*, 8> PlacementArgs;
15302 if (getDerived().TransformExprs(E->getPlacementArgs(),
15303 E->getNumPlacementArgs(), true,
15304 PlacementArgs, &ArgumentChanged))
15305 return ExprError();
15306
15307 // Transform the initializer (if any).
15308 Expr *OldInit = E->getInitializer();
15309 ExprResult NewInit;
15310 if (OldInit)
15311 NewInit = getDerived().TransformInitializer(OldInit, true);
15312 if (NewInit.isInvalid())
15313 return ExprError();
15314
15315 // Transform new operator and delete operator.
15316 FunctionDecl *OperatorNew = nullptr;
15317 if (E->getOperatorNew()) {
15318 OperatorNew = cast_or_null<FunctionDecl>(
15319 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
15320 if (!OperatorNew)
15321 return ExprError();
15322 }
15323
15324 FunctionDecl *OperatorDelete = nullptr;
15325 if (E->getOperatorDelete()) {
15326 OperatorDelete = cast_or_null<FunctionDecl>(
15327 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15328 if (!OperatorDelete)
15329 return ExprError();
15330 }
15331
15332 if (!getDerived().AlwaysRebuild() &&
15333 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
15334 ArraySize == E->getArraySize() &&
15335 NewInit.get() == OldInit &&
15336 OperatorNew == E->getOperatorNew() &&
15337 OperatorDelete == E->getOperatorDelete() &&
15338 !ArgumentChanged) {
15339 // Mark any declarations we need as referenced.
15340 // FIXME: instantiation-specific.
15341 if (OperatorNew)
15342 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
15343 if (OperatorDelete)
15344 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15345
15346 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
15347 QualType ElementType
15348 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
15349 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
15350 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
15351 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
15352 }
15353 }
15354
15355 return E;
15356 }
15357
15358 QualType AllocType = AllocTypeInfo->getType();
15359 if (!ArraySize) {
15360 // If no array size was specified, but the new expression was
15361 // instantiated with an array type (e.g., "new T" where T is
15362 // instantiated with "int[4]"), extract the outer bound from the
15363 // array type as our array size. We do this with constant and
15364 // dependently-sized array types.
15365 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
15366 if (!ArrayT) {
15367 // Do nothing
15368 } else if (const ConstantArrayType *ConsArrayT
15369 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
15370 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
15371 type: SemaRef.Context.getSizeType(),
15372 /*FIXME:*/ l: E->getBeginLoc());
15373 AllocType = ConsArrayT->getElementType();
15374 } else if (const DependentSizedArrayType *DepArrayT
15375 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
15376 if (DepArrayT->getSizeExpr()) {
15377 ArraySize = DepArrayT->getSizeExpr();
15378 AllocType = DepArrayT->getElementType();
15379 }
15380 }
15381 }
15382
15383 return getDerived().RebuildCXXNewExpr(
15384 E->getBeginLoc(), E->isGlobalNew(),
15385 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
15386 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
15387 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
15388}
15389
15390template<typename Derived>
15391ExprResult
15392TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
15393 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
15394 if (Operand.isInvalid())
15395 return ExprError();
15396
15397 // Transform the delete operator, if known.
15398 FunctionDecl *OperatorDelete = nullptr;
15399 if (E->getOperatorDelete()) {
15400 OperatorDelete = cast_or_null<FunctionDecl>(
15401 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15402 if (!OperatorDelete)
15403 return ExprError();
15404 }
15405
15406 if (!getDerived().AlwaysRebuild() &&
15407 Operand.get() == E->getArgument() &&
15408 OperatorDelete == E->getOperatorDelete()) {
15409 // Mark any declarations we need as referenced.
15410 // FIXME: instantiation-specific.
15411 if (OperatorDelete)
15412 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15413
15414 if (!E->getArgument()->isTypeDependent()) {
15415 QualType Destroyed = SemaRef.Context.getBaseElementType(
15416 QT: E->getDestroyedType());
15417 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15418 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15419 Func: SemaRef.LookupDestructor(Class: Record));
15420 }
15421
15422 return E;
15423 }
15424
15425 return getDerived().RebuildCXXDeleteExpr(
15426 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15427}
15428
15429template<typename Derived>
15430ExprResult
15431TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15432 CXXPseudoDestructorExpr *E) {
15433 ExprResult Base = getDerived().TransformExpr(E->getBase());
15434 if (Base.isInvalid())
15435 return ExprError();
15436
15437 ParsedType ObjectTypePtr;
15438 bool MayBePseudoDestructor = false;
15439 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15440 OpLoc: E->getOperatorLoc(),
15441 OpKind: E->isArrow()? tok::arrow : tok::period,
15442 ObjectType&: ObjectTypePtr,
15443 MayBePseudoDestructor);
15444 if (Base.isInvalid())
15445 return ExprError();
15446
15447 QualType ObjectType = ObjectTypePtr.get();
15448 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15449 if (QualifierLoc) {
15450 QualifierLoc
15451 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15452 if (!QualifierLoc)
15453 return ExprError();
15454 }
15455 CXXScopeSpec SS;
15456 SS.Adopt(Other: QualifierLoc);
15457
15458 PseudoDestructorTypeStorage Destroyed;
15459 if (E->getDestroyedTypeInfo()) {
15460 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15461 E->getDestroyedTypeInfo(), ObjectType,
15462 /*FirstQualifierInScope=*/nullptr);
15463 if (!DestroyedTypeInfo)
15464 return ExprError();
15465 Destroyed = DestroyedTypeInfo;
15466 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15467 // We aren't likely to be able to resolve the identifier down to a type
15468 // now anyway, so just retain the identifier.
15469 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15470 E->getDestroyedTypeLoc());
15471 } else {
15472 // Look for a destructor known with the given name.
15473 ParsedType T = SemaRef.getDestructorName(
15474 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15475 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15476 if (!T)
15477 return ExprError();
15478
15479 Destroyed
15480 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15481 Loc: E->getDestroyedTypeLoc());
15482 }
15483
15484 TypeSourceInfo *ScopeTypeInfo = nullptr;
15485 if (E->getScopeTypeInfo()) {
15486 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15487 E->getScopeTypeInfo(), ObjectType, nullptr);
15488 if (!ScopeTypeInfo)
15489 return ExprError();
15490 }
15491
15492 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15493 E->getOperatorLoc(),
15494 E->isArrow(),
15495 SS,
15496 ScopeTypeInfo,
15497 E->getColonColonLoc(),
15498 E->getTildeLoc(),
15499 Destroyed);
15500}
15501
15502template <typename Derived>
15503bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15504 bool RequiresADL,
15505 LookupResult &R) {
15506 // Transform all the decls.
15507 bool AllEmptyPacks = true;
15508 for (auto *OldD : Old->decls()) {
15509 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15510 if (!InstD) {
15511 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15512 // This can happen because of dependent hiding.
15513 if (isa<UsingShadowDecl>(Val: OldD))
15514 continue;
15515 else {
15516 R.clear();
15517 return true;
15518 }
15519 }
15520
15521 // Expand using pack declarations.
15522 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15523 ArrayRef<NamedDecl*> Decls = SingleDecl;
15524 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15525 Decls = UPD->expansions();
15526
15527 // Expand using declarations.
15528 for (auto *D : Decls) {
15529 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15530 for (auto *SD : UD->shadows())
15531 R.addDecl(D: SD);
15532 } else {
15533 R.addDecl(D);
15534 }
15535 }
15536
15537 AllEmptyPacks &= Decls.empty();
15538 }
15539
15540 // C++ [temp.res]/8.4.2:
15541 // The program is ill-formed, no diagnostic required, if [...] lookup for
15542 // a name in the template definition found a using-declaration, but the
15543 // lookup in the corresponding scope in the instantiation odoes not find
15544 // any declarations because the using-declaration was a pack expansion and
15545 // the corresponding pack is empty
15546 if (AllEmptyPacks && !RequiresADL) {
15547 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15548 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15549 return true;
15550 }
15551
15552 // Resolve a kind, but don't do any further analysis. If it's
15553 // ambiguous, the callee needs to deal with it.
15554 R.resolveKind();
15555
15556 if (Old->hasTemplateKeyword() && !R.empty()) {
15557 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15558 getSema().FilterAcceptableTemplateNames(R,
15559 /*AllowFunctionTemplates=*/true,
15560 /*AllowDependent=*/true);
15561 if (R.empty()) {
15562 // If a 'template' keyword was used, a lookup that finds only non-template
15563 // names is an error.
15564 getSema().Diag(R.getNameLoc(),
15565 diag::err_template_kw_refers_to_non_template)
15566 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15567 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15568 getSema().Diag(FoundDecl->getLocation(),
15569 diag::note_template_kw_refers_to_non_template)
15570 << R.getLookupName();
15571 return true;
15572 }
15573 }
15574
15575 return false;
15576}
15577
15578template <typename Derived>
15579ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15580 UnresolvedLookupExpr *Old) {
15581 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15582}
15583
15584template <typename Derived>
15585ExprResult
15586TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15587 bool IsAddressOfOperand) {
15588 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15589 Sema::LookupOrdinaryName);
15590
15591 // Transform the declaration set.
15592 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15593 return ExprError();
15594
15595 // Rebuild the nested-name qualifier, if present.
15596 CXXScopeSpec SS;
15597 if (Old->getQualifierLoc()) {
15598 NestedNameSpecifierLoc QualifierLoc
15599 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15600 if (!QualifierLoc)
15601 return ExprError();
15602
15603 SS.Adopt(Other: QualifierLoc);
15604 }
15605
15606 if (Old->getNamingClass()) {
15607 CXXRecordDecl *NamingClass
15608 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15609 Old->getNameLoc(),
15610 Old->getNamingClass()));
15611 if (!NamingClass) {
15612 R.clear();
15613 return ExprError();
15614 }
15615
15616 R.setNamingClass(NamingClass);
15617 }
15618
15619 // Rebuild the template arguments, if any.
15620 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15621 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15622 if (Old->hasExplicitTemplateArgs() &&
15623 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15624 Old->getNumTemplateArgs(),
15625 TransArgs)) {
15626 R.clear();
15627 return ExprError();
15628 }
15629
15630 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15631 // a non-static data member is named in an unevaluated operand, or when
15632 // a member is named in a dependent class scope function template explicit
15633 // specialization that is neither declared static nor with an explicit object
15634 // parameter.
15635 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15636 return SemaRef.BuildPossibleImplicitMemberExpr(
15637 SS, TemplateKWLoc, R,
15638 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15639 /*S=*/S: nullptr);
15640
15641 // If we have neither explicit template arguments, nor the template keyword,
15642 // it's a normal declaration name or member reference.
15643 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15644 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15645
15646 // If we have template arguments, then rebuild the template-id expression.
15647 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15648 Old->requiresADL(), &TransArgs);
15649}
15650
15651template<typename Derived>
15652ExprResult
15653TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15654 bool ArgChanged = false;
15655 SmallVector<TypeSourceInfo *, 4> Args;
15656 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15657 TypeSourceInfo *From = E->getArg(I);
15658 TypeLoc FromTL = From->getTypeLoc();
15659 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15660 TypeLocBuilder TLB;
15661 TLB.reserve(Requested: FromTL.getFullDataSize());
15662 QualType To = getDerived().TransformType(TLB, FromTL);
15663 if (To.isNull())
15664 return ExprError();
15665
15666 if (To == From->getType())
15667 Args.push_back(Elt: From);
15668 else {
15669 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15670 ArgChanged = true;
15671 }
15672 continue;
15673 }
15674
15675 ArgChanged = true;
15676
15677 // We have a pack expansion. Instantiate it.
15678 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15679 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15680 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15681 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15682
15683 // Determine whether the set of unexpanded parameter packs can and should
15684 // be expanded.
15685 bool Expand = true;
15686 bool RetainExpansion = false;
15687 UnsignedOrNone OrigNumExpansions =
15688 ExpansionTL.getTypePtr()->getNumExpansions();
15689 UnsignedOrNone NumExpansions = OrigNumExpansions;
15690 if (getDerived().TryExpandParameterPacks(
15691 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15692 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15693 RetainExpansion, NumExpansions))
15694 return ExprError();
15695
15696 if (!Expand) {
15697 // The transform has determined that we should perform a simple
15698 // transformation on the pack expansion, producing another pack
15699 // expansion.
15700 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15701
15702 TypeLocBuilder TLB;
15703 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15704
15705 QualType To = getDerived().TransformType(TLB, PatternTL);
15706 if (To.isNull())
15707 return ExprError();
15708
15709 To = getDerived().RebuildPackExpansionType(To,
15710 PatternTL.getSourceRange(),
15711 ExpansionTL.getEllipsisLoc(),
15712 NumExpansions);
15713 if (To.isNull())
15714 return ExprError();
15715
15716 PackExpansionTypeLoc ToExpansionTL
15717 = TLB.push<PackExpansionTypeLoc>(T: To);
15718 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15719 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15720 continue;
15721 }
15722
15723 // Expand the pack expansion by substituting for each argument in the
15724 // pack(s).
15725 for (unsigned I = 0; I != *NumExpansions; ++I) {
15726 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15727 TypeLocBuilder TLB;
15728 TLB.reserve(Requested: PatternTL.getFullDataSize());
15729 QualType To = getDerived().TransformType(TLB, PatternTL);
15730 if (To.isNull())
15731 return ExprError();
15732
15733 if (To->containsUnexpandedParameterPack()) {
15734 To = getDerived().RebuildPackExpansionType(To,
15735 PatternTL.getSourceRange(),
15736 ExpansionTL.getEllipsisLoc(),
15737 NumExpansions);
15738 if (To.isNull())
15739 return ExprError();
15740
15741 PackExpansionTypeLoc ToExpansionTL
15742 = TLB.push<PackExpansionTypeLoc>(T: To);
15743 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15744 }
15745
15746 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15747 }
15748
15749 if (!RetainExpansion)
15750 continue;
15751
15752 // If we're supposed to retain a pack expansion, do so by temporarily
15753 // forgetting the partially-substituted parameter pack.
15754 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15755
15756 TypeLocBuilder TLB;
15757 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15758
15759 QualType To = getDerived().TransformType(TLB, PatternTL);
15760 if (To.isNull())
15761 return ExprError();
15762
15763 To = getDerived().RebuildPackExpansionType(To,
15764 PatternTL.getSourceRange(),
15765 ExpansionTL.getEllipsisLoc(),
15766 NumExpansions);
15767 if (To.isNull())
15768 return ExprError();
15769
15770 PackExpansionTypeLoc ToExpansionTL
15771 = TLB.push<PackExpansionTypeLoc>(T: To);
15772 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15773 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15774 }
15775
15776 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15777 return E;
15778
15779 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15780 E->getEndLoc());
15781}
15782
15783template<typename Derived>
15784ExprResult
15785TreeTransform<Derived>::TransformConceptSpecializationExpr(
15786 ConceptSpecializationExpr *E) {
15787 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15788 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15789 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15790 Old->NumTemplateArgs, TransArgs))
15791 return ExprError();
15792
15793 return getDerived().RebuildConceptSpecializationExpr(
15794 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15795 E->getConceptNameInfo(), E->getFoundDecl(), E->getConceptDecl(),
15796 &TransArgs);
15797}
15798
15799template<typename Derived>
15800ExprResult
15801TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15802 SmallVector<ParmVarDecl*, 4> TransParams;
15803 SmallVector<QualType, 4> TransParamTypes;
15804 Sema::ExtParameterInfoBuilder ExtParamInfos;
15805
15806 // C++2a [expr.prim.req]p2
15807 // Expressions appearing within a requirement-body are unevaluated operands.
15808 EnterExpressionEvaluationContext Ctx(
15809 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15810 Sema::ReuseLambdaContextDecl);
15811
15812 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15813 C&: getSema().Context, DC: getSema().CurContext,
15814 StartLoc: E->getBody()->getBeginLoc());
15815
15816 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15817
15818 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15819 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15820 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15821
15822 for (ParmVarDecl *Param : TransParams)
15823 if (Param)
15824 Param->setDeclContext(Body);
15825
15826 // On failure to transform, TransformRequiresTypeParams returns an expression
15827 // in the event that the transformation of the type params failed in some way.
15828 // It is expected that this will result in a 'not satisfied' Requires clause
15829 // when instantiating.
15830 if (!TypeParamResult.isUnset())
15831 return TypeParamResult;
15832
15833 SmallVector<concepts::Requirement *, 4> TransReqs;
15834 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15835 TransReqs))
15836 return ExprError();
15837
15838 for (concepts::Requirement *Req : TransReqs) {
15839 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15840 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15841 ER->getReturnTypeRequirement()
15842 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15843 ->setDeclContext(Body);
15844 }
15845 }
15846 }
15847
15848 return getDerived().RebuildRequiresExpr(
15849 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15850 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15851}
15852
15853template<typename Derived>
15854bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15855 ArrayRef<concepts::Requirement *> Reqs,
15856 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15857 for (concepts::Requirement *Req : Reqs) {
15858 concepts::Requirement *TransReq = nullptr;
15859 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15860 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15861 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15862 TransReq = getDerived().TransformExprRequirement(ExprReq);
15863 else
15864 TransReq = getDerived().TransformNestedRequirement(
15865 cast<concepts::NestedRequirement>(Val: Req));
15866 if (!TransReq)
15867 return true;
15868 Transformed.push_back(Elt: TransReq);
15869 }
15870 return false;
15871}
15872
15873template<typename Derived>
15874concepts::TypeRequirement *
15875TreeTransform<Derived>::TransformTypeRequirement(
15876 concepts::TypeRequirement *Req) {
15877 if (Req->isSubstitutionFailure()) {
15878 if (getDerived().AlwaysRebuild())
15879 return getDerived().RebuildTypeRequirement(
15880 Req->getSubstitutionDiagnostic());
15881 return Req;
15882 }
15883 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15884 if (!TransType)
15885 return nullptr;
15886 return getDerived().RebuildTypeRequirement(TransType);
15887}
15888
15889template<typename Derived>
15890concepts::ExprRequirement *
15891TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15892 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15893 if (Req->isExprSubstitutionFailure())
15894 TransExpr = Req->getExprSubstitutionDiagnostic();
15895 else {
15896 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15897 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15898 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15899 if (TransExprRes.isInvalid())
15900 return nullptr;
15901 TransExpr = TransExprRes.get();
15902 }
15903
15904 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15905 const auto &RetReq = Req->getReturnTypeRequirement();
15906 if (RetReq.isEmpty())
15907 TransRetReq.emplace();
15908 else if (RetReq.isSubstitutionFailure())
15909 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15910 else if (RetReq.isTypeConstraint()) {
15911 TemplateParameterList *OrigTPL =
15912 RetReq.getTypeConstraintTemplateParameterList();
15913 TemplateParameterList *TPL =
15914 getDerived().TransformTemplateParameterList(OrigTPL);
15915 if (!TPL)
15916 return nullptr;
15917 TransRetReq.emplace(args&: TPL);
15918 }
15919 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15920 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15921 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15922 Req->getNoexceptLoc(),
15923 std::move(*TransRetReq));
15924 return getDerived().RebuildExprRequirement(
15925 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15926 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15927}
15928
15929template<typename Derived>
15930concepts::NestedRequirement *
15931TreeTransform<Derived>::TransformNestedRequirement(
15932 concepts::NestedRequirement *Req) {
15933 if (Req->hasInvalidConstraint()) {
15934 if (getDerived().AlwaysRebuild())
15935 return getDerived().RebuildNestedRequirement(
15936 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15937 return Req;
15938 }
15939 ExprResult TransConstraint =
15940 getDerived().TransformExpr(Req->getConstraintExpr());
15941 if (TransConstraint.isInvalid())
15942 return nullptr;
15943 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15944}
15945
15946template<typename Derived>
15947ExprResult
15948TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15949 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15950 if (!T)
15951 return ExprError();
15952
15953 if (!getDerived().AlwaysRebuild() &&
15954 T == E->getQueriedTypeSourceInfo())
15955 return E;
15956
15957 ExprResult SubExpr;
15958 {
15959 EnterExpressionEvaluationContext Unevaluated(
15960 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15961 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15962 if (SubExpr.isInvalid())
15963 return ExprError();
15964 }
15965
15966 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15967 SubExpr.get(), E->getEndLoc());
15968}
15969
15970template<typename Derived>
15971ExprResult
15972TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15973 ExprResult SubExpr;
15974 {
15975 EnterExpressionEvaluationContext Unevaluated(
15976 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15977 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15978 if (SubExpr.isInvalid())
15979 return ExprError();
15980
15981 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15982 return E;
15983 }
15984
15985 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15986 SubExpr.get(), E->getEndLoc());
15987}
15988
15989template <typename Derived>
15990ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15991 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15992 TypeSourceInfo **RecoveryTSI) {
15993 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15994 DRE, AddrTaken, RecoveryTSI);
15995
15996 // Propagate both errors and recovered types, which return ExprEmpty.
15997 if (!NewDRE.isUsable())
15998 return NewDRE;
15999
16000 // We got an expr, wrap it up in parens.
16001 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
16002 return PE;
16003 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
16004 PE->getRParen());
16005}
16006
16007template <typename Derived>
16008ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16009 DependentScopeDeclRefExpr *E) {
16010 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
16011 nullptr);
16012}
16013
16014template <typename Derived>
16015ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
16016 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
16017 TypeSourceInfo **RecoveryTSI) {
16018 assert(E->getQualifierLoc());
16019 NestedNameSpecifierLoc QualifierLoc =
16020 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
16021 if (!QualifierLoc)
16022 return ExprError();
16023 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16024
16025 // TODO: If this is a conversion-function-id, verify that the
16026 // destination type name (if present) resolves the same way after
16027 // instantiation as it did in the local scope.
16028
16029 DeclarationNameInfo NameInfo =
16030 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
16031 if (!NameInfo.getName())
16032 return ExprError();
16033
16034 if (!E->hasExplicitTemplateArgs()) {
16035 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
16036 // Note: it is sufficient to compare the Name component of NameInfo:
16037 // if name has not changed, DNLoc has not changed either.
16038 NameInfo.getName() == E->getDeclName())
16039 return E;
16040
16041 return getDerived().RebuildDependentScopeDeclRefExpr(
16042 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
16043 IsAddressOfOperand, RecoveryTSI);
16044 }
16045
16046 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16047 if (getDerived().TransformTemplateArguments(
16048 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
16049 return ExprError();
16050
16051 return getDerived().RebuildDependentScopeDeclRefExpr(
16052 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
16053 RecoveryTSI);
16054}
16055
16056template<typename Derived>
16057ExprResult
16058TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
16059 // CXXConstructExprs other than for list-initialization and
16060 // CXXTemporaryObjectExpr are always implicit, so when we have
16061 // a 1-argument construction we just transform that argument.
16062 if (getDerived().AllowSkippingCXXConstructExpr() &&
16063 ((E->getNumArgs() == 1 ||
16064 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
16065 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
16066 !E->isListInitialization()))
16067 return getDerived().TransformInitializer(E->getArg(Arg: 0),
16068 /*DirectInit*/ false);
16069
16070 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
16071
16072 QualType T = getDerived().TransformType(E->getType());
16073 if (T.isNull())
16074 return ExprError();
16075
16076 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16077 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16078 if (!Constructor)
16079 return ExprError();
16080
16081 bool ArgumentChanged = false;
16082 SmallVector<Expr*, 8> Args;
16083 {
16084 EnterExpressionEvaluationContext Context(
16085 getSema(), EnterExpressionEvaluationContext::InitList,
16086 E->isListInitialization());
16087 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
16088 &ArgumentChanged))
16089 return ExprError();
16090 }
16091
16092 if (!getDerived().AlwaysRebuild() &&
16093 T == E->getType() &&
16094 Constructor == E->getConstructor() &&
16095 !ArgumentChanged) {
16096 // Mark the constructor as referenced.
16097 // FIXME: Instantiation-specific
16098 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16099 return E;
16100 }
16101
16102 return getDerived().RebuildCXXConstructExpr(
16103 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
16104 E->hadMultipleCandidates(), E->isListInitialization(),
16105 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
16106 E->getConstructionKind(), E->getParenOrBraceRange());
16107}
16108
16109template<typename Derived>
16110ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
16111 CXXInheritedCtorInitExpr *E) {
16112 QualType T = getDerived().TransformType(E->getType());
16113 if (T.isNull())
16114 return ExprError();
16115
16116 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16117 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16118 if (!Constructor)
16119 return ExprError();
16120
16121 if (!getDerived().AlwaysRebuild() &&
16122 T == E->getType() &&
16123 Constructor == E->getConstructor()) {
16124 // Mark the constructor as referenced.
16125 // FIXME: Instantiation-specific
16126 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16127 return E;
16128 }
16129
16130 return getDerived().RebuildCXXInheritedCtorInitExpr(
16131 T, E->getLocation(), Constructor,
16132 E->constructsVBase(), E->inheritedFromVBase());
16133}
16134
16135/// Transform a C++ temporary-binding expression.
16136///
16137/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
16138/// transform the subexpression and return that.
16139template<typename Derived>
16140ExprResult
16141TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
16142 if (auto *Dtor = E->getTemporary()->getDestructor())
16143 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
16144 Func: const_cast<CXXDestructorDecl *>(Dtor));
16145 return getDerived().TransformExpr(E->getSubExpr());
16146}
16147
16148/// Transform a C++ expression that contains cleanups that should
16149/// be run after the expression is evaluated.
16150///
16151/// Since ExprWithCleanups nodes are implicitly generated, we
16152/// just transform the subexpression and return that.
16153template<typename Derived>
16154ExprResult
16155TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
16156 return getDerived().TransformExpr(E->getSubExpr());
16157}
16158
16159template<typename Derived>
16160ExprResult
16161TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
16162 CXXTemporaryObjectExpr *E) {
16163 TypeSourceInfo *T =
16164 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16165 if (!T)
16166 return ExprError();
16167
16168 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
16169 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
16170 if (!Constructor)
16171 return ExprError();
16172
16173 bool ArgumentChanged = false;
16174 SmallVector<Expr*, 8> Args;
16175 Args.reserve(N: E->getNumArgs());
16176 {
16177 EnterExpressionEvaluationContext Context(
16178 getSema(), EnterExpressionEvaluationContext::InitList,
16179 E->isListInitialization());
16180 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
16181 ArgChanged: &ArgumentChanged))
16182 return ExprError();
16183
16184 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
16185 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
16186 /*IsExplicit=*/IsExplicit: true);
16187 if (Res.isInvalid())
16188 return ExprError();
16189 Args = {Res.get()};
16190 }
16191 }
16192
16193 if (!getDerived().AlwaysRebuild() &&
16194 T == E->getTypeSourceInfo() &&
16195 Constructor == E->getConstructor() &&
16196 !ArgumentChanged) {
16197 // FIXME: Instantiation-specific
16198 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
16199 return SemaRef.MaybeBindToTemporary(E);
16200 }
16201
16202 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
16203 return getDerived().RebuildCXXTemporaryObjectExpr(
16204 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
16205}
16206
16207template<typename Derived>
16208ExprResult
16209TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
16210 // Transform any init-capture expressions before entering the scope of the
16211 // lambda body, because they are not semantically within that scope.
16212 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
16213 struct TransformedInitCapture {
16214 // The location of the ... if the result is retaining a pack expansion.
16215 SourceLocation EllipsisLoc;
16216 // Zero or more expansions of the init-capture.
16217 SmallVector<InitCaptureInfoTy, 4> Expansions;
16218 };
16219 SmallVector<TransformedInitCapture, 4> InitCaptures;
16220 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
16221 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16222 CEnd = E->capture_end();
16223 C != CEnd; ++C) {
16224 if (!E->isInitCapture(Capture: C))
16225 continue;
16226
16227 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
16228 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16229
16230 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
16231 UnsignedOrNone NumExpansions) {
16232 ExprResult NewExprInitResult = getDerived().TransformInitializer(
16233 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
16234
16235 if (NewExprInitResult.isInvalid()) {
16236 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
16237 return;
16238 }
16239 Expr *NewExprInit = NewExprInitResult.get();
16240
16241 QualType NewInitCaptureType =
16242 getSema().buildLambdaInitCaptureInitialization(
16243 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
16244 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
16245 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
16246 VarDecl::CInit,
16247 NewExprInit);
16248 Result.Expansions.push_back(
16249 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
16250 };
16251
16252 // If this is an init-capture pack, consider expanding the pack now.
16253 if (OldVD->isParameterPack()) {
16254 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
16255 ->getTypeLoc()
16256 .castAs<PackExpansionTypeLoc>();
16257 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16258 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
16259
16260 // Determine whether the set of unexpanded parameter packs can and should
16261 // be expanded.
16262 bool Expand = true;
16263 bool RetainExpansion = false;
16264 UnsignedOrNone OrigNumExpansions =
16265 ExpansionTL.getTypePtr()->getNumExpansions();
16266 UnsignedOrNone NumExpansions = OrigNumExpansions;
16267 if (getDerived().TryExpandParameterPacks(
16268 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
16269 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
16270 RetainExpansion, NumExpansions))
16271 return ExprError();
16272 assert(!RetainExpansion && "Should not need to retain expansion after a "
16273 "capture since it cannot be extended");
16274 if (Expand) {
16275 for (unsigned I = 0; I != *NumExpansions; ++I) {
16276 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16277 SubstInitCapture(SourceLocation(), std::nullopt);
16278 }
16279 } else {
16280 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
16281 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
16282 }
16283 } else {
16284 SubstInitCapture(SourceLocation(), std::nullopt);
16285 }
16286 }
16287
16288 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
16289 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
16290
16291 // Create the local class that will describe the lambda.
16292
16293 // FIXME: DependencyKind below is wrong when substituting inside a templated
16294 // context that isn't a DeclContext (such as a variable template), or when
16295 // substituting an unevaluated lambda inside of a function's parameter's type
16296 // - as parameter types are not instantiated from within a function's DC. We
16297 // use evaluation contexts to distinguish the function parameter case.
16298 CXXRecordDecl::LambdaDependencyKind DependencyKind =
16299 CXXRecordDecl::LDK_Unknown;
16300 DeclContext *DC = getSema().CurContext;
16301 // A RequiresExprBodyDecl is not interesting for dependencies.
16302 // For the following case,
16303 //
16304 // template <typename>
16305 // concept C = requires { [] {}; };
16306 //
16307 // template <class F>
16308 // struct Widget;
16309 //
16310 // template <C F>
16311 // struct Widget<F> {};
16312 //
16313 // While we are substituting Widget<F>, the parent of DC would be
16314 // the template specialization itself. Thus, the lambda expression
16315 // will be deemed as dependent even if there are no dependent template
16316 // arguments.
16317 // (A ClassTemplateSpecializationDecl is always a dependent context.)
16318 while (DC->isRequiresExprBody() || isa<CXXExpansionStmtDecl>(Val: DC))
16319 DC = DC->getParent();
16320 if ((getSema().isUnevaluatedContext() ||
16321 getSema().isConstantEvaluatedContext()) &&
16322 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
16323 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
16324 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
16325 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
16326
16327 CXXRecordDecl *OldClass = E->getLambdaClass();
16328 CXXRecordDecl *Class = getSema().createLambdaClosureType(
16329 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
16330 E->getCaptureDefault());
16331 getDerived().transformedLocalDecl(OldClass, {Class});
16332
16333 CXXMethodDecl *NewCallOperator =
16334 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
16335
16336 // Enter the scope of the lambda.
16337 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
16338 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
16339 E->hasExplicitParameters(), E->isMutable());
16340
16341 // Introduce the context of the call operator.
16342 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
16343 /*NewThisContext*/false);
16344
16345 bool Invalid = false;
16346
16347 // Transform captures.
16348 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16349 CEnd = E->capture_end();
16350 C != CEnd; ++C) {
16351 // When we hit the first implicit capture, tell Sema that we've finished
16352 // the list of explicit captures.
16353 if (C->isImplicit())
16354 break;
16355
16356 // Capturing 'this' is trivial.
16357 if (C->capturesThis()) {
16358 // If this is a lambda that is part of a default member initialiser
16359 // and which we're instantiating outside the class that 'this' is
16360 // supposed to refer to, adjust the type of 'this' accordingly.
16361 //
16362 // Otherwise, leave the type of 'this' as-is.
16363 Sema::CXXThisScopeRAII ThisScope(
16364 getSema(),
16365 dyn_cast_if_present<CXXRecordDecl>(
16366 getSema().getFunctionLevelDeclContext()),
16367 Qualifiers());
16368 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16369 /*BuildAndDiagnose*/ true, nullptr,
16370 C->getCaptureKind() == LCK_StarThis);
16371 continue;
16372 }
16373 // Captured expression will be recaptured during captured variables
16374 // rebuilding.
16375 if (C->capturesVLAType())
16376 continue;
16377
16378 // Rebuild init-captures, including the implied field declaration.
16379 if (E->isInitCapture(Capture: C)) {
16380 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
16381
16382 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16383 llvm::SmallVector<Decl*, 4> NewVDs;
16384
16385 for (InitCaptureInfoTy &Info : NewC.Expansions) {
16386 ExprResult Init = Info.first;
16387 QualType InitQualType = Info.second;
16388 if (Init.isInvalid() || InitQualType.isNull()) {
16389 Invalid = true;
16390 break;
16391 }
16392 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
16393 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
16394 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
16395 getSema().CurContext);
16396 if (!NewVD) {
16397 Invalid = true;
16398 break;
16399 }
16400 NewVDs.push_back(Elt: NewVD);
16401 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
16402 // Cases we want to tackle:
16403 // ([C(Pack)] {}, ...)
16404 // But rule out cases e.g.
16405 // [...C = Pack()] {}
16406 if (NewC.EllipsisLoc.isInvalid())
16407 LSI->ContainsUnexpandedParameterPack |=
16408 Init.get()->containsUnexpandedParameterPack();
16409 }
16410
16411 if (Invalid)
16412 break;
16413
16414 getDerived().transformedLocalDecl(OldVD, NewVDs);
16415 continue;
16416 }
16417
16418 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16419
16420 // Determine the capture kind for Sema.
16421 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16422 : C->getCaptureKind() == LCK_ByCopy
16423 ? TryCaptureKind::ExplicitByVal
16424 : TryCaptureKind::ExplicitByRef;
16425 SourceLocation EllipsisLoc;
16426 if (C->isPackExpansion()) {
16427 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16428 bool ShouldExpand = false;
16429 bool RetainExpansion = false;
16430 UnsignedOrNone NumExpansions = std::nullopt;
16431 if (getDerived().TryExpandParameterPacks(
16432 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16433 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16434 RetainExpansion, NumExpansions)) {
16435 Invalid = true;
16436 continue;
16437 }
16438
16439 if (ShouldExpand) {
16440 // The transform has determined that we should perform an expansion;
16441 // transform and capture each of the arguments.
16442 // expansion of the pattern. Do so.
16443 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16444 for (unsigned I = 0; I != *NumExpansions; ++I) {
16445 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16446 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16447 getDerived().TransformDecl(C->getLocation(), Pack));
16448 if (!CapturedVar) {
16449 Invalid = true;
16450 continue;
16451 }
16452
16453 // Capture the transformed variable.
16454 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16455 }
16456
16457 // FIXME: Retain a pack expansion if RetainExpansion is true.
16458
16459 continue;
16460 }
16461
16462 EllipsisLoc = C->getEllipsisLoc();
16463 }
16464
16465 // Transform the captured variable.
16466 auto *CapturedVar = cast_or_null<ValueDecl>(
16467 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16468 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16469 Invalid = true;
16470 continue;
16471 }
16472
16473 // This is not an init-capture; however it contains an unexpanded pack e.g.
16474 // ([Pack] {}(), ...)
16475 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16476 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16477
16478 // Capture the transformed variable.
16479 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16480 EllipsisLoc);
16481 }
16482 getSema().finishLambdaExplicitCaptures(LSI);
16483
16484 // Transform the template parameters, and add them to the current
16485 // instantiation scope. The null case is handled correctly.
16486 auto TPL = getDerived().TransformTemplateParameterList(
16487 E->getTemplateParameterList());
16488 LSI->GLTemplateParameterList = TPL;
16489 if (TPL) {
16490 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16491 TPL);
16492 LSI->ContainsUnexpandedParameterPack |=
16493 TPL->containsUnexpandedParameterPack();
16494 }
16495
16496 TypeLocBuilder NewCallOpTLBuilder;
16497 TypeLoc OldCallOpTypeLoc =
16498 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16499 QualType NewCallOpType =
16500 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16501 if (NewCallOpType.isNull())
16502 return ExprError();
16503 LSI->ContainsUnexpandedParameterPack |=
16504 NewCallOpType->containsUnexpandedParameterPack();
16505 TypeSourceInfo *NewCallOpTSI =
16506 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16507
16508 // The type may be an AttributedType or some other kind of sugar;
16509 // get the actual underlying FunctionProtoType.
16510 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16511 assert(FPTL && "Not a FunctionProtoType?");
16512
16513 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16514 if (TRC) {
16515 ExprResult E = getDerived().TransformLambdaConstraint(
16516 const_cast<Expr *>(TRC.ConstraintExpr));
16517 if (E.isInvalid())
16518 return E;
16519 TRC.ConstraintExpr = E.get();
16520 }
16521
16522 LSI->BeforeCompoundStatement = false;
16523 getSema().CompleteLambdaCallOperator(
16524 NewCallOperator, E->getCallOperator()->getLocation(),
16525 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16526 E->getCallOperator()->getConstexprKind(),
16527 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16528 E->hasExplicitResultType());
16529
16530 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16531 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16532
16533 {
16534 // Number the lambda for linkage purposes if necessary.
16535 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16536
16537 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16538 if (getDerived().ReplacingOriginal()) {
16539 Numbering = OldClass->getLambdaNumbering();
16540 }
16541
16542 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16543 }
16544
16545 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16546 // evaluation context even if we're not transforming the function body.
16547 getSema().PushExpressionEvaluationContextForFunction(
16548 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16549 E->getCallOperator());
16550
16551 StmtResult Body;
16552 {
16553 Sema::NonSFINAEContext _(getSema());
16554 Sema::CodeSynthesisContext C;
16555 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16556 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16557 getSema().pushCodeSynthesisContext(C);
16558
16559 // Instantiate the body of the lambda expression.
16560 Body = Invalid ? StmtError()
16561 : getDerived().TransformLambdaBody(E, E->getBody());
16562
16563 getSema().popCodeSynthesisContext();
16564 }
16565
16566 // ActOnLambda* will pop the function scope for us.
16567 FuncScopeCleanup.disable();
16568
16569 if (Body.isInvalid()) {
16570 SavedContext.pop();
16571 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16572 /*IsInstantiation=*/true);
16573 return ExprError();
16574 }
16575
16576 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16577 /*IsInstantiation=*/true,
16578 /*RetainFunctionScopeInfo=*/true);
16579 SavedContext.pop();
16580
16581 // Recompute the dependency of the lambda so that we can defer the lambda call
16582 // construction until after we have all the necessary template arguments. For
16583 // example, given
16584 //
16585 // template <class> struct S {
16586 // template <class U>
16587 // using Type = decltype([](U){}(42.0));
16588 // };
16589 // void foo() {
16590 // using T = S<int>::Type<float>;
16591 // ^~~~~~
16592 // }
16593 //
16594 // We would end up here from instantiating S<int> when ensuring its
16595 // completeness. That would transform the lambda call expression regardless of
16596 // the absence of the corresponding argument for U.
16597 //
16598 // Going ahead with unsubstituted type U makes things worse: we would soon
16599 // compare the argument type (which is float) against the parameter U
16600 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16601 // error suggesting unmatched types 'U' and 'float'!
16602 //
16603 // That said, everything will be fine if we defer that semantic checking.
16604 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16605 // dependent. Since the CallExpr's dependency boils down to the lambda's
16606 // dependency in this case, we can harness that by recomputing the dependency
16607 // from the instantiation arguments.
16608 //
16609 // FIXME: Creating the type of a lambda requires us to have a dependency
16610 // value, which happens before its substitution. We update its dependency
16611 // *after* the substitution in case we can't decide the dependency
16612 // so early, e.g. because we want to see if any of the *substituted*
16613 // parameters are dependent.
16614 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16615 Class->setLambdaDependencyKind(DependencyKind);
16616
16617 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16618 Body.get()->getEndLoc(), LSI);
16619}
16620
16621template<typename Derived>
16622StmtResult
16623TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16624 return TransformStmt(S);
16625}
16626
16627template<typename Derived>
16628StmtResult
16629TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16630 // Transform captures.
16631 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16632 CEnd = E->capture_end();
16633 C != CEnd; ++C) {
16634 // When we hit the first implicit capture, tell Sema that we've finished
16635 // the list of explicit captures.
16636 if (!C->isImplicit())
16637 continue;
16638
16639 // Capturing 'this' is trivial.
16640 if (C->capturesThis()) {
16641 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16642 /*BuildAndDiagnose*/ true, nullptr,
16643 C->getCaptureKind() == LCK_StarThis);
16644 continue;
16645 }
16646 // Captured expression will be recaptured during captured variables
16647 // rebuilding.
16648 if (C->capturesVLAType())
16649 continue;
16650
16651 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16652 assert(!E->isInitCapture(C) && "implicit init-capture?");
16653
16654 // Transform the captured variable.
16655 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16656 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16657 if (!CapturedVar || CapturedVar->isInvalidDecl())
16658 return StmtError();
16659
16660 // Capture the transformed variable.
16661 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16662 }
16663
16664 return S;
16665}
16666
16667template<typename Derived>
16668ExprResult
16669TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16670 CXXUnresolvedConstructExpr *E) {
16671 TypeSourceInfo *T =
16672 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16673 if (!T)
16674 return ExprError();
16675
16676 bool ArgumentChanged = false;
16677 SmallVector<Expr*, 8> Args;
16678 Args.reserve(N: E->getNumArgs());
16679 {
16680 EnterExpressionEvaluationContext Context(
16681 getSema(), EnterExpressionEvaluationContext::InitList,
16682 E->isListInitialization());
16683 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16684 &ArgumentChanged))
16685 return ExprError();
16686 }
16687
16688 if (!getDerived().AlwaysRebuild() &&
16689 T == E->getTypeSourceInfo() &&
16690 !ArgumentChanged)
16691 return E;
16692
16693 // FIXME: we're faking the locations of the commas
16694 return getDerived().RebuildCXXUnresolvedConstructExpr(
16695 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16696}
16697
16698template <typename Derived>
16699ExprResult TreeTransform<Derived>::TransformDependentTemplateIdExpr(
16700 DependentTemplateIdExpr *E) {
16701
16702 TemplateName Name = getDerived().TransformConceptTemplateName(
16703 E->getTemplateName(), E->getNameLoc());
16704 if (Name.isNull())
16705 return ExprError();
16706
16707 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16708 if (getDerived().TransformTemplateArguments(
16709 E->template_arguments().data(), E->getNumTemplateArgs(), TransArgs))
16710 return ExprError();
16711
16712 TemplateDecl *TD = Name.getAsTemplateDecl();
16713 if (!TD)
16714 return SemaRef.CheckVarOrConceptTemplateTemplateId(NameInfo: E->getNameInfo(), Template: Name,
16715 TemplateArgs: &TransArgs);
16716
16717 CXXScopeSpec SS;
16718
16719 LookupResult R(SemaRef, E->getNameInfo(), Sema::LookupOrdinaryName);
16720 R.addDecl(D: TD);
16721 R.resolveKind();
16722 return getDerived().RebuildTemplateIdExpr(
16723 SS, /*Template Keyword=*/SourceLocation(), R,
16724 /*RequiresADL=*/false, &TransArgs);
16725}
16726
16727template<typename Derived>
16728ExprResult
16729TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16730 CXXDependentScopeMemberExpr *E) {
16731 // Transform the base of the expression.
16732 ExprResult Base((Expr*) nullptr);
16733 Expr *OldBase;
16734 QualType BaseType;
16735 QualType ObjectType;
16736 if (!E->isImplicitAccess()) {
16737 OldBase = E->getBase();
16738 Base = getDerived().TransformExpr(OldBase);
16739 if (Base.isInvalid())
16740 return ExprError();
16741
16742 // Start the member reference and compute the object's type.
16743 ParsedType ObjectTy;
16744 bool MayBePseudoDestructor = false;
16745 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16746 OpLoc: E->getOperatorLoc(),
16747 OpKind: E->isArrow()? tok::arrow : tok::period,
16748 ObjectType&: ObjectTy,
16749 MayBePseudoDestructor);
16750 if (Base.isInvalid())
16751 return ExprError();
16752
16753 ObjectType = ObjectTy.get();
16754 BaseType = ((Expr*) Base.get())->getType();
16755 } else {
16756 OldBase = nullptr;
16757 BaseType = getDerived().TransformType(E->getBaseType());
16758 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16759 }
16760
16761 // Transform the first part of the nested-name-specifier that qualifies
16762 // the member name.
16763 NamedDecl *FirstQualifierInScope
16764 = getDerived().TransformFirstQualifierInScope(
16765 E->getFirstQualifierFoundInScope(),
16766 E->getQualifierLoc().getBeginLoc());
16767
16768 NestedNameSpecifierLoc QualifierLoc;
16769 if (E->getQualifier()) {
16770 QualifierLoc
16771 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16772 ObjectType,
16773 FirstQualifierInScope);
16774 if (!QualifierLoc)
16775 return ExprError();
16776 }
16777
16778 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16779
16780 // TODO: If this is a conversion-function-id, verify that the
16781 // destination type name (if present) resolves the same way after
16782 // instantiation as it did in the local scope.
16783
16784 DeclarationNameInfo NameInfo
16785 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16786 if (!NameInfo.getName())
16787 return ExprError();
16788
16789 if (!E->hasExplicitTemplateArgs()) {
16790 // This is a reference to a member without an explicitly-specified
16791 // template argument list. Optimize for this common case.
16792 if (!getDerived().AlwaysRebuild() &&
16793 Base.get() == OldBase &&
16794 BaseType == E->getBaseType() &&
16795 QualifierLoc == E->getQualifierLoc() &&
16796 NameInfo.getName() == E->getMember() &&
16797 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16798 return E;
16799
16800 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16801 BaseType,
16802 E->isArrow(),
16803 E->getOperatorLoc(),
16804 QualifierLoc,
16805 TemplateKWLoc,
16806 FirstQualifierInScope,
16807 NameInfo,
16808 /*TemplateArgs*/nullptr);
16809 }
16810
16811 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16812 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16813 E->getNumTemplateArgs(),
16814 TransArgs))
16815 return ExprError();
16816
16817 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16818 BaseType,
16819 E->isArrow(),
16820 E->getOperatorLoc(),
16821 QualifierLoc,
16822 TemplateKWLoc,
16823 FirstQualifierInScope,
16824 NameInfo,
16825 &TransArgs);
16826}
16827
16828template <typename Derived>
16829ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16830 UnresolvedMemberExpr *Old) {
16831 // Transform the base of the expression.
16832 ExprResult Base((Expr *)nullptr);
16833 QualType BaseType;
16834 if (!Old->isImplicitAccess()) {
16835 Base = getDerived().TransformExpr(Old->getBase());
16836 if (Base.isInvalid())
16837 return ExprError();
16838 Base =
16839 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16840 if (Base.isInvalid())
16841 return ExprError();
16842 BaseType = Base.get()->getType();
16843 } else {
16844 BaseType = getDerived().TransformType(Old->getBaseType());
16845 }
16846
16847 NestedNameSpecifierLoc QualifierLoc;
16848 if (Old->getQualifierLoc()) {
16849 QualifierLoc =
16850 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16851 if (!QualifierLoc)
16852 return ExprError();
16853 }
16854
16855 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16856
16857 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16858
16859 // Transform the declaration set.
16860 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16861 return ExprError();
16862
16863 // Determine the naming class.
16864 if (Old->getNamingClass()) {
16865 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16866 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16867 if (!NamingClass)
16868 return ExprError();
16869
16870 R.setNamingClass(NamingClass);
16871 }
16872
16873 TemplateArgumentListInfo TransArgs;
16874 if (Old->hasExplicitTemplateArgs()) {
16875 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16876 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16877 if (getDerived().TransformTemplateArguments(
16878 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16879 return ExprError();
16880 }
16881
16882 // FIXME: to do this check properly, we will need to preserve the
16883 // first-qualifier-in-scope here, just in case we had a dependent
16884 // base (and therefore couldn't do the check) and a
16885 // nested-name-qualifier (and therefore could do the lookup).
16886 NamedDecl *FirstQualifierInScope = nullptr;
16887
16888 return getDerived().RebuildUnresolvedMemberExpr(
16889 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16890 TemplateKWLoc, FirstQualifierInScope, R,
16891 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16892}
16893
16894template<typename Derived>
16895ExprResult
16896TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16897 EnterExpressionEvaluationContext Unevaluated(
16898 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16899 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16900 if (SubExpr.isInvalid())
16901 return ExprError();
16902
16903 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16904 return E;
16905
16906 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16907}
16908
16909template<typename Derived>
16910ExprResult
16911TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16912 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16913 if (Pattern.isInvalid())
16914 return ExprError();
16915
16916 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16917 return E;
16918
16919 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16920 E->getNumExpansions());
16921}
16922
16923template <typename Derived>
16924UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16925 ArrayRef<TemplateArgument> PackArgs) {
16926 UnsignedOrNone Result = 0u;
16927 for (const TemplateArgument &Arg : PackArgs) {
16928 if (!Arg.isPackExpansion()) {
16929 Result = *Result + 1;
16930 continue;
16931 }
16932
16933 TemplateArgumentLoc ArgLoc;
16934 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16935
16936 // Find the pattern of the pack expansion.
16937 SourceLocation Ellipsis;
16938 UnsignedOrNone OrigNumExpansions = std::nullopt;
16939 TemplateArgumentLoc Pattern =
16940 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16941 OrigNumExpansions);
16942
16943 // Substitute under the pack expansion. Do not expand the pack (yet).
16944 TemplateArgumentLoc OutPattern;
16945 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16946 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16947 /*Uneval*/ true))
16948 return 1u;
16949
16950 // See if we can determine the number of arguments from the result.
16951 UnsignedOrNone NumExpansions =
16952 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16953 if (!NumExpansions) {
16954 // No: we must be in an alias template expansion, and we're going to
16955 // need to actually expand the packs.
16956 Result = std::nullopt;
16957 break;
16958 }
16959
16960 Result = *Result + *NumExpansions;
16961 }
16962 return Result;
16963}
16964
16965template<typename Derived>
16966ExprResult
16967TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16968 // If E is not value-dependent, then nothing will change when we transform it.
16969 // Note: This is an instantiation-centric view.
16970 if (!E->isValueDependent())
16971 return E;
16972
16973 EnterExpressionEvaluationContext Unevaluated(
16974 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16975
16976 ArrayRef<TemplateArgument> PackArgs;
16977 TemplateArgument ArgStorage;
16978
16979 // Find the argument list to transform.
16980 if (E->isPartiallySubstituted()) {
16981 PackArgs = E->getPartialArguments();
16982 } else if (E->isValueDependent()) {
16983 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16984 bool ShouldExpand = false;
16985 bool RetainExpansion = false;
16986 UnsignedOrNone NumExpansions = std::nullopt;
16987 if (getDerived().TryExpandParameterPacks(
16988 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16989 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16990 RetainExpansion, NumExpansions))
16991 return ExprError();
16992
16993 // If we need to expand the pack, build a template argument from it and
16994 // expand that.
16995 if (ShouldExpand) {
16996 auto *Pack = E->getPack();
16997 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16998 ArgStorage = getSema().Context.getPackExpansionType(
16999 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
17000 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
17001 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
17002 } else {
17003 auto *VD = cast<ValueDecl>(Val: Pack);
17004 ExprResult DRE = getSema().BuildDeclRefExpr(
17005 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
17006 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
17007 E->getPackLoc());
17008 if (DRE.isInvalid())
17009 return ExprError();
17010 ArgStorage = TemplateArgument(
17011 new (getSema().Context)
17012 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
17013 /*IsCanonical=*/false);
17014 }
17015 PackArgs = ArgStorage;
17016 }
17017 }
17018
17019 // If we're not expanding the pack, just transform the decl.
17020 if (!PackArgs.size()) {
17021 auto *Pack = cast_or_null<NamedDecl>(
17022 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
17023 if (!Pack)
17024 return ExprError();
17025 return getDerived().RebuildSizeOfPackExpr(
17026 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
17027 std::nullopt, {});
17028 }
17029
17030 // Try to compute the result without performing a partial substitution.
17031 UnsignedOrNone Result =
17032 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
17033
17034 // Common case: we could determine the number of expansions without
17035 // substituting.
17036 if (Result)
17037 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
17038 E->getPackLoc(),
17039 E->getRParenLoc(), *Result, {});
17040
17041 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
17042 E->getPackLoc());
17043 {
17044 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
17045 typedef TemplateArgumentLocInventIterator<
17046 Derived, const TemplateArgument*> PackLocIterator;
17047 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
17048 PackLocIterator(*this, PackArgs.end()),
17049 TransformedPackArgs, /*Uneval*/true))
17050 return ExprError();
17051 }
17052
17053 // Check whether we managed to fully-expand the pack.
17054 // FIXME: Is it possible for us to do so and not hit the early exit path?
17055 SmallVector<TemplateArgument, 8> Args;
17056 bool PartialSubstitution = false;
17057 for (auto &Loc : TransformedPackArgs.arguments()) {
17058 Args.push_back(Elt: Loc.getArgument());
17059 if (Loc.getArgument().isPackExpansion())
17060 PartialSubstitution = true;
17061 }
17062
17063 if (PartialSubstitution)
17064 return getDerived().RebuildSizeOfPackExpr(
17065 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17066 std::nullopt, Args);
17067
17068 return getDerived().RebuildSizeOfPackExpr(
17069 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
17070 /*Length=*/static_cast<unsigned>(Args.size()),
17071 /*PartialArgs=*/{});
17072}
17073
17074template <typename Derived>
17075ExprResult
17076TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
17077 if (!E->isValueDependent())
17078 return E;
17079
17080 // Transform the index
17081 ExprResult IndexExpr;
17082 {
17083 EnterExpressionEvaluationContext ConstantContext(
17084 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
17085 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
17086 if (IndexExpr.isInvalid())
17087 return ExprError();
17088 }
17089
17090 SmallVector<Expr *, 5> ExpandedExprs;
17091 bool FullySubstituted = true;
17092 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
17093 Expr *Pattern = E->getPackIdExpression();
17094 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17095 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
17096 Unexpanded);
17097 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17098
17099 // Determine whether the set of unexpanded parameter packs can and should
17100 // be expanded.
17101 bool ShouldExpand = true;
17102 bool RetainExpansion = false;
17103 UnsignedOrNone OrigNumExpansions = std::nullopt,
17104 NumExpansions = std::nullopt;
17105 if (getDerived().TryExpandParameterPacks(
17106 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17107 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
17108 RetainExpansion, NumExpansions))
17109 return true;
17110 if (!ShouldExpand) {
17111 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17112 ExprResult Pack = getDerived().TransformExpr(Pattern);
17113 if (Pack.isInvalid())
17114 return ExprError();
17115 return getDerived().RebuildPackIndexingExpr(
17116 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
17117 {}, /*FullySubstituted=*/false);
17118 }
17119 for (unsigned I = 0; I != *NumExpansions; ++I) {
17120 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17121 ExprResult Out = getDerived().TransformExpr(Pattern);
17122 if (Out.isInvalid())
17123 return true;
17124 if (Out.get()->containsUnexpandedParameterPack()) {
17125 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17126 OrigNumExpansions);
17127 if (Out.isInvalid())
17128 return true;
17129 FullySubstituted = false;
17130 }
17131 ExpandedExprs.push_back(Elt: Out.get());
17132 }
17133 // If we're supposed to retain a pack expansion, do so by temporarily
17134 // forgetting the partially-substituted parameter pack.
17135 if (RetainExpansion) {
17136 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17137
17138 ExprResult Out = getDerived().TransformExpr(Pattern);
17139 if (Out.isInvalid())
17140 return true;
17141
17142 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
17143 OrigNumExpansions);
17144 if (Out.isInvalid())
17145 return true;
17146 FullySubstituted = false;
17147 ExpandedExprs.push_back(Elt: Out.get());
17148 }
17149 } else if (!E->expandsToEmptyPack()) {
17150 if (getDerived().TransformExprs(E->getExpressions().data(),
17151 E->getExpressions().size(), false,
17152 ExpandedExprs))
17153 return ExprError();
17154 }
17155
17156 return getDerived().RebuildPackIndexingExpr(
17157 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
17158 IndexExpr.get(), ExpandedExprs, FullySubstituted);
17159}
17160
17161template <typename Derived>
17162ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
17163 SubstNonTypeTemplateParmPackExpr *E) {
17164 if (!getSema().ArgPackSubstIndex)
17165 // We aren't expanding the parameter pack, so just return ourselves.
17166 return E;
17167
17168 TemplateArgument Pack = E->getArgumentPack();
17169 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
17170 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17171 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
17172 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
17173 SemaRef.getPackIndex(Pack), E->getFinal());
17174}
17175
17176template <typename Derived>
17177ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
17178 SubstNonTypeTemplateParmExpr *E) {
17179 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
17180
17181 // Insert a constant-evaluated context for the transform.
17182 // Otherwise, when a normalized constraint places the replacement inside
17183 // an unevaluated operand (e.g. decltype), entities it refers to are not
17184 // odr-used, and the constant evaluation performed by CheckTemplateArgument
17185 // below can spuriously fail for otherwise valid replacements,
17186 // e.g. when a call materializes a function parameter of class type whose
17187 // special members were never instantiated.
17188 EnterExpressionEvaluationContext ConstantEvaluated(
17189 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
17190 Sema::ReuseLambdaContextDecl,
17191 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
17192
17193 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
17194 if (Replacement.isInvalid())
17195 return true;
17196
17197 Decl *AssociatedDecl =
17198 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
17199 if (!AssociatedDecl)
17200 return true;
17201
17202 QualType ParamType = TransformType(E->getParameterType());
17203 if (ParamType.isNull())
17204 return true;
17205
17206 if (Replacement.get() == OrigReplacement &&
17207 AssociatedDecl == E->getAssociatedDecl() &&
17208 ParamType == E->getParameterType())
17209 return E;
17210
17211 if (Replacement.get() != OrigReplacement ||
17212 ParamType != E->getParameterType()) {
17213 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
17214 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
17215 // When transforming the replacement expression previously, all Sema
17216 // specific annotations, such as implicit casts, are discarded. Calling the
17217 // corresponding sema action is necessary to recover those. Otherwise,
17218 // equivalency of the result would be lost.
17219 TemplateArgument SugaredConverted, CanonicalConverted;
17220 Replacement = SemaRef.CheckTemplateArgument(
17221 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
17222 CanonicalConverted,
17223 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
17224 if (Replacement.isInvalid())
17225 return true;
17226 } else {
17227 // Otherwise, the same expression would have been produced.
17228 Replacement = E->getReplacement();
17229 }
17230
17231 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17232 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
17233 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
17234 E->getPackIndex(), E->getFinal());
17235}
17236
17237template<typename Derived>
17238ExprResult
17239TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
17240 // Default behavior is to do nothing with this transformation.
17241 return E;
17242}
17243
17244template<typename Derived>
17245ExprResult
17246TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
17247 MaterializeTemporaryExpr *E) {
17248 return getDerived().TransformExpr(E->getSubExpr());
17249}
17250
17251template<typename Derived>
17252ExprResult
17253TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
17254 UnresolvedLookupExpr *Callee = nullptr;
17255 if (Expr *OldCallee = E->getCallee()) {
17256 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
17257 if (CalleeResult.isInvalid())
17258 return ExprError();
17259 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
17260 }
17261
17262 Expr *Pattern = E->getPattern();
17263
17264 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17265 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
17266 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17267
17268 // Determine whether the set of unexpanded parameter packs can and should
17269 // be expanded.
17270 bool Expand = true;
17271 bool RetainExpansion = false;
17272 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
17273 NumExpansions = OrigNumExpansions;
17274 if (getDerived().TryExpandParameterPacks(
17275 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17276 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17277 NumExpansions))
17278 return true;
17279
17280 if (!Expand) {
17281 // Do not expand any packs here, just transform and rebuild a fold
17282 // expression.
17283 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17284
17285 ExprResult LHS =
17286 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
17287 if (LHS.isInvalid())
17288 return true;
17289
17290 ExprResult RHS =
17291 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
17292 if (RHS.isInvalid())
17293 return true;
17294
17295 if (!getDerived().AlwaysRebuild() &&
17296 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
17297 return E;
17298
17299 return getDerived().RebuildCXXFoldExpr(
17300 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
17301 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
17302 }
17303
17304 // Formally a fold expression expands to nested parenthesized expressions.
17305 // Enforce this limit to avoid creating trees so deep we can't safely traverse
17306 // them.
17307 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
17308 SemaRef.Diag(Loc: E->getEllipsisLoc(),
17309 DiagID: clang::diag::err_fold_expression_limit_exceeded)
17310 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
17311 << E->getSourceRange();
17312 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
17313 return ExprError();
17314 }
17315
17316 // The transform has determined that we should perform an elementwise
17317 // expansion of the pattern. Do so.
17318 ExprResult Result = getDerived().TransformExpr(E->getInit());
17319 if (Result.isInvalid())
17320 return true;
17321 bool LeftFold = E->isLeftFold();
17322
17323 // If we're retaining an expansion for a right fold, it is the innermost
17324 // component and takes the init (if any).
17325 if (!LeftFold && RetainExpansion) {
17326 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17327
17328 ExprResult Out = getDerived().TransformExpr(Pattern);
17329 if (Out.isInvalid())
17330 return true;
17331
17332 Result = getDerived().RebuildCXXFoldExpr(
17333 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
17334 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
17335 if (Result.isInvalid())
17336 return true;
17337 }
17338
17339 bool WarnedOnComparison = false;
17340 for (unsigned I = 0; I != *NumExpansions; ++I) {
17341 Sema::ArgPackSubstIndexRAII SubstIndex(
17342 getSema(), LeftFold ? I : *NumExpansions - I - 1);
17343 ExprResult Out = getDerived().TransformExpr(Pattern);
17344 if (Out.isInvalid())
17345 return true;
17346
17347 if (Out.get()->containsUnexpandedParameterPack()) {
17348 // We still have a pack; retain a pack expansion for this slice.
17349 Result = getDerived().RebuildCXXFoldExpr(
17350 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
17351 E->getOperator(), E->getEllipsisLoc(),
17352 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
17353 OrigNumExpansions);
17354 } else if (Result.isUsable()) {
17355 // We've got down to a single element; build a binary operator.
17356 Expr *LHS = LeftFold ? Result.get() : Out.get();
17357 Expr *RHS = LeftFold ? Out.get() : Result.get();
17358 if (Callee) {
17359 UnresolvedSet<16> Functions;
17360 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
17361 Result = getDerived().RebuildCXXOperatorCallExpr(
17362 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
17363 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
17364 Functions, LHS, RHS);
17365 } else {
17366 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
17367 E->getOperator(), LHS, RHS,
17368 /*ForFoldExpresion=*/true);
17369 if (!WarnedOnComparison && Result.isUsable()) {
17370 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
17371 BO && BO->isComparisonOp()) {
17372 WarnedOnComparison = true;
17373 SemaRef.Diag(Loc: BO->getBeginLoc(),
17374 DiagID: diag::warn_comparison_in_fold_expression)
17375 << BO->getOpcodeStr();
17376 }
17377 }
17378 }
17379 } else
17380 Result = Out;
17381
17382 if (Result.isInvalid())
17383 return true;
17384 }
17385
17386 // If we're retaining an expansion for a left fold, it is the outermost
17387 // component and takes the complete expansion so far as its init (if any).
17388 if (LeftFold && RetainExpansion) {
17389 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17390
17391 ExprResult Out = getDerived().TransformExpr(Pattern);
17392 if (Out.isInvalid())
17393 return true;
17394
17395 Result = getDerived().RebuildCXXFoldExpr(
17396 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
17397 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
17398 if (Result.isInvalid())
17399 return true;
17400 }
17401
17402 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
17403 PE->setIsProducedByFoldExpansion();
17404
17405 // If we had no init and an empty pack, and we're not retaining an expansion,
17406 // then produce a fallback value or error.
17407 if (Result.isUnset())
17408 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
17409 E->getOperator());
17410 return Result;
17411}
17412
17413template <typename Derived>
17414ExprResult
17415TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
17416 SmallVector<Expr *, 4> TransformedInits;
17417 ArrayRef<Expr *> InitExprs = E->getInitExprs();
17418
17419 QualType T = getDerived().TransformType(E->getType());
17420
17421 bool ArgChanged = false;
17422
17423 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
17424 TransformedInits, &ArgChanged))
17425 return ExprError();
17426
17427 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
17428 return E;
17429
17430 return getDerived().RebuildCXXParenListInitExpr(
17431 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
17432 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
17433}
17434
17435template<typename Derived>
17436ExprResult
17437TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
17438 CXXStdInitializerListExpr *E) {
17439 return getDerived().TransformExpr(E->getSubExpr());
17440}
17441
17442template<typename Derived>
17443ExprResult
17444TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
17445 return SemaRef.MaybeBindToTemporary(E);
17446}
17447
17448template<typename Derived>
17449ExprResult
17450TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17451 return E;
17452}
17453
17454template<typename Derived>
17455ExprResult
17456TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17457 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17458 if (SubExpr.isInvalid())
17459 return ExprError();
17460
17461 if (!getDerived().AlwaysRebuild() &&
17462 SubExpr.get() == E->getSubExpr())
17463 return E;
17464
17465 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17466}
17467
17468template<typename Derived>
17469ExprResult
17470TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17471 // Transform each of the elements.
17472 SmallVector<Expr *, 8> Elements;
17473 bool ArgChanged = false;
17474 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17475 /*IsCall=*/false, Elements, &ArgChanged))
17476 return ExprError();
17477
17478 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17479 return SemaRef.MaybeBindToTemporary(E);
17480
17481 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17482 Elements.data(),
17483 Elements.size());
17484}
17485
17486template<typename Derived>
17487ExprResult
17488TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17489 ObjCDictionaryLiteral *E) {
17490 // Transform each of the elements.
17491 SmallVector<ObjCDictionaryElement, 8> Elements;
17492 bool ArgChanged = false;
17493 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17494 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17495
17496 if (OrigElement.isPackExpansion()) {
17497 // This key/value element is a pack expansion.
17498 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17499 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17500 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17501 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17502
17503 // Determine whether the set of unexpanded parameter packs can
17504 // and should be expanded.
17505 bool Expand = true;
17506 bool RetainExpansion = false;
17507 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17508 UnsignedOrNone NumExpansions = OrigNumExpansions;
17509 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17510 OrigElement.Value->getEndLoc());
17511 if (getDerived().TryExpandParameterPacks(
17512 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17513 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17514 NumExpansions))
17515 return ExprError();
17516
17517 if (!Expand) {
17518 // The transform has determined that we should perform a simple
17519 // transformation on the pack expansion, producing another pack
17520 // expansion.
17521 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17522 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17523 if (Key.isInvalid())
17524 return ExprError();
17525
17526 if (Key.get() != OrigElement.Key)
17527 ArgChanged = true;
17528
17529 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17530 if (Value.isInvalid())
17531 return ExprError();
17532
17533 if (Value.get() != OrigElement.Value)
17534 ArgChanged = true;
17535
17536 ObjCDictionaryElement Expansion = {
17537 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17538 };
17539 Elements.push_back(Elt: Expansion);
17540 continue;
17541 }
17542
17543 // Record right away that the argument was changed. This needs
17544 // to happen even if the array expands to nothing.
17545 ArgChanged = true;
17546
17547 // The transform has determined that we should perform an elementwise
17548 // expansion of the pattern. Do so.
17549 for (unsigned I = 0; I != *NumExpansions; ++I) {
17550 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17551 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17552 if (Key.isInvalid())
17553 return ExprError();
17554
17555 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17556 if (Value.isInvalid())
17557 return ExprError();
17558
17559 ObjCDictionaryElement Element = {
17560 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17561 };
17562
17563 // If any unexpanded parameter packs remain, we still have a
17564 // pack expansion.
17565 // FIXME: Can this really happen?
17566 if (Key.get()->containsUnexpandedParameterPack() ||
17567 Value.get()->containsUnexpandedParameterPack())
17568 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17569
17570 Elements.push_back(Elt: Element);
17571 }
17572
17573 // FIXME: Retain a pack expansion if RetainExpansion is true.
17574
17575 // We've finished with this pack expansion.
17576 continue;
17577 }
17578
17579 // Transform and check key.
17580 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17581 if (Key.isInvalid())
17582 return ExprError();
17583
17584 if (Key.get() != OrigElement.Key)
17585 ArgChanged = true;
17586
17587 // Transform and check value.
17588 ExprResult Value
17589 = getDerived().TransformExpr(OrigElement.Value);
17590 if (Value.isInvalid())
17591 return ExprError();
17592
17593 if (Value.get() != OrigElement.Value)
17594 ArgChanged = true;
17595
17596 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17597 .NumExpansions: std::nullopt};
17598 Elements.push_back(Elt: Element);
17599 }
17600
17601 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17602 return SemaRef.MaybeBindToTemporary(E);
17603
17604 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17605 Elements);
17606}
17607
17608template<typename Derived>
17609ExprResult
17610TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17611 TypeSourceInfo *EncodedTypeInfo
17612 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17613 if (!EncodedTypeInfo)
17614 return ExprError();
17615
17616 if (!getDerived().AlwaysRebuild() &&
17617 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17618 return E;
17619
17620 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17621 EncodedTypeInfo,
17622 E->getRParenLoc());
17623}
17624
17625template<typename Derived>
17626ExprResult TreeTransform<Derived>::
17627TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17628 // This is a kind of implicit conversion, and it needs to get dropped
17629 // and recomputed for the same general reasons that ImplicitCastExprs
17630 // do, as well a more specific one: this expression is only valid when
17631 // it appears *immediately* as an argument expression.
17632 return getDerived().TransformExpr(E->getSubExpr());
17633}
17634
17635template<typename Derived>
17636ExprResult TreeTransform<Derived>::
17637TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17638 TypeSourceInfo *TSInfo
17639 = getDerived().TransformType(E->getTypeInfoAsWritten());
17640 if (!TSInfo)
17641 return ExprError();
17642
17643 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17644 if (Result.isInvalid())
17645 return ExprError();
17646
17647 if (!getDerived().AlwaysRebuild() &&
17648 TSInfo == E->getTypeInfoAsWritten() &&
17649 Result.get() == E->getSubExpr())
17650 return E;
17651
17652 return SemaRef.ObjC().BuildObjCBridgedCast(
17653 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17654 SubExpr: Result.get());
17655}
17656
17657template <typename Derived>
17658ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17659 ObjCAvailabilityCheckExpr *E) {
17660 return E;
17661}
17662
17663template<typename Derived>
17664ExprResult
17665TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17666 // Transform arguments.
17667 bool ArgChanged = false;
17668 SmallVector<Expr*, 8> Args;
17669 Args.reserve(N: E->getNumArgs());
17670 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17671 &ArgChanged))
17672 return ExprError();
17673
17674 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17675 // Class message: transform the receiver type.
17676 TypeSourceInfo *ReceiverTypeInfo
17677 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17678 if (!ReceiverTypeInfo)
17679 return ExprError();
17680
17681 // If nothing changed, just retain the existing message send.
17682 if (!getDerived().AlwaysRebuild() &&
17683 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17684 return SemaRef.MaybeBindToTemporary(E);
17685
17686 // Build a new class message send.
17687 SmallVector<SourceLocation, 16> SelLocs;
17688 E->getSelectorLocs(SelLocs);
17689 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17690 E->getSelector(),
17691 SelLocs,
17692 E->getMethodDecl(),
17693 E->getLeftLoc(),
17694 Args,
17695 E->getRightLoc());
17696 }
17697 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17698 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17699 if (!E->getMethodDecl())
17700 return ExprError();
17701
17702 // Build a new class message send to 'super'.
17703 SmallVector<SourceLocation, 16> SelLocs;
17704 E->getSelectorLocs(SelLocs);
17705 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17706 E->getSelector(),
17707 SelLocs,
17708 E->getReceiverType(),
17709 E->getMethodDecl(),
17710 E->getLeftLoc(),
17711 Args,
17712 E->getRightLoc());
17713 }
17714
17715 // Instance message: transform the receiver
17716 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17717 "Only class and instance messages may be instantiated");
17718 ExprResult Receiver
17719 = getDerived().TransformExpr(E->getInstanceReceiver());
17720 if (Receiver.isInvalid())
17721 return ExprError();
17722
17723 // If nothing changed, just retain the existing message send.
17724 if (!getDerived().AlwaysRebuild() &&
17725 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17726 return SemaRef.MaybeBindToTemporary(E);
17727
17728 // Build a new instance message send.
17729 SmallVector<SourceLocation, 16> SelLocs;
17730 E->getSelectorLocs(SelLocs);
17731 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17732 E->getSelector(),
17733 SelLocs,
17734 E->getMethodDecl(),
17735 E->getLeftLoc(),
17736 Args,
17737 E->getRightLoc());
17738}
17739
17740template<typename Derived>
17741ExprResult
17742TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17743 return E;
17744}
17745
17746template<typename Derived>
17747ExprResult
17748TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17749 return E;
17750}
17751
17752template<typename Derived>
17753ExprResult
17754TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17755 // Transform the base expression.
17756 ExprResult Base = getDerived().TransformExpr(E->getBase());
17757 if (Base.isInvalid())
17758 return ExprError();
17759
17760 // We don't need to transform the ivar; it will never change.
17761
17762 // If nothing changed, just retain the existing expression.
17763 if (!getDerived().AlwaysRebuild() &&
17764 Base.get() == E->getBase())
17765 return E;
17766
17767 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17768 E->getLocation(),
17769 E->isArrow(), E->isFreeIvar());
17770}
17771
17772template<typename Derived>
17773ExprResult
17774TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17775 // 'super' and types never change. Property never changes. Just
17776 // retain the existing expression.
17777 if (!E->isObjectReceiver())
17778 return E;
17779
17780 // Transform the base expression.
17781 ExprResult Base = getDerived().TransformExpr(E->getBase());
17782 if (Base.isInvalid())
17783 return ExprError();
17784
17785 // We don't need to transform the property; it will never change.
17786
17787 // If nothing changed, just retain the existing expression.
17788 if (!getDerived().AlwaysRebuild() &&
17789 Base.get() == E->getBase())
17790 return E;
17791
17792 if (E->isExplicitProperty())
17793 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17794 E->getExplicitProperty(),
17795 E->getLocation());
17796
17797 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17798 SemaRef.Context.PseudoObjectTy,
17799 E->getImplicitPropertyGetter(),
17800 E->getImplicitPropertySetter(),
17801 E->getLocation());
17802}
17803
17804template<typename Derived>
17805ExprResult
17806TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17807 // Transform the base expression.
17808 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17809 if (Base.isInvalid())
17810 return ExprError();
17811
17812 // Transform the key expression.
17813 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17814 if (Key.isInvalid())
17815 return ExprError();
17816
17817 // If nothing changed, just retain the existing expression.
17818 if (!getDerived().AlwaysRebuild() &&
17819 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17820 return E;
17821
17822 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17823 Base.get(), Key.get(),
17824 E->getAtIndexMethodDecl(),
17825 E->setAtIndexMethodDecl());
17826}
17827
17828template<typename Derived>
17829ExprResult
17830TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17831 // Transform the base expression.
17832 ExprResult Base = getDerived().TransformExpr(E->getBase());
17833 if (Base.isInvalid())
17834 return ExprError();
17835
17836 // If nothing changed, just retain the existing expression.
17837 if (!getDerived().AlwaysRebuild() &&
17838 Base.get() == E->getBase())
17839 return E;
17840
17841 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17842 E->getOpLoc(),
17843 E->isArrow());
17844}
17845
17846template<typename Derived>
17847ExprResult
17848TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17849 bool ArgumentChanged = false;
17850 SmallVector<Expr*, 8> SubExprs;
17851 SubExprs.reserve(N: E->getNumSubExprs());
17852 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17853 SubExprs, &ArgumentChanged))
17854 return ExprError();
17855
17856 if (!getDerived().AlwaysRebuild() &&
17857 !ArgumentChanged)
17858 return E;
17859
17860 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17861 SubExprs,
17862 E->getRParenLoc());
17863}
17864
17865template<typename Derived>
17866ExprResult
17867TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17868 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17869 if (SrcExpr.isInvalid())
17870 return ExprError();
17871
17872 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17873 if (!Type)
17874 return ExprError();
17875
17876 if (!getDerived().AlwaysRebuild() &&
17877 Type == E->getTypeSourceInfo() &&
17878 SrcExpr.get() == E->getSrcExpr())
17879 return E;
17880
17881 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17882 SrcExpr.get(), Type,
17883 E->getRParenLoc());
17884}
17885
17886template<typename Derived>
17887ExprResult
17888TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17889 BlockDecl *oldBlock = E->getBlockDecl();
17890
17891 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17892 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17893
17894 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17895 blockScope->TheDecl->setBlockMissingReturnType(
17896 oldBlock->blockMissingReturnType());
17897
17898 SmallVector<ParmVarDecl*, 4> params;
17899 SmallVector<QualType, 4> paramTypes;
17900
17901 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17902
17903 // Parameter substitution.
17904 Sema::ExtParameterInfoBuilder extParamInfos;
17905 if (getDerived().TransformFunctionTypeParams(
17906 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17907 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17908 extParamInfos)) {
17909 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17910 return ExprError();
17911 }
17912
17913 QualType exprResultType =
17914 getDerived().TransformType(exprFunctionType->getReturnType());
17915
17916 auto epi = exprFunctionType->getExtProtoInfo();
17917 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17918
17919 QualType functionType =
17920 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17921 blockScope->FunctionType = functionType;
17922
17923 // Set the parameters on the block decl.
17924 if (!params.empty())
17925 blockScope->TheDecl->setParams(params);
17926
17927 if (!oldBlock->blockMissingReturnType()) {
17928 blockScope->HasImplicitReturnType = false;
17929 blockScope->ReturnType = exprResultType;
17930 }
17931
17932 // Transform the body
17933 StmtResult body = getDerived().TransformStmt(E->getBody());
17934 if (body.isInvalid()) {
17935 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17936 return ExprError();
17937 }
17938
17939#ifndef NDEBUG
17940 // In builds with assertions, make sure that we captured everything we
17941 // captured before.
17942 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17943 for (const auto &I : oldBlock->captures()) {
17944 VarDecl *oldCapture = I.getVariable();
17945
17946 // Ignore parameter packs.
17947 if (oldCapture->isParameterPack())
17948 continue;
17949
17950 VarDecl *newCapture =
17951 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17952 oldCapture));
17953 assert(blockScope->CaptureMap.count(newCapture));
17954 }
17955 }
17956#endif
17957
17958 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17959 /*Scope=*/CurScope: nullptr);
17960}
17961
17962template<typename Derived>
17963ExprResult
17964TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17965 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17966 if (SrcExpr.isInvalid())
17967 return ExprError();
17968
17969 QualType Type = getDerived().TransformType(E->getType());
17970
17971 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17972 RParenLoc: E->getRParenLoc());
17973}
17974
17975template<typename Derived>
17976ExprResult
17977TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17978 bool ArgumentChanged = false;
17979 SmallVector<Expr*, 8> SubExprs;
17980 SubExprs.reserve(N: E->getNumSubExprs());
17981 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17982 SubExprs, &ArgumentChanged))
17983 return ExprError();
17984
17985 if (!getDerived().AlwaysRebuild() &&
17986 !ArgumentChanged)
17987 return E;
17988
17989 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17990 E->getOp(), E->getRParenLoc());
17991}
17992
17993//===----------------------------------------------------------------------===//
17994// Type reconstruction
17995//===----------------------------------------------------------------------===//
17996
17997template<typename Derived>
17998QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17999 SourceLocation Star) {
18000 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
18001 Entity: getDerived().getBaseEntity());
18002}
18003
18004template<typename Derived>
18005QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
18006 SourceLocation Star) {
18007 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
18008 Entity: getDerived().getBaseEntity());
18009}
18010
18011template<typename Derived>
18012QualType
18013TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
18014 bool WrittenAsLValue,
18015 SourceLocation Sigil) {
18016 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
18017 Loc: Sigil, Entity: getDerived().getBaseEntity());
18018}
18019
18020template <typename Derived>
18021QualType TreeTransform<Derived>::RebuildMemberPointerType(
18022 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
18023 SourceLocation Sigil) {
18024 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
18025 Entity: getDerived().getBaseEntity());
18026}
18027
18028template<typename Derived>
18029QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
18030 const ObjCTypeParamDecl *Decl,
18031 SourceLocation ProtocolLAngleLoc,
18032 ArrayRef<ObjCProtocolDecl *> Protocols,
18033 ArrayRef<SourceLocation> ProtocolLocs,
18034 SourceLocation ProtocolRAngleLoc) {
18035 return SemaRef.ObjC().BuildObjCTypeParamType(
18036 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18037 /*FailOnError=*/FailOnError: true);
18038}
18039
18040template<typename Derived>
18041QualType TreeTransform<Derived>::RebuildObjCObjectType(
18042 QualType BaseType,
18043 SourceLocation Loc,
18044 SourceLocation TypeArgsLAngleLoc,
18045 ArrayRef<TypeSourceInfo *> TypeArgs,
18046 SourceLocation TypeArgsRAngleLoc,
18047 SourceLocation ProtocolLAngleLoc,
18048 ArrayRef<ObjCProtocolDecl *> Protocols,
18049 ArrayRef<SourceLocation> ProtocolLocs,
18050 SourceLocation ProtocolRAngleLoc) {
18051 return SemaRef.ObjC().BuildObjCObjectType(
18052 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
18053 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
18054 /*FailOnError=*/FailOnError: true,
18055 /*Rebuilding=*/Rebuilding: true);
18056}
18057
18058template<typename Derived>
18059QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
18060 QualType PointeeType,
18061 SourceLocation Star) {
18062 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
18063}
18064
18065template <typename Derived>
18066QualType TreeTransform<Derived>::RebuildArrayType(
18067 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
18068 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18069 if (SizeExpr || !Size)
18070 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
18071 Quals: IndexTypeQuals, Brackets: BracketsRange,
18072 Entity: getDerived().getBaseEntity());
18073
18074 QualType Types[] = {
18075 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
18076 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
18077 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
18078 };
18079 QualType SizeType;
18080 for (const auto &T : Types)
18081 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
18082 SizeType = T;
18083 break;
18084 }
18085
18086 // Note that we can return a VariableArrayType here in the case where
18087 // the element type was a dependent VariableArrayType.
18088 IntegerLiteral *ArraySize
18089 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
18090 /*FIXME*/l: BracketsRange.getBegin());
18091 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
18092 Quals: IndexTypeQuals, Brackets: BracketsRange,
18093 Entity: getDerived().getBaseEntity());
18094}
18095
18096template <typename Derived>
18097QualType TreeTransform<Derived>::RebuildConstantArrayType(
18098 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
18099 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
18100 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
18101 IndexTypeQuals, BracketsRange);
18102}
18103
18104template <typename Derived>
18105QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
18106 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
18107 SourceRange BracketsRange) {
18108 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
18109 IndexTypeQuals, BracketsRange);
18110}
18111
18112template <typename Derived>
18113QualType TreeTransform<Derived>::RebuildVariableArrayType(
18114 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18115 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18116 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18117 SizeExpr,
18118 IndexTypeQuals, BracketsRange);
18119}
18120
18121template <typename Derived>
18122QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
18123 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
18124 unsigned IndexTypeQuals, SourceRange BracketsRange) {
18125 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
18126 SizeExpr,
18127 IndexTypeQuals, BracketsRange);
18128}
18129
18130template <typename Derived>
18131QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
18132 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
18133 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
18134 AttrLoc: AttributeLoc);
18135}
18136
18137template <typename Derived>
18138QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
18139 unsigned NumElements,
18140 VectorKind VecKind) {
18141 // FIXME: semantic checking!
18142 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
18143}
18144
18145template <typename Derived>
18146QualType TreeTransform<Derived>::RebuildDependentVectorType(
18147 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
18148 VectorKind VecKind) {
18149 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
18150}
18151
18152template<typename Derived>
18153QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
18154 unsigned NumElements,
18155 SourceLocation AttributeLoc) {
18156 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18157 NumElements, true);
18158 IntegerLiteral *VectorSize
18159 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
18160 l: AttributeLoc);
18161 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
18162}
18163
18164template<typename Derived>
18165QualType
18166TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
18167 Expr *SizeExpr,
18168 SourceLocation AttributeLoc) {
18169 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
18170}
18171
18172template <typename Derived>
18173QualType TreeTransform<Derived>::RebuildConstantMatrixType(
18174 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
18175 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
18176 NumColumns);
18177}
18178
18179template <typename Derived>
18180QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
18181 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
18182 SourceLocation AttributeLoc) {
18183 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
18184 AttrLoc: AttributeLoc);
18185}
18186
18187template <typename Derived>
18188QualType TreeTransform<Derived>::RebuildFunctionProtoType(
18189 QualType T, MutableArrayRef<QualType> ParamTypes,
18190 const FunctionProtoType::ExtProtoInfo &EPI) {
18191 return SemaRef.BuildFunctionType(T, ParamTypes,
18192 Loc: getDerived().getBaseLocation(),
18193 Entity: getDerived().getBaseEntity(),
18194 EPI);
18195}
18196
18197template<typename Derived>
18198QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
18199 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
18200}
18201
18202template <typename Derived>
18203QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
18204 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
18205 SourceLocation NameLoc, Decl *D) {
18206 assert(D && "no decl found");
18207 if (D->isInvalidDecl()) return QualType();
18208
18209 // FIXME: Doesn't account for ObjCInterfaceDecl!
18210 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
18211 // A valid resolved using typename pack expansion decl can have multiple
18212 // UsingDecls, but they must each have exactly one type, and it must be
18213 // the same type in every case. But we must have at least one expansion!
18214 if (UPD->expansions().empty()) {
18215 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
18216 << UPD->isCXXClassMember() << UPD;
18217 return QualType();
18218 }
18219
18220 // We might still have some unresolved types. Try to pick a resolved type
18221 // if we can. The final instantiation will check that the remaining
18222 // unresolved types instantiate to the type we pick.
18223 QualType FallbackT;
18224 QualType T;
18225 for (auto *E : UPD->expansions()) {
18226 QualType ThisT =
18227 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
18228 if (ThisT.isNull())
18229 continue;
18230 if (ThisT->getAs<UnresolvedUsingType>())
18231 FallbackT = ThisT;
18232 else if (T.isNull())
18233 T = ThisT;
18234 else
18235 assert(getSema().Context.hasSameType(ThisT, T) &&
18236 "mismatched resolved types in using pack expansion");
18237 }
18238 return T.isNull() ? FallbackT : T;
18239 }
18240 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
18241 assert(Using->hasTypename() &&
18242 "UnresolvedUsingTypenameDecl transformed to non-typename using");
18243
18244 // A valid resolved using typename decl points to exactly one type decl.
18245 assert(++Using->shadow_begin() == Using->shadow_end());
18246
18247 UsingShadowDecl *Shadow = *Using->shadow_begin();
18248 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
18249 return QualType();
18250 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
18251 }
18252 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
18253 "UnresolvedUsingTypenameDecl transformed to non-using decl");
18254 return SemaRef.Context.getUnresolvedUsingType(
18255 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
18256}
18257
18258template <typename Derived>
18259QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
18260 TypeOfKind Kind) {
18261 return SemaRef.BuildTypeofExprType(E, Kind);
18262}
18263
18264template<typename Derived>
18265QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
18266 TypeOfKind Kind) {
18267 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
18268}
18269
18270template <typename Derived>
18271QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
18272 return SemaRef.BuildDecltypeType(E);
18273}
18274
18275template <typename Derived>
18276QualType TreeTransform<Derived>::RebuildPackIndexingType(
18277 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
18278 SourceLocation EllipsisLoc, bool FullySubstituted,
18279 ArrayRef<QualType> Expansions) {
18280 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
18281 FullySubstituted, Expansions);
18282}
18283
18284template<typename Derived>
18285QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
18286 UnaryTransformType::UTTKind UKind,
18287 SourceLocation Loc) {
18288 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
18289}
18290
18291template <typename Derived>
18292QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
18293 ElaboratedTypeKeyword Keyword, TemplateName Template,
18294 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
18295 return SemaRef.CheckTemplateIdType(
18296 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
18297 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
18298}
18299
18300template<typename Derived>
18301QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
18302 SourceLocation KWLoc) {
18303 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
18304}
18305
18306template<typename Derived>
18307QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
18308 SourceLocation KWLoc,
18309 bool isReadPipe) {
18310 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
18311 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
18312}
18313
18314template <typename Derived>
18315QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
18316 unsigned NumBits,
18317 SourceLocation Loc) {
18318 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18319 NumBits, true);
18320 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
18321 type: SemaRef.Context.IntTy, l: Loc);
18322 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
18323}
18324
18325template <typename Derived>
18326QualType TreeTransform<Derived>::RebuildDependentBitIntType(
18327 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
18328 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
18329}
18330
18331template <typename Derived>
18332TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18333 bool TemplateKW,
18334 TemplateName Name) {
18335 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
18336 Template: Name);
18337}
18338
18339template <typename Derived>
18340TemplateName TreeTransform<Derived>::RebuildTemplateName(
18341 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
18342 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
18343 UnqualifiedId TemplateName;
18344 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
18345 Sema::TemplateTy Template;
18346 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
18347 TemplateName, ParsedType::make(P: ObjectType),
18348 /*EnteringContext=*/false, Template,
18349 AllowInjectedClassName);
18350 return Template.get();
18351}
18352
18353template<typename Derived>
18354TemplateName
18355TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18356 SourceLocation TemplateKWLoc,
18357 OverloadedOperatorKind Operator,
18358 SourceLocation NameLoc,
18359 QualType ObjectType,
18360 bool AllowInjectedClassName) {
18361 UnqualifiedId Name;
18362 // FIXME: Bogus location information.
18363 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
18364 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
18365 Sema::TemplateTy Template;
18366 getSema().ActOnTemplateName(
18367 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
18368 /*EnteringContext=*/false, Template, AllowInjectedClassName);
18369 return Template.get();
18370}
18371
18372template <typename Derived>
18373ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
18374 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
18375 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
18376 Expr *Second) {
18377 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
18378
18379 if (First->getObjectKind() == OK_ObjCProperty) {
18380 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18381 if (BinaryOperator::isAssignmentOp(Opc))
18382 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
18383 Opcode: Opc, LHS: First, RHS: Second);
18384 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
18385 if (Result.isInvalid())
18386 return ExprError();
18387 First = Result.get();
18388 }
18389
18390 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
18391 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
18392 if (Result.isInvalid())
18393 return ExprError();
18394 Second = Result.get();
18395 }
18396
18397 // Determine whether this should be a builtin operation.
18398 if (Op == OO_Subscript) {
18399 if (!First->getType()->isOverloadableType() &&
18400 !Second->getType()->isOverloadableType())
18401 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
18402 OpLoc);
18403 } else if (Op == OO_Arrow) {
18404 // It is possible that the type refers to a RecoveryExpr created earlier
18405 // in the tree transformation.
18406 if (First->getType()->isDependentType())
18407 return ExprError();
18408 // -> is never a builtin operation.
18409 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
18410 } else if (Second == nullptr || isPostIncDec) {
18411 if (!First->getType()->isOverloadableType() ||
18412 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
18413 // The argument is not of overloadable type, or this is an expression
18414 // of the form &Class::member, so try to create a built-in unary
18415 // operation.
18416 UnaryOperatorKind Opc
18417 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18418
18419 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
18420 }
18421 } else {
18422 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
18423 !First->getType()->isOverloadableType() &&
18424 !Second->getType()->isOverloadableType()) {
18425 // Neither of the arguments is type-dependent or has an overloadable
18426 // type, so try to create a built-in binary operation.
18427 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18428 ExprResult Result
18429 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
18430 if (Result.isInvalid())
18431 return ExprError();
18432
18433 return Result;
18434 }
18435 }
18436
18437 // Create the overloaded operator invocation for unary operators.
18438 if (!Second || isPostIncDec) {
18439 UnaryOperatorKind Opc
18440 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18441 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18442 RequiresADL);
18443 }
18444
18445 // Create the overloaded operator invocation for binary operators.
18446 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18447 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18448 LHS: First, RHS: Second, RequiresADL);
18449 if (Result.isInvalid())
18450 return ExprError();
18451
18452 return Result;
18453}
18454
18455template<typename Derived>
18456ExprResult
18457TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18458 SourceLocation OperatorLoc,
18459 bool isArrow,
18460 CXXScopeSpec &SS,
18461 TypeSourceInfo *ScopeType,
18462 SourceLocation CCLoc,
18463 SourceLocation TildeLoc,
18464 PseudoDestructorTypeStorage Destroyed) {
18465 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18466 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18467 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18468 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18469 !cast<PointerType>(Val&: CanonicalBaseType)
18470 ->getPointeeType()
18471 ->getAsCanonical<RecordType>())) {
18472 // This pseudo-destructor expression is still a pseudo-destructor.
18473 return SemaRef.BuildPseudoDestructorExpr(
18474 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18475 CCLoc, TildeLoc, DestroyedType: Destroyed);
18476 }
18477
18478 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18479 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18480 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18481 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18482 NameInfo.setNamedTypeInfo(DestroyedType);
18483
18484 // The scope type is now known to be a valid nested name specifier
18485 // component. Tack it on to the nested name specifier.
18486 if (ScopeType) {
18487 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18488 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18489 diag::err_expected_class_or_namespace)
18490 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18491 return ExprError();
18492 }
18493 SS.clear();
18494 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18495 }
18496
18497 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18498 return getSema().BuildMemberReferenceExpr(
18499 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18500 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18501 /*TemplateArgs*/ nullptr,
18502 /*S*/ nullptr);
18503}
18504
18505template<typename Derived>
18506StmtResult
18507TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18508 SourceLocation Loc = S->getBeginLoc();
18509 CapturedDecl *CD = S->getCapturedDecl();
18510 unsigned NumParams = CD->getNumParams();
18511 unsigned ContextParamPos = CD->getContextParamPosition();
18512 SmallVector<Sema::CapturedParamNameType, 4> Params;
18513 for (unsigned I = 0; I < NumParams; ++I) {
18514 if (I != ContextParamPos) {
18515 Params.push_back(
18516 Elt: std::make_pair(
18517 CD->getParam(i: I)->getName(),
18518 getDerived().TransformType(CD->getParam(i: I)->getType())));
18519 } else {
18520 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18521 }
18522 }
18523 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18524 S->getCapturedRegionKind(), Params);
18525 StmtResult Body;
18526 {
18527 Sema::CompoundScopeRAII CompoundScope(getSema());
18528 Body = getDerived().TransformStmt(S->getCapturedStmt());
18529 }
18530
18531 if (Body.isInvalid()) {
18532 getSema().ActOnCapturedRegionError();
18533 return StmtError();
18534 }
18535
18536 return getSema().ActOnCapturedRegionEnd(Body.get());
18537}
18538
18539template <typename Derived>
18540StmtResult
18541TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18542 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18543 // function definition or instantiation of a function template specialization
18544 // and will therefore never appear in a dependent context.
18545 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18546 "context");
18547}
18548
18549template <typename Derived>
18550ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18551 // We can transform the base expression and allow argument resolution to fill
18552 // in the rest.
18553 return getDerived().TransformExpr(E->getArgLValue());
18554}
18555
18556} // end namespace clang
18557
18558#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18559