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/SemaInternal.h"
43#include "clang/Sema/SemaObjC.h"
44#include "clang/Sema/SemaOpenACC.h"
45#include "clang/Sema/SemaOpenMP.h"
46#include "clang/Sema/SemaPseudoObject.h"
47#include "clang/Sema/SemaSYCL.h"
48#include "clang/Sema/Template.h"
49#include "llvm/ADT/ArrayRef.h"
50#include "llvm/Support/ErrorHandling.h"
51#include <algorithm>
52#include <optional>
53
54using namespace llvm::omp;
55
56namespace clang {
57using namespace sema;
58
59// This helper class is used to facilitate pack expansion during tree transform.
60struct UnexpandedInfo {
61 SourceLocation Ellipsis;
62 UnsignedOrNone OrigNumExpansions = std::nullopt;
63
64 bool Expand = false;
65 bool RetainExpansion = false;
66 UnsignedOrNone NumExpansions = std::nullopt;
67 bool ExpandUnderForgetSubstitions = false;
68};
69
70/// A semantic tree transformation that allows one to transform one
71/// abstract syntax tree into another.
72///
73/// A new tree transformation is defined by creating a new subclass \c X of
74/// \c TreeTransform<X> and then overriding certain operations to provide
75/// behavior specific to that transformation. For example, template
76/// instantiation is implemented as a tree transformation where the
77/// transformation of TemplateTypeParmType nodes involves substituting the
78/// template arguments for their corresponding template parameters; a similar
79/// transformation is performed for non-type template parameters and
80/// template template parameters.
81///
82/// This tree-transformation template uses static polymorphism to allow
83/// subclasses to customize any of its operations. Thus, a subclass can
84/// override any of the transformation or rebuild operators by providing an
85/// operation with the same signature as the default implementation. The
86/// overriding function should not be virtual.
87///
88/// Semantic tree transformations are split into two stages, either of which
89/// can be replaced by a subclass. The "transform" step transforms an AST node
90/// or the parts of an AST node using the various transformation functions,
91/// then passes the pieces on to the "rebuild" step, which constructs a new AST
92/// node of the appropriate kind from the pieces. The default transformation
93/// routines recursively transform the operands to composite AST nodes (e.g.,
94/// the pointee type of a PointerType node) and, if any of those operand nodes
95/// were changed by the transformation, invokes the rebuild operation to create
96/// a new AST node.
97///
98/// Subclasses can customize the transformation at various levels. The
99/// most coarse-grained transformations involve replacing TransformType(),
100/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
101/// TransformTemplateName(), or TransformTemplateArgument() with entirely
102/// new implementations.
103///
104/// For more fine-grained transformations, subclasses can replace any of the
105/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
106/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
107/// replacing TransformTemplateTypeParmType() allows template instantiation
108/// to substitute template arguments for their corresponding template
109/// parameters. Additionally, subclasses can override the \c RebuildXXX
110/// functions to control how AST nodes are rebuilt when their operands change.
111/// By default, \c TreeTransform will invoke semantic analysis to rebuild
112/// AST nodes. However, certain other tree transformations (e.g, cloning) may
113/// be able to use more efficient rebuild steps.
114///
115/// There are a handful of other functions that can be overridden, allowing one
116/// to avoid traversing nodes that don't need any transformation
117/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
118/// operands have not changed (\c AlwaysRebuild()), and customize the
119/// default locations and entity names used for type-checking
120/// (\c getBaseLocation(), \c getBaseEntity()).
121template<typename Derived>
122class TreeTransform {
123 /// Private RAII object that helps us forget and then re-remember
124 /// the template argument corresponding to a partially-substituted parameter
125 /// pack.
126 class ForgetPartiallySubstitutedPackRAII {
127 Derived &Self;
128 TemplateArgument Old;
129 // Set the pack expansion index to -1 to avoid pack substitution and
130 // indicate that parameter packs should be instantiated as themselves.
131 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
132
133 public:
134 ForgetPartiallySubstitutedPackRAII(Derived &Self)
135 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
136 Old = Self.ForgetPartiallySubstitutedPack();
137 }
138
139 ~ForgetPartiallySubstitutedPackRAII() {
140 Self.RememberPartiallySubstitutedPack(Old);
141 }
142 ForgetPartiallySubstitutedPackRAII(
143 const ForgetPartiallySubstitutedPackRAII &) = delete;
144 ForgetPartiallySubstitutedPackRAII &
145 operator=(const ForgetPartiallySubstitutedPackRAII &) = delete;
146 };
147
148protected:
149 Sema &SemaRef;
150
151 /// The set of local declarations that have been transformed, for
152 /// cases where we are forced to build new declarations within the transformer
153 /// rather than in the subclass (e.g., lambda closure types).
154 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
155
156public:
157 /// Initializes a new tree transformer.
158 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
159
160 /// Retrieves a reference to the derived class.
161 Derived &getDerived() { return static_cast<Derived&>(*this); }
162
163 /// Retrieves a reference to the derived class.
164 const Derived &getDerived() const {
165 return static_cast<const Derived&>(*this);
166 }
167
168 static inline ExprResult Owned(Expr *E) { return E; }
169 static inline StmtResult Owned(Stmt *S) { return S; }
170
171 /// Retrieves a reference to the semantic analysis object used for
172 /// this tree transform.
173 Sema &getSema() const { return SemaRef; }
174
175 /// Whether the transformation should always rebuild AST nodes, even
176 /// if none of the children have changed.
177 ///
178 /// Subclasses may override this function to specify when the transformation
179 /// should rebuild all AST nodes.
180 ///
181 /// We must always rebuild all AST nodes when performing variadic template
182 /// pack expansion, in order to avoid violating the AST invariant that each
183 /// statement node appears at most once in its containing declaration.
184 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
185
186 /// Whether the transformation is forming an expression or statement that
187 /// replaces the original. In this case, we'll reuse mangling numbers from
188 /// existing lambdas.
189 bool ReplacingOriginal() { return false; }
190
191 /// Wether CXXConstructExpr can be skipped when they are implicit.
192 /// They will be reconstructed when used if needed.
193 /// This is useful when the user that cause rebuilding of the
194 /// CXXConstructExpr is outside of the expression at which the TreeTransform
195 /// started.
196 bool AllowSkippingCXXConstructExpr() { return true; }
197
198 /// Returns the location of the entity being transformed, if that
199 /// information was not available elsewhere in the AST.
200 ///
201 /// By default, returns no source-location information. Subclasses can
202 /// provide an alternative implementation that provides better location
203 /// information.
204 SourceLocation getBaseLocation() { return SourceLocation(); }
205
206 /// Returns the name of the entity being transformed, if that
207 /// information was not available elsewhere in the AST.
208 ///
209 /// By default, returns an empty name. Subclasses can provide an alternative
210 /// implementation with a more precise name.
211 DeclarationName getBaseEntity() { return DeclarationName(); }
212
213 /// Sets the "base" location and entity when that
214 /// information is known based on another transformation.
215 ///
216 /// By default, the source location and entity are ignored. Subclasses can
217 /// override this function to provide a customized implementation.
218 void setBase(SourceLocation Loc, DeclarationName Entity) { }
219
220 /// RAII object that temporarily sets the base location and entity
221 /// used for reporting diagnostics in types.
222 class TemporaryBase {
223 TreeTransform &Self;
224 SourceLocation OldLocation;
225 DeclarationName OldEntity;
226
227 public:
228 TemporaryBase(TreeTransform &Self, SourceLocation Location,
229 DeclarationName Entity) : Self(Self) {
230 OldLocation = Self.getDerived().getBaseLocation();
231 OldEntity = Self.getDerived().getBaseEntity();
232
233 if (Location.isValid())
234 Self.getDerived().setBase(Location, Entity);
235 }
236
237 ~TemporaryBase() {
238 Self.getDerived().setBase(OldLocation, OldEntity);
239 }
240 TemporaryBase(const TemporaryBase &) = delete;
241 TemporaryBase &operator=(const TemporaryBase &) = delete;
242 };
243
244 /// Determine whether the given type \p T has already been
245 /// transformed.
246 ///
247 /// Subclasses can provide an alternative implementation of this routine
248 /// to short-circuit evaluation when it is known that a given type will
249 /// not change. For example, template instantiation need not traverse
250 /// non-dependent types.
251 bool AlreadyTransformed(QualType T) {
252 return T.isNull();
253 }
254
255 /// Transform a template parameter depth level.
256 ///
257 /// During a transformation that transforms template parameters, this maps
258 /// an old template parameter depth to a new depth.
259 unsigned TransformTemplateDepth(unsigned Depth) {
260 return Depth;
261 }
262
263 /// Determine whether the given call argument should be dropped, e.g.,
264 /// because it is a default argument.
265 ///
266 /// Subclasses can provide an alternative implementation of this routine to
267 /// determine which kinds of call arguments get dropped. By default,
268 /// CXXDefaultArgument nodes are dropped (prior to transformation).
269 bool DropCallArgument(Expr *E) {
270 return E->isDefaultArgument();
271 }
272
273 /// Determine whether we should expand a pack expansion with the
274 /// given set of parameter packs into separate arguments by repeatedly
275 /// transforming the pattern.
276 ///
277 /// By default, the transformer never tries to expand pack expansions.
278 /// Subclasses can override this routine to provide different behavior.
279 ///
280 /// \param EllipsisLoc The location of the ellipsis that identifies the
281 /// pack expansion.
282 ///
283 /// \param PatternRange The source range that covers the entire pattern of
284 /// the pack expansion.
285 ///
286 /// \param Unexpanded The set of unexpanded parameter packs within the
287 /// pattern.
288 ///
289 /// \param ShouldExpand Will be set to \c true if the transformer should
290 /// expand the corresponding pack expansions into separate arguments. When
291 /// set, \c NumExpansions must also be set.
292 ///
293 /// \param RetainExpansion Whether the caller should add an unexpanded
294 /// pack expansion after all of the expanded arguments. This is used
295 /// when extending explicitly-specified template argument packs per
296 /// C++0x [temp.arg.explicit]p9.
297 ///
298 /// \param NumExpansions The number of separate arguments that will be in
299 /// the expanded form of the corresponding pack expansion. This is both an
300 /// input and an output parameter, which can be set by the caller if the
301 /// number of expansions is known a priori (e.g., due to a prior substitution)
302 /// and will be set by the callee when the number of expansions is known.
303 /// The callee must set this value when \c ShouldExpand is \c true; it may
304 /// set this value in other cases.
305 ///
306 /// \returns true if an error occurred (e.g., because the parameter packs
307 /// are to be instantiated with arguments of different lengths), false
308 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
309 /// must be set.
310 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
311 SourceRange PatternRange,
312 ArrayRef<UnexpandedParameterPack> Unexpanded,
313 bool FailOnPackProducingTemplates,
314 bool &ShouldExpand, bool &RetainExpansion,
315 UnsignedOrNone &NumExpansions) {
316 ShouldExpand = false;
317 return false;
318 }
319
320 /// "Forget" about the partially-substituted pack template argument,
321 /// when performing an instantiation that must preserve the parameter pack
322 /// use.
323 ///
324 /// This routine is meant to be overridden by the template instantiator.
325 TemplateArgument ForgetPartiallySubstitutedPack() {
326 return TemplateArgument();
327 }
328
329 /// "Remember" the partially-substituted pack template argument
330 /// after performing an instantiation that must preserve the parameter pack
331 /// use.
332 ///
333 /// This routine is meant to be overridden by the template instantiator.
334 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
335
336 /// "Forget" the template substitution to allow transforming the AST without
337 /// any template instantiations. This is used to expand template packs when
338 /// their size is not known in advance (e.g. for builtins that produce type
339 /// packs).
340 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
341 void RememberSubstitution(MultiLevelTemplateArgumentList) {}
342
343private:
344 struct ForgetSubstitutionRAII {
345 Derived &Self;
346 MultiLevelTemplateArgumentList Old;
347
348 public:
349 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
350 Old = Self.ForgetSubstitution();
351 }
352
353 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
354 };
355
356public:
357 /// Note to the derived class when a function parameter pack is
358 /// being expanded.
359 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
360
361 /// Transforms the given type into another type.
362 ///
363 /// By default, this routine transforms a type by creating a
364 /// TypeSourceInfo for it and delegating to the appropriate
365 /// function. This is expensive, but we don't mind, because
366 /// this method is deprecated anyway; all users should be
367 /// switched to storing TypeSourceInfos.
368 ///
369 /// \returns the transformed type.
370 QualType TransformType(QualType T);
371
372 /// Transforms the given type-with-location into a new
373 /// type-with-location.
374 ///
375 /// By default, this routine transforms a type by delegating to the
376 /// appropriate TransformXXXType to build a new type. Subclasses
377 /// may override this function (to take over all type
378 /// transformations) or some set of the TransformXXXType functions
379 /// to alter the transformation.
380 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);
381
382 /// Transform the given type-with-location into a new
383 /// type, collecting location information in the given builder
384 /// as necessary.
385 ///
386 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
387
388 /// Transform a type that is permitted to produce a
389 /// DeducedTemplateSpecializationType.
390 ///
391 /// This is used in the (relatively rare) contexts where it is acceptable
392 /// for transformation to produce a class template type with deduced
393 /// template arguments.
394 /// @{
395 QualType TransformTypeWithDeducedTST(QualType T);
396 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);
397 /// @}
398
399 /// The reason why the value of a statement is not discarded, if any.
400 enum class StmtDiscardKind {
401 Discarded,
402 NotDiscarded,
403 StmtExprResult,
404 };
405
406 /// Transform the given statement.
407 ///
408 /// By default, this routine transforms a statement by delegating to the
409 /// appropriate TransformXXXStmt function to transform a specific kind of
410 /// statement or the TransformExpr() function to transform an expression.
411 /// Subclasses may override this function to transform statements using some
412 /// other mechanism.
413 ///
414 /// \returns the transformed statement.
415 StmtResult TransformStmt(Stmt *S,
416 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
417
418 /// Transform the given statement.
419 ///
420 /// By default, this routine transforms a statement by delegating to the
421 /// appropriate TransformOMPXXXClause function to transform a specific kind
422 /// of clause. Subclasses may override this function to transform statements
423 /// using some other mechanism.
424 ///
425 /// \returns the transformed OpenMP clause.
426 OMPClause *TransformOMPClause(OMPClause *S);
427
428 /// Transform the given attribute.
429 ///
430 /// By default, this routine transforms a statement by delegating to the
431 /// appropriate TransformXXXAttr function to transform a specific kind
432 /// of attribute. Subclasses may override this function to transform
433 /// attributed statements/types using some other mechanism.
434 ///
435 /// \returns the transformed attribute
436 const Attr *TransformAttr(const Attr *S);
437
438 // Transform the given statement attribute.
439 //
440 // Delegates to the appropriate TransformXXXAttr function to transform a
441 // specific kind of statement attribute. Unlike the non-statement taking
442 // version of this, this implements all attributes, not just pragmas.
443 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
444 const Attr *A);
445
446 // Transform the specified attribute.
447 //
448 // Subclasses should override the transformation of attributes with a pragma
449 // spelling to transform expressions stored within the attribute.
450 //
451 // \returns the transformed attribute.
452#define ATTR(X) \
453 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
454#include "clang/Basic/AttrList.inc"
455
456 // Transform the specified attribute.
457 //
458 // Subclasses should override the transformation of attributes to do
459 // transformation and checking of statement attributes. By default, this
460 // delegates to the non-statement taking version.
461 //
462 // \returns the transformed attribute.
463#define ATTR(X) \
464 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
465 const X##Attr *A) { \
466 return getDerived().Transform##X##Attr(A); \
467 }
468#include "clang/Basic/AttrList.inc"
469
470 /// Transform the given expression.
471 ///
472 /// By default, this routine transforms an expression by delegating to the
473 /// appropriate TransformXXXExpr function to build a new expression.
474 /// Subclasses may override this function to transform expressions using some
475 /// other mechanism.
476 ///
477 /// \returns the transformed expression.
478 ExprResult TransformExpr(Expr *E);
479
480 /// Transform the given initializer.
481 ///
482 /// By default, this routine transforms an initializer by stripping off the
483 /// semantic nodes added by initialization, then passing the result to
484 /// TransformExpr or TransformExprs.
485 ///
486 /// \returns the transformed initializer.
487 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
488
489 /// Transform the given list of expressions.
490 ///
491 /// This routine transforms a list of expressions by invoking
492 /// \c TransformExpr() for each subexpression. However, it also provides
493 /// support for variadic templates by expanding any pack expansions (if the
494 /// derived class permits such expansion) along the way. When pack expansions
495 /// are present, the number of outputs may not equal the number of inputs.
496 ///
497 /// \param Inputs The set of expressions to be transformed.
498 ///
499 /// \param NumInputs The number of expressions in \c Inputs.
500 ///
501 /// \param IsCall If \c true, then this transform is being performed on
502 /// function-call arguments, and any arguments that should be dropped, will
503 /// be.
504 ///
505 /// \param Outputs The transformed input expressions will be added to this
506 /// vector.
507 ///
508 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
509 /// due to transformation.
510 ///
511 /// \returns true if an error occurred, false otherwise.
512 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
513 SmallVectorImpl<Expr *> &Outputs,
514 bool *ArgChanged = nullptr);
515
516 /// Transform the given declaration, which is referenced from a type
517 /// or expression.
518 ///
519 /// By default, acts as the identity function on declarations, unless the
520 /// transformer has had to transform the declaration itself. Subclasses
521 /// may override this function to provide alternate behavior.
522 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
523 llvm::DenseMap<Decl *, Decl *>::iterator Known
524 = TransformedLocalDecls.find(Val: D);
525 if (Known != TransformedLocalDecls.end())
526 return Known->second;
527
528 return D;
529 }
530
531 /// Transform the specified condition.
532 ///
533 /// By default, this transforms the variable and expression and rebuilds
534 /// the condition.
535 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
536 Expr *Expr,
537 Sema::ConditionKind Kind);
538
539 /// Transform the attributes associated with the given declaration and
540 /// place them on the new declaration.
541 ///
542 /// By default, this operation does nothing. Subclasses may override this
543 /// behavior to transform attributes.
544 void transformAttrs(Decl *Old, Decl *New) { }
545
546 /// Note that a local declaration has been transformed by this
547 /// transformer.
548 ///
549 /// Local declarations are typically transformed via a call to
550 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
551 /// the transformer itself has to transform the declarations. This routine
552 /// can be overridden by a subclass that keeps track of such mappings.
553 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
554 assert(New.size() == 1 &&
555 "must override transformedLocalDecl if performing pack expansion");
556 TransformedLocalDecls[Old] = New.front();
557 }
558
559 /// Transform the definition of the given declaration.
560 ///
561 /// By default, invokes TransformDecl() to transform the declaration.
562 /// Subclasses may override this function to provide alternate behavior.
563 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
564 return getDerived().TransformDecl(Loc, D);
565 }
566
567 /// Transform the given declaration, which was the first part of a
568 /// nested-name-specifier in a member access expression.
569 ///
570 /// This specific declaration transformation only applies to the first
571 /// identifier in a nested-name-specifier of a member access expression, e.g.,
572 /// the \c T in \c x->T::member
573 ///
574 /// By default, invokes TransformDecl() to transform the declaration.
575 /// Subclasses may override this function to provide alternate behavior.
576 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
577 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
578 }
579
580 /// Transform the set of declarations in an OverloadExpr.
581 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
582 LookupResult &R);
583
584 /// Transform the given nested-name-specifier with source-location
585 /// information.
586 ///
587 /// By default, transforms all of the types and declarations within the
588 /// nested-name-specifier. Subclasses may override this function to provide
589 /// alternate behavior.
590 NestedNameSpecifierLoc
591 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
592 QualType ObjectType = QualType(),
593 NamedDecl *FirstQualifierInScope = nullptr);
594
595 /// Transform the given declaration name.
596 ///
597 /// By default, transforms the types of conversion function, constructor,
598 /// and destructor names and then (if needed) rebuilds the declaration name.
599 /// Identifiers and selectors are returned unmodified. Subclasses may
600 /// override this function to provide alternate behavior.
601 DeclarationNameInfo
602 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
603
604 bool TransformRequiresExprRequirements(
605 ArrayRef<concepts::Requirement *> Reqs,
606 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
607 concepts::TypeRequirement *
608 TransformTypeRequirement(concepts::TypeRequirement *Req);
609 concepts::ExprRequirement *
610 TransformExprRequirement(concepts::ExprRequirement *Req);
611 concepts::NestedRequirement *
612 TransformNestedRequirement(concepts::NestedRequirement *Req);
613
614 /// Transform the given template name.
615 ///
616 /// \param SS The nested-name-specifier that qualifies the template
617 /// name. This nested-name-specifier must already have been transformed.
618 ///
619 /// \param Name The template name to transform.
620 ///
621 /// \param NameLoc The source location of the template name.
622 ///
623 /// \param ObjectType If we're translating a template name within a member
624 /// access expression, this is the type of the object whose member template
625 /// is being referenced.
626 ///
627 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
628 /// also refers to a name within the current (lexical) scope, this is the
629 /// declaration it refers to.
630 ///
631 /// By default, transforms the template name by transforming the declarations
632 /// and nested-name-specifiers that occur within the template name.
633 /// Subclasses may override this function to provide alternate behavior.
634 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
635 SourceLocation TemplateKWLoc,
636 TemplateName Name, SourceLocation NameLoc,
637 QualType ObjectType = QualType(),
638 NamedDecl *FirstQualifierInScope = nullptr,
639 bool AllowInjectedClassName = false);
640
641 /// Transform the given template argument.
642 ///
643 /// By default, this operation transforms the type, expression, or
644 /// declaration stored within the template argument and constructs a
645 /// new template argument from the transformed result. Subclasses may
646 /// override this function to provide alternate behavior.
647 ///
648 /// Returns true if there was an error.
649 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
650 TemplateArgumentLoc &Output,
651 bool Uneval = false);
652
653 TemplateArgument TransformNamedTemplateTemplateArgument(
654 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
655 TemplateName Name, SourceLocation NameLoc);
656
657 /// Transform the given set of template arguments.
658 ///
659 /// By default, this operation transforms all of the template arguments
660 /// in the input set using \c TransformTemplateArgument(), and appends
661 /// the transformed arguments to the output list.
662 ///
663 /// Note that this overload of \c TransformTemplateArguments() is merely
664 /// a convenience function. Subclasses that wish to override this behavior
665 /// should override the iterator-based member template version.
666 ///
667 /// \param Inputs The set of template arguments to be transformed.
668 ///
669 /// \param NumInputs The number of template arguments in \p Inputs.
670 ///
671 /// \param Outputs The set of transformed template arguments output by this
672 /// routine.
673 ///
674 /// Returns true if an error occurred.
675 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
676 unsigned NumInputs,
677 TemplateArgumentListInfo &Outputs,
678 bool Uneval = false) {
679 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
680 Uneval);
681 }
682
683 /// Transform the given set of template arguments.
684 ///
685 /// By default, this operation transforms all of the template arguments
686 /// in the input set using \c TransformTemplateArgument(), and appends
687 /// the transformed arguments to the output list.
688 ///
689 /// \param First An iterator to the first template argument.
690 ///
691 /// \param Last An iterator one step past the last template argument.
692 ///
693 /// \param Outputs The set of transformed template arguments output by this
694 /// routine.
695 ///
696 /// Returns true if an error occurred.
697 template<typename InputIterator>
698 bool TransformTemplateArguments(InputIterator First,
699 InputIterator Last,
700 TemplateArgumentListInfo &Outputs,
701 bool Uneval = false);
702
703 template <typename InputIterator>
704 bool TransformConceptTemplateArguments(InputIterator First,
705 InputIterator Last,
706 TemplateArgumentListInfo &Outputs,
707 bool Uneval = false);
708
709 /// Checks if the argument pack from \p In will need to be expanded and does
710 /// the necessary prework.
711 /// Whether the expansion is needed is captured in Info.Expand.
712 ///
713 /// - When the expansion is required, \p Out will be a template pattern that
714 /// would need to be expanded.
715 /// - When the expansion must not happen, \p Out will be a pack that must be
716 /// returned to the outputs directly.
717 ///
718 /// \return true iff the error occurred
719 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
720 TemplateArgumentLoc &Out, UnexpandedInfo &Info);
721
722 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
723 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
724 TemplateArgumentLoc &ArgLoc);
725
726 /// Fakes up a TypeSourceInfo for a type.
727 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
728 return SemaRef.Context.getTrivialTypeSourceInfo(T,
729 Loc: getDerived().getBaseLocation());
730 }
731
732#define ABSTRACT_TYPELOC(CLASS, PARENT)
733#define TYPELOC(CLASS, PARENT) \
734 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
735#include "clang/AST/TypeLocNodes.def"
736
737 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
738 TemplateTypeParmTypeLoc TL,
739 bool SuppressObjCLifetime);
740 QualType
741 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
742 SubstTemplateTypeParmPackTypeLoc TL,
743 bool SuppressObjCLifetime);
744
745 template<typename Fn>
746 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
747 FunctionProtoTypeLoc TL,
748 CXXRecordDecl *ThisContext,
749 Qualifiers ThisTypeQuals,
750 Fn TransformExceptionSpec);
751
752 bool TransformExceptionSpec(SourceLocation Loc,
753 FunctionProtoType::ExceptionSpecInfo &ESI,
754 SmallVectorImpl<QualType> &Exceptions,
755 bool &Changed);
756
757 StmtResult TransformSEHHandler(Stmt *Handler);
758
759 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
760 TemplateSpecializationTypeLoc TL,
761 QualType ObjectType,
762 NamedDecl *FirstQualifierInScope,
763 bool AllowInjectedClassName);
764
765 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
766
767 /// Transforms the parameters of a function type into the
768 /// given vectors.
769 ///
770 /// The result vectors should be kept in sync; null entries in the
771 /// variables vector are acceptable.
772 ///
773 /// LastParamTransformed, if non-null, will be set to the index of the last
774 /// parameter on which transformation was started. In the event of an error,
775 /// this will contain the parameter which failed to instantiate.
776 ///
777 /// Return true on error.
778 bool TransformFunctionTypeParams(
779 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
780 const QualType *ParamTypes,
781 const FunctionProtoType::ExtParameterInfo *ParamInfos,
782 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
783 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
784
785 bool TransformFunctionTypeParams(
786 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
787 const QualType *ParamTypes,
788 const FunctionProtoType::ExtParameterInfo *ParamInfos,
789 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
790 Sema::ExtParameterInfoBuilder &PInfos) {
791 return getDerived().TransformFunctionTypeParams(
792 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
793 }
794
795 /// Transforms the parameters of a requires expresison into the given vectors.
796 ///
797 /// The result vectors should be kept in sync; null entries in the
798 /// variables vector are acceptable.
799 ///
800 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
801 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
802 /// which are cases where transformation shouldn't continue.
803 ExprResult TransformRequiresTypeParams(
804 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
805 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
806 SmallVectorImpl<QualType> &PTypes,
807 SmallVectorImpl<ParmVarDecl *> &TransParams,
808 Sema::ExtParameterInfoBuilder &PInfos) {
809 if (getDerived().TransformFunctionTypeParams(
810 KWLoc, Params, /*ParamTypes=*/nullptr,
811 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
812 return ExprError();
813
814 return ExprResult{};
815 }
816
817 /// Transforms a single function-type parameter. Return null
818 /// on error.
819 ///
820 /// \param indexAdjustment - A number to add to the parameter's
821 /// scope index; can be negative
822 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
823 int indexAdjustment,
824 UnsignedOrNone NumExpansions,
825 bool ExpectParameterPack);
826
827 /// Transform the body of a lambda-expression.
828 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
829 /// Alternative implementation of TransformLambdaBody that skips transforming
830 /// the body.
831 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
832
833 CXXRecordDecl::LambdaDependencyKind
834 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
835 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
836 LSI->Lambda->getLambdaDependencyKind());
837 }
838
839 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
840
841 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
842 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
843
844 TemplateParameterList *TransformTemplateParameterList(
845 TemplateParameterList *TPL) {
846 return TPL;
847 }
848
849 ExprResult TransformAddressOfOperand(Expr *E);
850
851 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
852 bool IsAddressOfOperand,
853 TypeSourceInfo **RecoveryTSI);
854
855 ExprResult TransformParenDependentScopeDeclRefExpr(
856 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
857 TypeSourceInfo **RecoveryTSI);
858
859 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
860 bool IsAddressOfOperand);
861
862 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
863
864 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
865
866// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
867// amount of stack usage with clang.
868#define STMT(Node, Parent) \
869 LLVM_ATTRIBUTE_NOINLINE \
870 StmtResult Transform##Node(Node *S);
871#define VALUESTMT(Node, Parent) \
872 LLVM_ATTRIBUTE_NOINLINE \
873 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
874#define EXPR(Node, Parent) \
875 LLVM_ATTRIBUTE_NOINLINE \
876 ExprResult Transform##Node(Node *E);
877#define ABSTRACT_STMT(Stmt)
878#include "clang/AST/StmtNodes.inc"
879
880#define GEN_CLANG_CLAUSE_CLASS
881#define CLAUSE_CLASS(Enum, Str, Class) \
882 LLVM_ATTRIBUTE_NOINLINE \
883 OMPClause *Transform##Class(Class *S);
884#include "llvm/Frontend/OpenMP/OMP.inc"
885
886 /// Build a new qualified type given its unqualified type and type location.
887 ///
888 /// By default, this routine adds type qualifiers only to types that can
889 /// have qualifiers, and silently suppresses those qualifiers that are not
890 /// permitted. Subclasses may override this routine to provide different
891 /// behavior.
892 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
893
894 /// Build a new pointer type given its pointee type.
895 ///
896 /// By default, performs semantic analysis when building the pointer type.
897 /// Subclasses may override this routine to provide different behavior.
898 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
899
900 /// Build a new block pointer type given its pointee type.
901 ///
902 /// By default, performs semantic analysis when building the block pointer
903 /// type. Subclasses may override this routine to provide different behavior.
904 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
905
906 /// Build a new reference type given the type it references.
907 ///
908 /// By default, performs semantic analysis when building the
909 /// reference type. Subclasses may override this routine to provide
910 /// different behavior.
911 ///
912 /// \param LValue whether the type was written with an lvalue sigil
913 /// or an rvalue sigil.
914 QualType RebuildReferenceType(QualType ReferentType,
915 bool LValue,
916 SourceLocation Sigil);
917
918 /// Build a new member pointer type given the pointee type and the
919 /// qualifier it refers into.
920 ///
921 /// By default, performs semantic analysis when building the member pointer
922 /// type. Subclasses may override this routine to provide different behavior.
923 QualType RebuildMemberPointerType(QualType PointeeType,
924 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
925 SourceLocation Sigil);
926
927 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
928 SourceLocation ProtocolLAngleLoc,
929 ArrayRef<ObjCProtocolDecl *> Protocols,
930 ArrayRef<SourceLocation> ProtocolLocs,
931 SourceLocation ProtocolRAngleLoc);
932
933 /// Build an Objective-C object type.
934 ///
935 /// By default, performs semantic analysis when building the object type.
936 /// Subclasses may override this routine to provide different behavior.
937 QualType RebuildObjCObjectType(QualType BaseType,
938 SourceLocation Loc,
939 SourceLocation TypeArgsLAngleLoc,
940 ArrayRef<TypeSourceInfo *> TypeArgs,
941 SourceLocation TypeArgsRAngleLoc,
942 SourceLocation ProtocolLAngleLoc,
943 ArrayRef<ObjCProtocolDecl *> Protocols,
944 ArrayRef<SourceLocation> ProtocolLocs,
945 SourceLocation ProtocolRAngleLoc);
946
947 /// Build a new Objective-C object pointer type given the pointee type.
948 ///
949 /// By default, directly builds the pointer type, with no additional semantic
950 /// analysis.
951 QualType RebuildObjCObjectPointerType(QualType PointeeType,
952 SourceLocation Star);
953
954 /// Build a new array type given the element type, size
955 /// modifier, size of the array (if known), size expression, and index type
956 /// qualifiers.
957 ///
958 /// By default, performs semantic analysis when building the array type.
959 /// Subclasses may override this routine to provide different behavior.
960 /// Also by default, all of the other Rebuild*Array
961 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
962 const llvm::APInt *Size, Expr *SizeExpr,
963 unsigned IndexTypeQuals, SourceRange BracketsRange);
964
965 /// Build a new constant array type given the element type, size
966 /// modifier, (known) size of the array, and index type qualifiers.
967 ///
968 /// By default, performs semantic analysis when building the array type.
969 /// Subclasses may override this routine to provide different behavior.
970 QualType RebuildConstantArrayType(QualType ElementType,
971 ArraySizeModifier SizeMod,
972 const llvm::APInt &Size, Expr *SizeExpr,
973 unsigned IndexTypeQuals,
974 SourceRange BracketsRange);
975
976 /// Build a new incomplete array type given the element type, size
977 /// modifier, and index type qualifiers.
978 ///
979 /// By default, performs semantic analysis when building the array type.
980 /// Subclasses may override this routine to provide different behavior.
981 QualType RebuildIncompleteArrayType(QualType ElementType,
982 ArraySizeModifier SizeMod,
983 unsigned IndexTypeQuals,
984 SourceRange BracketsRange);
985
986 /// Build a new variable-length array type given the element type,
987 /// size modifier, size expression, and index type qualifiers.
988 ///
989 /// By default, performs semantic analysis when building the array type.
990 /// Subclasses may override this routine to provide different behavior.
991 QualType RebuildVariableArrayType(QualType ElementType,
992 ArraySizeModifier SizeMod, Expr *SizeExpr,
993 unsigned IndexTypeQuals,
994 SourceRange BracketsRange);
995
996 /// Build a new dependent-sized array type given the element type,
997 /// size modifier, size expression, and index type qualifiers.
998 ///
999 /// By default, performs semantic analysis when building the array type.
1000 /// Subclasses may override this routine to provide different behavior.
1001 QualType RebuildDependentSizedArrayType(QualType ElementType,
1002 ArraySizeModifier SizeMod,
1003 Expr *SizeExpr,
1004 unsigned IndexTypeQuals,
1005 SourceRange BracketsRange);
1006
1007 /// Build a new vector type given the element type and
1008 /// number of elements.
1009 ///
1010 /// By default, performs semantic analysis when building the vector type.
1011 /// Subclasses may override this routine to provide different behavior.
1012 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1013 VectorKind VecKind);
1014
1015 /// Build a new potentially dependently-sized extended vector type
1016 /// given the element type and number of elements.
1017 ///
1018 /// By default, performs semantic analysis when building the vector type.
1019 /// Subclasses may override this routine to provide different behavior.
1020 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1021 SourceLocation AttributeLoc, VectorKind);
1022
1023 /// Build a new extended vector type given the element type and
1024 /// number of elements.
1025 ///
1026 /// By default, performs semantic analysis when building the vector type.
1027 /// Subclasses may override this routine to provide different behavior.
1028 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1029 SourceLocation AttributeLoc);
1030
1031 /// Build a new potentially dependently-sized extended vector type
1032 /// given the element type and number of elements.
1033 ///
1034 /// By default, performs semantic analysis when building the vector type.
1035 /// Subclasses may override this routine to provide different behavior.
1036 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1037 Expr *SizeExpr,
1038 SourceLocation AttributeLoc);
1039
1040 /// Build a new matrix type given the element type and dimensions.
1041 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1042 unsigned NumColumns);
1043
1044 /// Build a new matrix type given the type and dependently-defined
1045 /// dimensions.
1046 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1047 Expr *ColumnExpr,
1048 SourceLocation AttributeLoc);
1049
1050 /// Build a new DependentAddressSpaceType or return the pointee
1051 /// type variable with the correct address space (retrieved from
1052 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1053 /// where the address space remains dependent.
1054 ///
1055 /// By default, performs semantic analysis when building the type with address
1056 /// space applied. Subclasses may override this routine to provide different
1057 /// behavior.
1058 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1059 Expr *AddrSpaceExpr,
1060 SourceLocation AttributeLoc);
1061
1062 /// Build a new function type.
1063 ///
1064 /// By default, performs semantic analysis when building the function type.
1065 /// Subclasses may override this routine to provide different behavior.
1066 QualType RebuildFunctionProtoType(QualType T,
1067 MutableArrayRef<QualType> ParamTypes,
1068 const FunctionProtoType::ExtProtoInfo &EPI);
1069
1070 /// Build a new unprototyped function type.
1071 QualType RebuildFunctionNoProtoType(QualType ResultType);
1072
1073 /// Rebuild an unresolved typename type, given the decl that
1074 /// the UnresolvedUsingTypenameDecl was transformed to.
1075 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1076 NestedNameSpecifier Qualifier,
1077 SourceLocation NameLoc, Decl *D);
1078
1079 /// Build a new type found via an alias.
1080 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1081 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1082 QualType UnderlyingType) {
1083 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1084 }
1085
1086 /// Build a new typedef type.
1087 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1088 NestedNameSpecifier Qualifier,
1089 TypedefNameDecl *Typedef) {
1090 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1091 }
1092
1093 /// Build a new MacroDefined type.
1094 QualType RebuildMacroQualifiedType(QualType T,
1095 const IdentifierInfo *MacroII) {
1096 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1097 }
1098
1099 /// Build a new class/struct/union/enum type.
1100 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1101 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1102 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1103 /*OwnsTag=*/OwnsTag: false);
1104 }
1105 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1106 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1107 }
1108
1109 /// Build a new typeof(expr) type.
1110 ///
1111 /// By default, performs semantic analysis when building the typeof type.
1112 /// Subclasses may override this routine to provide different behavior.
1113 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1114 TypeOfKind Kind);
1115
1116 /// Build a new typeof(type) type.
1117 ///
1118 /// By default, builds a new TypeOfType with the given underlying type.
1119 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1120
1121 /// Build a new unary transform type.
1122 QualType RebuildUnaryTransformType(QualType BaseType,
1123 UnaryTransformType::UTTKind UKind,
1124 SourceLocation Loc);
1125
1126 /// Build a new C++11 decltype type.
1127 ///
1128 /// By default, performs semantic analysis when building the decltype type.
1129 /// Subclasses may override this routine to provide different behavior.
1130 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1131
1132 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1133 SourceLocation Loc,
1134 SourceLocation EllipsisLoc,
1135 bool FullySubstituted,
1136 ArrayRef<QualType> Expansions = {});
1137
1138 /// Build a new C++11 auto type.
1139 ///
1140 /// By default, builds a new AutoType with the given deduced type.
1141 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1142 ConceptDecl *TypeConstraintConcept,
1143 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1144 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1145 // which has been deduced to a dependent type into an undeduced 'auto', so
1146 // that we'll retry deduction after the transformation.
1147 return SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword,
1148 /*IsDependent*/ IsDependent: false, /*IsPack=*/IsPack: false,
1149 TypeConstraintConcept,
1150 TypeConstraintArgs);
1151 }
1152
1153 /// By default, builds a new DeducedTemplateSpecializationType with the given
1154 /// deduced type.
1155 QualType RebuildDeducedTemplateSpecializationType(
1156 ElaboratedTypeKeyword Keyword, TemplateName Template, QualType Deduced) {
1157 return SemaRef.Context.getDeducedTemplateSpecializationType(
1158 Keyword, Template, DeducedType: Deduced, /*IsDependent*/ IsDependent: false);
1159 }
1160
1161 /// Build a new template specialization type.
1162 ///
1163 /// By default, performs semantic analysis when building the template
1164 /// specialization type. Subclasses may override this routine to provide
1165 /// different behavior.
1166 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1167 TemplateName Template,
1168 SourceLocation TemplateLoc,
1169 TemplateArgumentListInfo &Args);
1170
1171 /// Build a new parenthesized type.
1172 ///
1173 /// By default, builds a new ParenType type from the inner type.
1174 /// Subclasses may override this routine to provide different behavior.
1175 QualType RebuildParenType(QualType InnerType) {
1176 return SemaRef.BuildParenType(T: InnerType);
1177 }
1178
1179 /// Build a new typename type that refers to an identifier.
1180 ///
1181 /// By default, performs semantic analysis when building the typename type
1182 /// (or elaborated type). Subclasses may override this routine to provide
1183 /// different behavior.
1184 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1185 SourceLocation KeywordLoc,
1186 NestedNameSpecifierLoc QualifierLoc,
1187 const IdentifierInfo *Id,
1188 SourceLocation IdLoc,
1189 bool DeducedTSTContext) {
1190 CXXScopeSpec SS;
1191 SS.Adopt(Other: QualifierLoc);
1192
1193 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1194 // If the name is still dependent, just build a new dependent name type.
1195 if (!SemaRef.computeDeclContext(SS))
1196 return SemaRef.Context.getDependentNameType(Keyword,
1197 NNS: QualifierLoc.getNestedNameSpecifier(),
1198 Name: Id);
1199 }
1200
1201 if (Keyword == ElaboratedTypeKeyword::None ||
1202 Keyword == ElaboratedTypeKeyword::Typename) {
1203 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1204 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1205 }
1206
1207 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1208
1209 // We had a dependent elaborated-type-specifier that has been transformed
1210 // into a non-dependent elaborated-type-specifier. Find the tag we're
1211 // referring to.
1212 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1213 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1214 if (!DC)
1215 return QualType();
1216
1217 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1218 return QualType();
1219
1220 TagDecl *Tag = nullptr;
1221 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1222 switch (Result.getResultKind()) {
1223 case LookupResultKind::NotFound:
1224 case LookupResultKind::NotFoundInCurrentInstantiation:
1225 break;
1226
1227 case LookupResultKind::Found:
1228 Tag = Result.getAsSingle<TagDecl>();
1229 break;
1230
1231 case LookupResultKind::FoundOverloaded:
1232 case LookupResultKind::FoundUnresolvedValue:
1233 llvm_unreachable("Tag lookup cannot find non-tags");
1234
1235 case LookupResultKind::Ambiguous:
1236 // Let the LookupResult structure handle ambiguities.
1237 return QualType();
1238 }
1239
1240 if (!Tag) {
1241 // Check where the name exists but isn't a tag type and use that to emit
1242 // better diagnostics.
1243 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1244 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1245 switch (Result.getResultKind()) {
1246 case LookupResultKind::Found:
1247 case LookupResultKind::FoundOverloaded:
1248 case LookupResultKind::FoundUnresolvedValue: {
1249 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1250 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1251 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1252 << SomeDecl << NTK << Kind;
1253 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1254 break;
1255 }
1256 default:
1257 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1258 << Kind << Id << DC << QualifierLoc.getSourceRange();
1259 break;
1260 }
1261 return QualType();
1262 }
1263 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1264 NewTagLoc: IdLoc, Name: Id)) {
1265 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1266 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1267 return QualType();
1268 }
1269 return getDerived().RebuildTagType(
1270 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1271 }
1272
1273 /// Build a new pack expansion type.
1274 ///
1275 /// By default, builds a new PackExpansionType type from the given pattern.
1276 /// Subclasses may override this routine to provide different behavior.
1277 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1278 SourceLocation EllipsisLoc,
1279 UnsignedOrNone NumExpansions) {
1280 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1281 NumExpansions);
1282 }
1283
1284 /// Build a new atomic type given its value type.
1285 ///
1286 /// By default, performs semantic analysis when building the atomic type.
1287 /// Subclasses may override this routine to provide different behavior.
1288 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1289
1290 /// Build a new pipe type given its value type.
1291 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1292 bool isReadPipe);
1293
1294 /// Build a bit-precise int given its value type.
1295 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1296 SourceLocation Loc);
1297
1298 /// Build a dependent bit-precise int given its value type.
1299 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1300 SourceLocation Loc);
1301
1302 /// Build a new template name given a nested name specifier, a flag
1303 /// indicating whether the "template" keyword was provided, and the template
1304 /// that the template name refers to.
1305 ///
1306 /// By default, builds the new template name directly. Subclasses may override
1307 /// this routine to provide different behavior.
1308 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1309 TemplateName Name);
1310
1311 /// Build a new template name given a nested name specifier and the
1312 /// name that is referred to as a template.
1313 ///
1314 /// By default, performs semantic analysis to determine whether the name can
1315 /// be resolved to a specific template, then builds the appropriate kind of
1316 /// template name. Subclasses may override this routine to provide different
1317 /// behavior.
1318 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1319 SourceLocation TemplateKWLoc,
1320 const IdentifierInfo &Name,
1321 SourceLocation NameLoc, QualType ObjectType,
1322 bool AllowInjectedClassName);
1323
1324 /// Build a new template name given a nested name specifier and the
1325 /// overloaded operator name that is referred to as a template.
1326 ///
1327 /// By default, performs semantic analysis to determine whether the name can
1328 /// be resolved to a specific template, then builds the appropriate kind of
1329 /// template name. Subclasses may override this routine to provide different
1330 /// behavior.
1331 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1332 SourceLocation TemplateKWLoc,
1333 OverloadedOperatorKind Operator,
1334 SourceLocation NameLoc, QualType ObjectType,
1335 bool AllowInjectedClassName);
1336
1337 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1338 SourceLocation TemplateKWLoc,
1339 IdentifierOrOverloadedOperator IO,
1340 SourceLocation NameLoc, QualType ObjectType,
1341 bool AllowInjectedClassName);
1342
1343 /// Build a new template name given a template template parameter pack
1344 /// and the
1345 ///
1346 /// By default, performs semantic analysis to determine whether the name can
1347 /// be resolved to a specific template, then builds the appropriate kind of
1348 /// template name. Subclasses may override this routine to provide different
1349 /// behavior.
1350 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1351 Decl *AssociatedDecl, unsigned Index,
1352 bool Final) {
1353 return getSema().Context.getSubstTemplateTemplateParmPack(
1354 ArgPack, AssociatedDecl, Index, Final);
1355 }
1356
1357 /// Build a new compound statement.
1358 ///
1359 /// By default, performs semantic analysis to build the new statement.
1360 /// Subclasses may override this routine to provide different behavior.
1361 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1362 MultiStmtArg Statements,
1363 SourceLocation RBraceLoc,
1364 bool IsStmtExpr) {
1365 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1366 IsStmtExpr);
1367 }
1368
1369 /// Build a new case statement.
1370 ///
1371 /// By default, performs semantic analysis to build the new statement.
1372 /// Subclasses may override this routine to provide different behavior.
1373 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1374 Expr *LHS,
1375 SourceLocation EllipsisLoc,
1376 Expr *RHS,
1377 SourceLocation ColonLoc) {
1378 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1379 ColonLoc);
1380 }
1381
1382 /// Attach the body to a new case statement.
1383 ///
1384 /// By default, performs semantic analysis to build the new statement.
1385 /// Subclasses may override this routine to provide different behavior.
1386 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1387 getSema().ActOnCaseStmtBody(S, Body);
1388 return S;
1389 }
1390
1391 /// Build a new default statement.
1392 ///
1393 /// By default, performs semantic analysis to build the new statement.
1394 /// Subclasses may override this routine to provide different behavior.
1395 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1396 SourceLocation ColonLoc,
1397 Stmt *SubStmt) {
1398 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1399 /*CurScope=*/nullptr);
1400 }
1401
1402 /// Build a new label statement.
1403 ///
1404 /// By default, performs semantic analysis to build the new statement.
1405 /// Subclasses may override this routine to provide different behavior.
1406 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1407 SourceLocation ColonLoc, Stmt *SubStmt) {
1408 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1409 }
1410
1411 /// Build a new attributed statement.
1412 ///
1413 /// By default, performs semantic analysis to build the new statement.
1414 /// Subclasses may override this routine to provide different behavior.
1415 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1416 ArrayRef<const Attr *> Attrs,
1417 Stmt *SubStmt) {
1418 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1419 return StmtError();
1420 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1421 }
1422
1423 /// Build a new "if" statement.
1424 ///
1425 /// By default, performs semantic analysis to build the new statement.
1426 /// Subclasses may override this routine to provide different behavior.
1427 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1428 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1429 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1430 SourceLocation ElseLoc, Stmt *Else) {
1431 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1432 Then, ElseLoc, Else);
1433 }
1434
1435 /// Start building a new switch statement.
1436 ///
1437 /// By default, performs semantic analysis to build the new statement.
1438 /// Subclasses may override this routine to provide different behavior.
1439 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1440 SourceLocation LParenLoc, Stmt *Init,
1441 Sema::ConditionResult Cond,
1442 SourceLocation RParenLoc) {
1443 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1444 RParenLoc);
1445 }
1446
1447 /// Attach the body to the switch statement.
1448 ///
1449 /// By default, performs semantic analysis to build the new statement.
1450 /// Subclasses may override this routine to provide different behavior.
1451 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1452 Stmt *Switch, Stmt *Body) {
1453 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1454 }
1455
1456 /// Build a new while statement.
1457 ///
1458 /// By default, performs semantic analysis to build the new statement.
1459 /// Subclasses may override this routine to provide different behavior.
1460 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1461 Sema::ConditionResult Cond,
1462 SourceLocation RParenLoc, Stmt *Body) {
1463 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1464 }
1465
1466 /// Build a new do-while statement.
1467 ///
1468 /// By default, performs semantic analysis to build the new statement.
1469 /// Subclasses may override this routine to provide different behavior.
1470 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1471 SourceLocation WhileLoc, SourceLocation LParenLoc,
1472 Expr *Cond, SourceLocation RParenLoc) {
1473 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1474 Cond, RParenLoc);
1475 }
1476
1477 /// Build a new for statement.
1478 ///
1479 /// By default, performs semantic analysis to build the new statement.
1480 /// Subclasses may override this routine to provide different behavior.
1481 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1482 Stmt *Init, Sema::ConditionResult Cond,
1483 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1484 Stmt *Body) {
1485 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1486 Inc, RParenLoc, Body);
1487 }
1488
1489 /// Build a new goto statement.
1490 ///
1491 /// By default, performs semantic analysis to build the new statement.
1492 /// Subclasses may override this routine to provide different behavior.
1493 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1494 LabelDecl *Label) {
1495 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1496 }
1497
1498 /// Build a new indirect goto statement.
1499 ///
1500 /// By default, performs semantic analysis to build the new statement.
1501 /// Subclasses may override this routine to provide different behavior.
1502 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1503 SourceLocation StarLoc,
1504 Expr *Target) {
1505 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1506 }
1507
1508 /// Build a new return statement.
1509 ///
1510 /// By default, performs semantic analysis to build the new statement.
1511 /// Subclasses may override this routine to provide different behavior.
1512 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1513 return getSema().BuildReturnStmt(ReturnLoc, Result);
1514 }
1515
1516 /// Build a new declaration statement.
1517 ///
1518 /// By default, performs semantic analysis to build the new statement.
1519 /// Subclasses may override this routine to provide different behavior.
1520 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1521 SourceLocation StartLoc, SourceLocation EndLoc) {
1522 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1523 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1524 }
1525
1526 /// Build a new inline asm statement.
1527 ///
1528 /// By default, performs semantic analysis to build the new statement.
1529 /// Subclasses may override this routine to provide different behavior.
1530 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1531 bool IsVolatile, unsigned NumOutputs,
1532 unsigned NumInputs, IdentifierInfo **Names,
1533 MultiExprArg Constraints, MultiExprArg Exprs,
1534 Expr *AsmString, MultiExprArg Clobbers,
1535 unsigned NumLabels,
1536 SourceLocation RParenLoc) {
1537 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1538 NumInputs, Names, Constraints, Exprs,
1539 AsmString, Clobbers, NumLabels, RParenLoc);
1540 }
1541
1542 /// Build a new MS style inline asm statement.
1543 ///
1544 /// By default, performs semantic analysis to build the new statement.
1545 /// Subclasses may override this routine to provide different behavior.
1546 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1547 ArrayRef<Token> AsmToks,
1548 StringRef AsmString,
1549 unsigned NumOutputs, unsigned NumInputs,
1550 ArrayRef<StringRef> Constraints,
1551 ArrayRef<StringRef> Clobbers,
1552 ArrayRef<Expr*> Exprs,
1553 SourceLocation EndLoc) {
1554 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1555 NumOutputs, NumInputs,
1556 Constraints, Clobbers, Exprs, EndLoc);
1557 }
1558
1559 /// Build a new co_return statement.
1560 ///
1561 /// By default, performs semantic analysis to build the new statement.
1562 /// Subclasses may override this routine to provide different behavior.
1563 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1564 bool IsImplicit) {
1565 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1566 }
1567
1568 /// Build a new co_await expression.
1569 ///
1570 /// By default, performs semantic analysis to build the new expression.
1571 /// Subclasses may override this routine to provide different behavior.
1572 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1573 UnresolvedLookupExpr *OpCoawaitLookup,
1574 bool IsImplicit) {
1575 // This function rebuilds a coawait-expr given its operator.
1576 // For an explicit coawait-expr, the rebuild involves the full set
1577 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1578 // including calling await_transform().
1579 // For an implicit coawait-expr, we need to rebuild the "operator
1580 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1581 // This mirrors how the implicit CoawaitExpr is originally created
1582 // in Sema::ActOnCoroutineBodyStart().
1583 if (IsImplicit) {
1584 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1585 CoawaitLoc, Operand, OpCoawaitLookup);
1586 if (Suspend.isInvalid())
1587 return ExprError();
1588 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1589 Suspend.get(), true);
1590 }
1591
1592 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1593 OpCoawaitLookup);
1594 }
1595
1596 /// Build a new co_await expression.
1597 ///
1598 /// By default, performs semantic analysis to build the new expression.
1599 /// Subclasses may override this routine to provide different behavior.
1600 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1601 Expr *Result,
1602 UnresolvedLookupExpr *Lookup) {
1603 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1604 }
1605
1606 /// Build a new co_yield expression.
1607 ///
1608 /// By default, performs semantic analysis to build the new expression.
1609 /// Subclasses may override this routine to provide different behavior.
1610 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1611 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1612 }
1613
1614 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1615 return getSema().BuildCoroutineBodyStmt(Args);
1616 }
1617
1618 /// Build a new Objective-C \@try statement.
1619 ///
1620 /// By default, performs semantic analysis to build the new statement.
1621 /// Subclasses may override this routine to provide different behavior.
1622 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1623 Stmt *TryBody,
1624 MultiStmtArg CatchStmts,
1625 Stmt *Finally) {
1626 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1627 Finally);
1628 }
1629
1630 /// Rebuild an Objective-C exception declaration.
1631 ///
1632 /// By default, performs semantic analysis to build the new declaration.
1633 /// Subclasses may override this routine to provide different behavior.
1634 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1635 TypeSourceInfo *TInfo, QualType T) {
1636 return getSema().ObjC().BuildObjCExceptionDecl(
1637 TInfo, T, ExceptionDecl->getInnerLocStart(),
1638 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1639 }
1640
1641 /// Build a new Objective-C \@catch statement.
1642 ///
1643 /// By default, performs semantic analysis to build the new statement.
1644 /// Subclasses may override this routine to provide different behavior.
1645 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1646 SourceLocation RParenLoc,
1647 VarDecl *Var,
1648 Stmt *Body) {
1649 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1650 }
1651
1652 /// Build a new Objective-C \@finally statement.
1653 ///
1654 /// By default, performs semantic analysis to build the new statement.
1655 /// Subclasses may override this routine to provide different behavior.
1656 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1657 Stmt *Body) {
1658 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1659 }
1660
1661 /// Build a new Objective-C \@throw statement.
1662 ///
1663 /// By default, performs semantic analysis to build the new statement.
1664 /// Subclasses may override this routine to provide different behavior.
1665 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1666 Expr *Operand) {
1667 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1668 }
1669
1670 /// Build a new OpenMP Canonical loop.
1671 ///
1672 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1673 /// OMPCanonicalLoop.
1674 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1675 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1676 }
1677
1678 /// Build a new OpenMP executable directive.
1679 ///
1680 /// By default, performs semantic analysis to build the new statement.
1681 /// Subclasses may override this routine to provide different behavior.
1682 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1683 DeclarationNameInfo DirName,
1684 OpenMPDirectiveKind CancelRegion,
1685 ArrayRef<OMPClause *> Clauses,
1686 Stmt *AStmt, SourceLocation StartLoc,
1687 SourceLocation EndLoc) {
1688
1689 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1690 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1691 }
1692
1693 /// Build a new OpenMP informational directive.
1694 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1695 DeclarationNameInfo DirName,
1696 ArrayRef<OMPClause *> Clauses,
1697 Stmt *AStmt,
1698 SourceLocation StartLoc,
1699 SourceLocation EndLoc) {
1700
1701 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1702 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1703 }
1704
1705 /// Build a new OpenMP 'if' clause.
1706 ///
1707 /// By default, performs semantic analysis to build the new OpenMP clause.
1708 /// Subclasses may override this routine to provide different behavior.
1709 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1710 Expr *Condition, SourceLocation StartLoc,
1711 SourceLocation LParenLoc,
1712 SourceLocation NameModifierLoc,
1713 SourceLocation ColonLoc,
1714 SourceLocation EndLoc) {
1715 return getSema().OpenMP().ActOnOpenMPIfClause(
1716 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1717 EndLoc);
1718 }
1719
1720 /// Build a new OpenMP 'final' 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 *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1725 SourceLocation LParenLoc,
1726 SourceLocation EndLoc) {
1727 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1728 LParenLoc, EndLoc);
1729 }
1730
1731 /// Build a new OpenMP 'num_threads' clause.
1732 ///
1733 /// By default, performs semantic analysis to build the new OpenMP clause.
1734 /// Subclasses may override this routine to provide different behavior.
1735 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1736 Expr *NumThreads,
1737 SourceLocation StartLoc,
1738 SourceLocation LParenLoc,
1739 SourceLocation ModifierLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1742 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1743 }
1744
1745 /// Build a new OpenMP 'safelen' clause.
1746 ///
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1749 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1750 SourceLocation LParenLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1753 EndLoc);
1754 }
1755
1756 /// Build a new OpenMP 'simdlen' clause.
1757 ///
1758 /// By default, performs semantic analysis to build the new OpenMP clause.
1759 /// Subclasses may override this routine to provide different behavior.
1760 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1761 SourceLocation LParenLoc,
1762 SourceLocation EndLoc) {
1763 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1764 EndLoc);
1765 }
1766
1767 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1768 SourceLocation StartLoc,
1769 SourceLocation LParenLoc,
1770 SourceLocation EndLoc) {
1771 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1772 EndLoc);
1773 }
1774
1775 /// Build a new OpenMP 'permutation' clause.
1776 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1777 SourceLocation StartLoc,
1778 SourceLocation LParenLoc,
1779 SourceLocation EndLoc) {
1780 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1781 LParenLoc, EndLoc);
1782 }
1783
1784 /// Build a new OpenMP 'full' clause.
1785 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1786 SourceLocation EndLoc) {
1787 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1788 }
1789
1790 /// Build a new OpenMP 'partial' clause.
1791 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1792 SourceLocation LParenLoc,
1793 SourceLocation EndLoc) {
1794 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1795 LParenLoc, EndLoc);
1796 }
1797
1798 OMPClause *
1799 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1800 SourceLocation LParenLoc, SourceLocation FirstLoc,
1801 SourceLocation CountLoc, SourceLocation EndLoc) {
1802 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1803 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1804 }
1805
1806 /// Build a new OpenMP 'allocator' clause.
1807 ///
1808 /// By default, performs semantic analysis to build the new OpenMP clause.
1809 /// Subclasses may override this routine to provide different behavior.
1810 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1811 SourceLocation LParenLoc,
1812 SourceLocation EndLoc) {
1813 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1814 EndLoc);
1815 }
1816
1817 /// Build a new OpenMP 'collapse' clause.
1818 ///
1819 /// By default, performs semantic analysis to build the new OpenMP clause.
1820 /// Subclasses may override this routine to provide different behavior.
1821 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1822 SourceLocation LParenLoc,
1823 SourceLocation EndLoc) {
1824 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1825 LParenLoc, EndLoc);
1826 }
1827
1828 /// Build a new OpenMP 'default' clause.
1829 ///
1830 /// By default, performs semantic analysis to build the new OpenMP clause.
1831 /// Subclasses may override this routine to provide different behavior.
1832 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1833 OpenMPDefaultClauseVariableCategory VCKind,
1834 SourceLocation VCLoc,
1835 SourceLocation StartLoc,
1836 SourceLocation LParenLoc,
1837 SourceLocation EndLoc) {
1838 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1839 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1840 }
1841
1842 /// Build a new OpenMP 'proc_bind' clause.
1843 ///
1844 /// By default, performs semantic analysis to build the new OpenMP clause.
1845 /// Subclasses may override this routine to provide different behavior.
1846 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1847 SourceLocation KindKwLoc,
1848 SourceLocation StartLoc,
1849 SourceLocation LParenLoc,
1850 SourceLocation EndLoc) {
1851 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1852 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1853 }
1854 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1855 SourceLocation StartLoc,
1856 SourceLocation LParenLoc,
1857 SourceLocation EndLoc) {
1858 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1859 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1860 }
1861
1862 /// Build a new OpenMP 'schedule' clause.
1863 ///
1864 /// By default, performs semantic analysis to build the new OpenMP clause.
1865 /// Subclasses may override this routine to provide different behavior.
1866 OMPClause *RebuildOMPScheduleClause(
1867 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1868 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1869 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1870 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1871 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1872 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1873 CommaLoc, EndLoc);
1874 }
1875
1876 /// Build a new OpenMP 'ordered' clause.
1877 ///
1878 /// By default, performs semantic analysis to build the new OpenMP clause.
1879 /// Subclasses may override this routine to provide different behavior.
1880 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1881 SourceLocation EndLoc,
1882 SourceLocation LParenLoc, Expr *Num) {
1883 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1884 LParenLoc, Num);
1885 }
1886
1887 /// Build a new OpenMP 'nowait' clause.
1888 ///
1889 /// By default, performs semantic analysis to build the new OpenMP clause.
1890 /// Subclasses may override this routine to provide different behavior.
1891 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1892 SourceLocation LParenLoc,
1893 SourceLocation EndLoc) {
1894 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1895 LParenLoc, Condition);
1896 }
1897
1898 /// Build a new OpenMP 'private' clause.
1899 ///
1900 /// By default, performs semantic analysis to build the new OpenMP clause.
1901 /// Subclasses may override this routine to provide different behavior.
1902 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1903 SourceLocation StartLoc,
1904 SourceLocation LParenLoc,
1905 SourceLocation EndLoc) {
1906 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1907 LParenLoc, EndLoc);
1908 }
1909
1910 /// Build a new OpenMP 'firstprivate' clause.
1911 ///
1912 /// By default, performs semantic analysis to build the new OpenMP clause.
1913 /// Subclasses may override this routine to provide different behavior.
1914 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1915 SourceLocation StartLoc,
1916 SourceLocation LParenLoc,
1917 SourceLocation EndLoc) {
1918 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1919 LParenLoc, EndLoc);
1920 }
1921
1922 /// Build a new OpenMP 'lastprivate' clause.
1923 ///
1924 /// By default, performs semantic analysis to build the new OpenMP clause.
1925 /// Subclasses may override this routine to provide different behavior.
1926 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1927 OpenMPLastprivateModifier LPKind,
1928 SourceLocation LPKindLoc,
1929 SourceLocation ColonLoc,
1930 SourceLocation StartLoc,
1931 SourceLocation LParenLoc,
1932 SourceLocation EndLoc) {
1933 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1934 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1935 }
1936
1937 /// Build a new OpenMP 'shared' clause.
1938 ///
1939 /// By default, performs semantic analysis to build the new OpenMP clause.
1940 /// Subclasses may override this routine to provide different behavior.
1941 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1942 SourceLocation StartLoc,
1943 SourceLocation LParenLoc,
1944 SourceLocation EndLoc) {
1945 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1946 LParenLoc, EndLoc);
1947 }
1948
1949 /// Build a new OpenMP 'reduction' clause.
1950 ///
1951 /// By default, performs semantic analysis to build the new statement.
1952 /// Subclasses may override this routine to provide different behavior.
1953 OMPClause *RebuildOMPReductionClause(
1954 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1955 OpenMPOriginalSharingModifier OriginalSharingModifier,
1956 SourceLocation StartLoc, SourceLocation LParenLoc,
1957 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1958 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1959 const DeclarationNameInfo &ReductionId,
1960 ArrayRef<Expr *> UnresolvedReductions) {
1961 return getSema().OpenMP().ActOnOpenMPReductionClause(
1962 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1963 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1964 UnresolvedReductions);
1965 }
1966
1967 /// Build a new OpenMP 'task_reduction' clause.
1968 ///
1969 /// By default, performs semantic analysis to build the new statement.
1970 /// Subclasses may override this routine to provide different behavior.
1971 OMPClause *RebuildOMPTaskReductionClause(
1972 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1973 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1974 CXXScopeSpec &ReductionIdScopeSpec,
1975 const DeclarationNameInfo &ReductionId,
1976 ArrayRef<Expr *> UnresolvedReductions) {
1977 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1978 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1979 ReductionId, UnresolvedReductions);
1980 }
1981
1982 /// Build a new OpenMP 'in_reduction' clause.
1983 ///
1984 /// By default, performs semantic analysis to build the new statement.
1985 /// Subclasses may override this routine to provide different behavior.
1986 OMPClause *
1987 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1988 SourceLocation LParenLoc, SourceLocation ColonLoc,
1989 SourceLocation EndLoc,
1990 CXXScopeSpec &ReductionIdScopeSpec,
1991 const DeclarationNameInfo &ReductionId,
1992 ArrayRef<Expr *> UnresolvedReductions) {
1993 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1994 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1995 ReductionId, UnresolvedReductions);
1996 }
1997
1998 /// Build a new OpenMP 'linear' clause.
1999 ///
2000 /// By default, performs semantic analysis to build the new OpenMP clause.
2001 /// Subclasses may override this routine to provide different behavior.
2002 OMPClause *RebuildOMPLinearClause(
2003 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2004 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2005 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2006 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2007 return getSema().OpenMP().ActOnOpenMPLinearClause(
2008 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2009 StepModifierLoc, EndLoc);
2010 }
2011
2012 /// Build a new OpenMP 'aligned' clause.
2013 ///
2014 /// By default, performs semantic analysis to build the new OpenMP clause.
2015 /// Subclasses may override this routine to provide different behavior.
2016 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2017 SourceLocation StartLoc,
2018 SourceLocation LParenLoc,
2019 SourceLocation ColonLoc,
2020 SourceLocation EndLoc) {
2021 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2022 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2023 }
2024
2025 /// Build a new OpenMP 'copyin' clause.
2026 ///
2027 /// By default, performs semantic analysis to build the new OpenMP clause.
2028 /// Subclasses may override this routine to provide different behavior.
2029 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2030 SourceLocation StartLoc,
2031 SourceLocation LParenLoc,
2032 SourceLocation EndLoc) {
2033 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2034 LParenLoc, EndLoc);
2035 }
2036
2037 /// Build a new OpenMP 'copyprivate' clause.
2038 ///
2039 /// By default, performs semantic analysis to build the new OpenMP clause.
2040 /// Subclasses may override this routine to provide different behavior.
2041 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2042 SourceLocation StartLoc,
2043 SourceLocation LParenLoc,
2044 SourceLocation EndLoc) {
2045 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2046 LParenLoc, EndLoc);
2047 }
2048
2049 /// Build a new OpenMP 'flush' pseudo clause.
2050 ///
2051 /// By default, performs semantic analysis to build the new OpenMP clause.
2052 /// Subclasses may override this routine to provide different behavior.
2053 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2054 SourceLocation StartLoc,
2055 SourceLocation LParenLoc,
2056 SourceLocation EndLoc) {
2057 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2058 LParenLoc, EndLoc);
2059 }
2060
2061 /// Build a new OpenMP 'depobj' pseudo clause.
2062 ///
2063 /// By default, performs semantic analysis to build the new OpenMP clause.
2064 /// Subclasses may override this routine to provide different behavior.
2065 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2066 SourceLocation LParenLoc,
2067 SourceLocation EndLoc) {
2068 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2069 LParenLoc, EndLoc);
2070 }
2071
2072 /// Build a new OpenMP 'depend' pseudo clause.
2073 ///
2074 /// By default, performs semantic analysis to build the new OpenMP clause.
2075 /// Subclasses may override this routine to provide different behavior.
2076 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2077 Expr *DepModifier, ArrayRef<Expr *> VarList,
2078 SourceLocation StartLoc,
2079 SourceLocation LParenLoc,
2080 SourceLocation EndLoc) {
2081 return getSema().OpenMP().ActOnOpenMPDependClause(
2082 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2083 }
2084
2085 /// Build a new OpenMP 'device' clause.
2086 ///
2087 /// By default, performs semantic analysis to build the new statement.
2088 /// Subclasses may override this routine to provide different behavior.
2089 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2090 Expr *Device, SourceLocation StartLoc,
2091 SourceLocation LParenLoc,
2092 SourceLocation ModifierLoc,
2093 SourceLocation EndLoc) {
2094 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2095 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2096 }
2097
2098 /// Build a new OpenMP 'map' clause.
2099 ///
2100 /// By default, performs semantic analysis to build the new OpenMP clause.
2101 /// Subclasses may override this routine to provide different behavior.
2102 OMPClause *RebuildOMPMapClause(
2103 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2104 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2105 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2106 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2107 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2108 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2109 return getSema().OpenMP().ActOnOpenMPMapClause(
2110 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2111 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2112 ColonLoc, VarList, Locs,
2113 /*NoDiagnose=*/false, UnresolvedMappers);
2114 }
2115
2116 /// Build a new OpenMP 'allocate' clause.
2117 ///
2118 /// By default, performs semantic analysis to build the new OpenMP clause.
2119 /// Subclasses may override this routine to provide different behavior.
2120 OMPClause *
2121 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2122 OpenMPAllocateClauseModifier FirstModifier,
2123 SourceLocation FirstModifierLoc,
2124 OpenMPAllocateClauseModifier SecondModifier,
2125 SourceLocation SecondModifierLoc,
2126 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2127 SourceLocation LParenLoc, SourceLocation ColonLoc,
2128 SourceLocation EndLoc) {
2129 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2130 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2131 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2132 }
2133
2134 /// Build a new OpenMP 'num_teams' clause.
2135 ///
2136 /// By default, performs semantic analysis to build the new statement.
2137 /// Subclasses may override this routine to provide different behavior.
2138 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2139 SourceLocation StartLoc,
2140 SourceLocation LParenLoc,
2141 SourceLocation EndLoc) {
2142 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2143 LParenLoc, EndLoc);
2144 }
2145
2146 /// Build a new OpenMP 'thread_limit' clause.
2147 ///
2148 /// By default, performs semantic analysis to build the new statement.
2149 /// Subclasses may override this routine to provide different behavior.
2150 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2151 SourceLocation StartLoc,
2152 SourceLocation LParenLoc,
2153 SourceLocation EndLoc) {
2154 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2155 LParenLoc, EndLoc);
2156 }
2157
2158 /// Build a new OpenMP 'priority' clause.
2159 ///
2160 /// By default, performs semantic analysis to build the new statement.
2161 /// Subclasses may override this routine to provide different behavior.
2162 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2163 SourceLocation LParenLoc,
2164 SourceLocation EndLoc) {
2165 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2166 LParenLoc, EndLoc);
2167 }
2168
2169 /// Build a new OpenMP 'grainsize' clause.
2170 ///
2171 /// By default, performs semantic analysis to build the new statement.
2172 /// Subclasses may override this routine to provide different behavior.
2173 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2174 Expr *Device, SourceLocation StartLoc,
2175 SourceLocation LParenLoc,
2176 SourceLocation ModifierLoc,
2177 SourceLocation EndLoc) {
2178 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2179 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2180 }
2181
2182 /// Build a new OpenMP 'num_tasks' clause.
2183 ///
2184 /// By default, performs semantic analysis to build the new statement.
2185 /// Subclasses may override this routine to provide different behavior.
2186 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2187 Expr *NumTasks, SourceLocation StartLoc,
2188 SourceLocation LParenLoc,
2189 SourceLocation ModifierLoc,
2190 SourceLocation EndLoc) {
2191 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2192 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2193 }
2194
2195 /// Build a new OpenMP 'hint' clause.
2196 ///
2197 /// By default, performs semantic analysis to build the new statement.
2198 /// Subclasses may override this routine to provide different behavior.
2199 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2200 SourceLocation LParenLoc,
2201 SourceLocation EndLoc) {
2202 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2203 EndLoc);
2204 }
2205
2206 /// Build a new OpenMP 'detach' clause.
2207 ///
2208 /// By default, performs semantic analysis to build the new statement.
2209 /// Subclasses may override this routine to provide different behavior.
2210 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2211 SourceLocation LParenLoc,
2212 SourceLocation EndLoc) {
2213 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2214 EndLoc);
2215 }
2216
2217 /// Build a new OpenMP 'dist_schedule' clause.
2218 ///
2219 /// By default, performs semantic analysis to build the new OpenMP clause.
2220 /// Subclasses may override this routine to provide different behavior.
2221 OMPClause *
2222 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2223 Expr *ChunkSize, SourceLocation StartLoc,
2224 SourceLocation LParenLoc, SourceLocation KindLoc,
2225 SourceLocation CommaLoc, SourceLocation EndLoc) {
2226 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2227 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2228 }
2229
2230 /// Build a new OpenMP 'to' clause.
2231 ///
2232 /// By default, performs semantic analysis to build the new statement.
2233 /// Subclasses may override this routine to provide different behavior.
2234 OMPClause *
2235 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2236 ArrayRef<SourceLocation> MotionModifiersLoc,
2237 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2238 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2239 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2240 ArrayRef<Expr *> UnresolvedMappers) {
2241 return getSema().OpenMP().ActOnOpenMPToClause(
2242 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2243 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2244 UnresolvedMappers);
2245 }
2246
2247 /// Build a new OpenMP 'from' clause.
2248 ///
2249 /// By default, performs semantic analysis to build the new statement.
2250 /// Subclasses may override this routine to provide different behavior.
2251 OMPClause *
2252 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2253 ArrayRef<SourceLocation> MotionModifiersLoc,
2254 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2255 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2256 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2257 ArrayRef<Expr *> UnresolvedMappers) {
2258 return getSema().OpenMP().ActOnOpenMPFromClause(
2259 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2260 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2261 UnresolvedMappers);
2262 }
2263
2264 /// Build a new OpenMP 'use_device_ptr' clause.
2265 ///
2266 /// By default, performs semantic analysis to build the new OpenMP clause.
2267 /// Subclasses may override this routine to provide different behavior.
2268 OMPClause *RebuildOMPUseDevicePtrClause(
2269 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2270 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2271 SourceLocation FallbackModifierLoc) {
2272 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2273 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2274 }
2275
2276 /// Build a new OpenMP 'use_device_addr' clause.
2277 ///
2278 /// By default, performs semantic analysis to build the new OpenMP clause.
2279 /// Subclasses may override this routine to provide different behavior.
2280 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2281 const OMPVarListLocTy &Locs) {
2282 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2283 }
2284
2285 /// Build a new OpenMP 'is_device_ptr' clause.
2286 ///
2287 /// By default, performs semantic analysis to build the new OpenMP clause.
2288 /// Subclasses may override this routine to provide different behavior.
2289 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2290 const OMPVarListLocTy &Locs) {
2291 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2292 }
2293
2294 /// Build a new OpenMP 'has_device_addr' clause.
2295 ///
2296 /// By default, performs semantic analysis to build the new OpenMP clause.
2297 /// Subclasses may override this routine to provide different behavior.
2298 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2299 const OMPVarListLocTy &Locs) {
2300 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2301 }
2302
2303 /// Build a new OpenMP 'defaultmap' clause.
2304 ///
2305 /// By default, performs semantic analysis to build the new OpenMP clause.
2306 /// Subclasses may override this routine to provide different behavior.
2307 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2308 OpenMPDefaultmapClauseKind Kind,
2309 SourceLocation StartLoc,
2310 SourceLocation LParenLoc,
2311 SourceLocation MLoc,
2312 SourceLocation KindLoc,
2313 SourceLocation EndLoc) {
2314 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2315 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2316 }
2317
2318 /// Build a new OpenMP 'nontemporal' 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 *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2323 SourceLocation StartLoc,
2324 SourceLocation LParenLoc,
2325 SourceLocation EndLoc) {
2326 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2327 LParenLoc, EndLoc);
2328 }
2329
2330 /// Build a new OpenMP 'inclusive' clause.
2331 ///
2332 /// By default, performs semantic analysis to build the new OpenMP clause.
2333 /// Subclasses may override this routine to provide different behavior.
2334 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2335 SourceLocation StartLoc,
2336 SourceLocation LParenLoc,
2337 SourceLocation EndLoc) {
2338 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2339 LParenLoc, EndLoc);
2340 }
2341
2342 /// Build a new OpenMP 'exclusive' clause.
2343 ///
2344 /// By default, performs semantic analysis to build the new OpenMP clause.
2345 /// Subclasses may override this routine to provide different behavior.
2346 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2347 SourceLocation StartLoc,
2348 SourceLocation LParenLoc,
2349 SourceLocation EndLoc) {
2350 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2351 LParenLoc, EndLoc);
2352 }
2353
2354 /// Build a new OpenMP 'uses_allocators' clause.
2355 ///
2356 /// By default, performs semantic analysis to build the new OpenMP clause.
2357 /// Subclasses may override this routine to provide different behavior.
2358 OMPClause *RebuildOMPUsesAllocatorsClause(
2359 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2360 SourceLocation LParenLoc, SourceLocation EndLoc) {
2361 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2362 StartLoc, LParenLoc, EndLoc, Data);
2363 }
2364
2365 /// Build a new OpenMP 'affinity' clause.
2366 ///
2367 /// By default, performs semantic analysis to build the new OpenMP clause.
2368 /// Subclasses may override this routine to provide different behavior.
2369 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2370 SourceLocation LParenLoc,
2371 SourceLocation ColonLoc,
2372 SourceLocation EndLoc, Expr *Modifier,
2373 ArrayRef<Expr *> Locators) {
2374 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2375 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2376 }
2377
2378 /// Build a new OpenMP 'order' clause.
2379 ///
2380 /// By default, performs semantic analysis to build the new OpenMP clause.
2381 /// Subclasses may override this routine to provide different behavior.
2382 OMPClause *RebuildOMPOrderClause(
2383 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2384 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2385 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2386 return getSema().OpenMP().ActOnOpenMPOrderClause(
2387 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2388 }
2389
2390 /// Build a new OpenMP 'init' clause.
2391 ///
2392 /// By default, performs semantic analysis to build the new OpenMP clause.
2393 /// Subclasses may override this routine to provide different behavior.
2394 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2395 SourceLocation StartLoc,
2396 SourceLocation LParenLoc,
2397 SourceLocation VarLoc,
2398 SourceLocation EndLoc) {
2399 return getSema().OpenMP().ActOnOpenMPInitClause(
2400 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2401 }
2402
2403 /// Build a new OpenMP 'use' clause.
2404 ///
2405 /// By default, performs semantic analysis to build the new OpenMP clause.
2406 /// Subclasses may override this routine to provide different behavior.
2407 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2408 SourceLocation LParenLoc,
2409 SourceLocation VarLoc, SourceLocation EndLoc) {
2410 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2411 LParenLoc, VarLoc, EndLoc);
2412 }
2413
2414 /// Build a new OpenMP 'destroy' clause.
2415 ///
2416 /// By default, performs semantic analysis to build the new OpenMP clause.
2417 /// Subclasses may override this routine to provide different behavior.
2418 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2419 SourceLocation LParenLoc,
2420 SourceLocation VarLoc,
2421 SourceLocation EndLoc) {
2422 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2423 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2424 }
2425
2426 /// Build a new OpenMP 'novariants' clause.
2427 ///
2428 /// By default, performs semantic analysis to build the new OpenMP clause.
2429 /// Subclasses may override this routine to provide different behavior.
2430 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2431 SourceLocation StartLoc,
2432 SourceLocation LParenLoc,
2433 SourceLocation EndLoc) {
2434 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2435 LParenLoc, EndLoc);
2436 }
2437
2438 /// Build a new OpenMP 'nocontext' clause.
2439 ///
2440 /// By default, performs semantic analysis to build the new OpenMP clause.
2441 /// Subclasses may override this routine to provide different behavior.
2442 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2443 SourceLocation LParenLoc,
2444 SourceLocation EndLoc) {
2445 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2446 LParenLoc, EndLoc);
2447 }
2448
2449 /// Build a new OpenMP 'filter' clause.
2450 ///
2451 /// By default, performs semantic analysis to build the new OpenMP clause.
2452 /// Subclasses may override this routine to provide different behavior.
2453 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2454 SourceLocation LParenLoc,
2455 SourceLocation EndLoc) {
2456 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2457 LParenLoc, EndLoc);
2458 }
2459
2460 /// Build a new OpenMP 'bind' clause.
2461 ///
2462 /// By default, performs semantic analysis to build the new OpenMP clause.
2463 /// Subclasses may override this routine to provide different behavior.
2464 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2465 SourceLocation KindLoc,
2466 SourceLocation StartLoc,
2467 SourceLocation LParenLoc,
2468 SourceLocation EndLoc) {
2469 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2470 LParenLoc, EndLoc);
2471 }
2472
2473 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2474 ///
2475 /// By default, performs semantic analysis to build the new OpenMP clause.
2476 /// Subclasses may override this routine to provide different behavior.
2477 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2478 SourceLocation LParenLoc,
2479 SourceLocation EndLoc) {
2480 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2481 LParenLoc, EndLoc);
2482 }
2483
2484 /// Build a new OpenMP 'dyn_groupprivate' clause.
2485 ///
2486 /// By default, performs semantic analysis to build the new OpenMP clause.
2487 /// Subclasses may override this routine to provide different behavior.
2488 OMPClause *RebuildOMPDynGroupprivateClause(
2489 OpenMPDynGroupprivateClauseModifier M1,
2490 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2491 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2492 SourceLocation M2Loc, SourceLocation EndLoc) {
2493 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2494 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2495 }
2496
2497 /// Build a new OpenMP 'ompx_attribute' clause.
2498 ///
2499 /// By default, performs semantic analysis to build the new OpenMP clause.
2500 /// Subclasses may override this routine to provide different behavior.
2501 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2502 SourceLocation StartLoc,
2503 SourceLocation LParenLoc,
2504 SourceLocation EndLoc) {
2505 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2506 LParenLoc, EndLoc);
2507 }
2508
2509 /// Build a new OpenMP 'ompx_bare' clause.
2510 ///
2511 /// By default, performs semantic analysis to build the new OpenMP clause.
2512 /// Subclasses may override this routine to provide different behavior.
2513 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2514 SourceLocation EndLoc) {
2515 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2516 }
2517
2518 /// Build a new OpenMP 'align' clause.
2519 ///
2520 /// By default, performs semantic analysis to build the new OpenMP clause.
2521 /// Subclasses may override this routine to provide different behavior.
2522 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2523 SourceLocation LParenLoc,
2524 SourceLocation EndLoc) {
2525 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2526 EndLoc);
2527 }
2528
2529 /// Build a new OpenMP 'at' clause.
2530 ///
2531 /// By default, performs semantic analysis to build the new OpenMP clause.
2532 /// Subclasses may override this routine to provide different behavior.
2533 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2534 SourceLocation StartLoc,
2535 SourceLocation LParenLoc,
2536 SourceLocation EndLoc) {
2537 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2538 LParenLoc, EndLoc);
2539 }
2540
2541 /// Build a new OpenMP 'severity' clause.
2542 ///
2543 /// By default, performs semantic analysis to build the new OpenMP clause.
2544 /// Subclasses may override this routine to provide different behavior.
2545 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2546 SourceLocation KwLoc,
2547 SourceLocation StartLoc,
2548 SourceLocation LParenLoc,
2549 SourceLocation EndLoc) {
2550 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2551 LParenLoc, EndLoc);
2552 }
2553
2554 /// Build a new OpenMP 'message' clause.
2555 ///
2556 /// By default, performs semantic analysis to build the new OpenMP clause.
2557 /// Subclasses may override this routine to provide different behavior.
2558 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2559 SourceLocation LParenLoc,
2560 SourceLocation EndLoc) {
2561 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2562 EndLoc);
2563 }
2564
2565 /// Build a new OpenMP 'doacross' clause.
2566 ///
2567 /// By default, performs semantic analysis to build the new OpenMP clause.
2568 /// Subclasses may override this routine to provide different behavior.
2569 OMPClause *
2570 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2571 SourceLocation DepLoc, SourceLocation ColonLoc,
2572 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2573 SourceLocation LParenLoc, SourceLocation EndLoc) {
2574 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2575 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2576 }
2577
2578 /// Build a new OpenMP 'holds' clause.
2579 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2580 SourceLocation LParenLoc,
2581 SourceLocation EndLoc) {
2582 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2583 EndLoc);
2584 }
2585
2586 /// Rebuild the operand to an Objective-C \@synchronized statement.
2587 ///
2588 /// By default, performs semantic analysis to build the new statement.
2589 /// Subclasses may override this routine to provide different behavior.
2590 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2591 Expr *object) {
2592 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2593 }
2594
2595 /// Build a new Objective-C \@synchronized statement.
2596 ///
2597 /// By default, performs semantic analysis to build the new statement.
2598 /// Subclasses may override this routine to provide different behavior.
2599 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2600 Expr *Object, Stmt *Body) {
2601 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2602 }
2603
2604 /// Build a new Objective-C \@autoreleasepool statement.
2605 ///
2606 /// By default, performs semantic analysis to build the new statement.
2607 /// Subclasses may override this routine to provide different behavior.
2608 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2609 Stmt *Body) {
2610 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2611 }
2612
2613 /// Build a new Objective-C fast enumeration statement.
2614 ///
2615 /// By default, performs semantic analysis to build the new statement.
2616 /// Subclasses may override this routine to provide different behavior.
2617 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2618 Stmt *Element,
2619 Expr *Collection,
2620 SourceLocation RParenLoc,
2621 Stmt *Body) {
2622 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2623 ForLoc, Element, Collection, RParenLoc);
2624 if (ForEachStmt.isInvalid())
2625 return StmtError();
2626
2627 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2628 Body);
2629 }
2630
2631 /// Build a new C++ exception declaration.
2632 ///
2633 /// By default, performs semantic analysis to build the new decaration.
2634 /// Subclasses may override this routine to provide different behavior.
2635 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2636 TypeSourceInfo *Declarator,
2637 SourceLocation StartLoc,
2638 SourceLocation IdLoc,
2639 IdentifierInfo *Id) {
2640 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2641 StartLoc, IdLoc, Id);
2642 if (Var)
2643 getSema().CurContext->addDecl(Var);
2644 return Var;
2645 }
2646
2647 /// Build a new C++ catch statement.
2648 ///
2649 /// By default, performs semantic analysis to build the new statement.
2650 /// Subclasses may override this routine to provide different behavior.
2651 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2652 VarDecl *ExceptionDecl,
2653 Stmt *Handler) {
2654 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2655 Handler));
2656 }
2657
2658 /// Build a new C++ try statement.
2659 ///
2660 /// By default, performs semantic analysis to build the new statement.
2661 /// Subclasses may override this routine to provide different behavior.
2662 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2663 ArrayRef<Stmt *> Handlers) {
2664 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2665 }
2666
2667 /// Build a new C++0x range-based for statement.
2668 ///
2669 /// By default, performs semantic analysis to build the new statement.
2670 /// Subclasses may override this routine to provide different behavior.
2671 StmtResult RebuildCXXForRangeStmt(
2672 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2673 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2674 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2675 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2676 // If we've just learned that the range is actually an Objective-C
2677 // collection, treat this as an Objective-C fast enumeration loop.
2678 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2679 if (RangeStmt->isSingleDecl()) {
2680 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2681 if (RangeVar->isInvalidDecl())
2682 return StmtError();
2683
2684 Expr *RangeExpr = RangeVar->getInit();
2685 if (!RangeExpr->isTypeDependent() &&
2686 RangeExpr->getType()->isObjCObjectPointerType()) {
2687 // FIXME: Support init-statements in Objective-C++20 ranged for
2688 // statement.
2689 if (Init) {
2690 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2691 DiagID: diag::err_objc_for_range_init_stmt)
2692 << Init->getSourceRange();
2693 }
2694 return getSema().ObjC().ActOnObjCForCollectionStmt(
2695 ForLoc, LoopVar, RangeExpr, RParenLoc);
2696 }
2697 }
2698 }
2699 }
2700
2701 return getSema().BuildCXXForRangeStmt(
2702 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2703 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2704 }
2705
2706 /// Build a new C++0x range-based for statement.
2707 ///
2708 /// By default, performs semantic analysis to build the new statement.
2709 /// Subclasses may override this routine to provide different behavior.
2710 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2711 bool IsIfExists,
2712 NestedNameSpecifierLoc QualifierLoc,
2713 DeclarationNameInfo NameInfo,
2714 Stmt *Nested) {
2715 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2716 QualifierLoc, NameInfo, Nested);
2717 }
2718
2719 /// Attach body to a C++0x range-based for statement.
2720 ///
2721 /// By default, performs semantic analysis to finish the new statement.
2722 /// Subclasses may override this routine to provide different behavior.
2723 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2724 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2725 }
2726
2727 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2728 Stmt *TryBlock, Stmt *Handler) {
2729 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2730 }
2731
2732 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2733 Stmt *Block) {
2734 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2735 }
2736
2737 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2738 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2739 }
2740
2741 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2742 SourceLocation LParen,
2743 SourceLocation RParen,
2744 TypeSourceInfo *TSI) {
2745 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2746 TSI);
2747 }
2748
2749 /// Build a new predefined expression.
2750 ///
2751 /// By default, performs semantic analysis to build the new expression.
2752 /// Subclasses may override this routine to provide different behavior.
2753 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2754 return getSema().BuildPredefinedExpr(Loc, IK);
2755 }
2756
2757 /// Build a new expression that references a declaration.
2758 ///
2759 /// By default, performs semantic analysis to build the new expression.
2760 /// Subclasses may override this routine to provide different behavior.
2761 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2762 LookupResult &R,
2763 bool RequiresADL) {
2764 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2765 }
2766
2767
2768 /// Build a new expression that references a declaration.
2769 ///
2770 /// By default, performs semantic analysis to build the new expression.
2771 /// Subclasses may override this routine to provide different behavior.
2772 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2773 ValueDecl *VD,
2774 const DeclarationNameInfo &NameInfo,
2775 NamedDecl *Found,
2776 TemplateArgumentListInfo *TemplateArgs) {
2777 CXXScopeSpec SS;
2778 SS.Adopt(Other: QualifierLoc);
2779 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2780 TemplateArgs);
2781 }
2782
2783 /// Build a new expression in parentheses.
2784 ///
2785 /// By default, performs semantic analysis to build the new expression.
2786 /// Subclasses may override this routine to provide different behavior.
2787 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2788 SourceLocation RParen) {
2789 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2790 }
2791
2792 /// Build a new pseudo-destructor expression.
2793 ///
2794 /// By default, performs semantic analysis to build the new expression.
2795 /// Subclasses may override this routine to provide different behavior.
2796 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2797 SourceLocation OperatorLoc,
2798 bool isArrow,
2799 CXXScopeSpec &SS,
2800 TypeSourceInfo *ScopeType,
2801 SourceLocation CCLoc,
2802 SourceLocation TildeLoc,
2803 PseudoDestructorTypeStorage Destroyed);
2804
2805 /// Build a new unary operator expression.
2806 ///
2807 /// By default, performs semantic analysis to build the new expression.
2808 /// Subclasses may override this routine to provide different behavior.
2809 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2810 UnaryOperatorKind Opc,
2811 Expr *SubExpr) {
2812 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2813 }
2814
2815 /// Build a new builtin offsetof expression.
2816 ///
2817 /// By default, performs semantic analysis to build the new expression.
2818 /// Subclasses may override this routine to provide different behavior.
2819 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2820 TypeSourceInfo *Type,
2821 ArrayRef<Sema::OffsetOfComponent> Components,
2822 SourceLocation RParenLoc) {
2823 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2824 RParenLoc);
2825 }
2826
2827 /// Build a new sizeof, alignof or vec_step expression with a
2828 /// type argument.
2829 ///
2830 /// By default, performs semantic analysis to build the new expression.
2831 /// Subclasses may override this routine to provide different behavior.
2832 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2833 SourceLocation OpLoc,
2834 UnaryExprOrTypeTrait ExprKind,
2835 SourceRange R) {
2836 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2837 }
2838
2839 /// Build a new sizeof, alignof or vec step expression with an
2840 /// expression argument.
2841 ///
2842 /// By default, performs semantic analysis to build the new expression.
2843 /// Subclasses may override this routine to provide different behavior.
2844 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2845 UnaryExprOrTypeTrait ExprKind,
2846 SourceRange R) {
2847 ExprResult Result
2848 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2849 if (Result.isInvalid())
2850 return ExprError();
2851
2852 return Result;
2853 }
2854
2855 /// Build a new array subscript expression.
2856 ///
2857 /// By default, performs semantic analysis to build the new expression.
2858 /// Subclasses may override this routine to provide different behavior.
2859 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2860 SourceLocation LBracketLoc,
2861 Expr *RHS,
2862 SourceLocation RBracketLoc) {
2863 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2864 LBracketLoc, RHS,
2865 RBracketLoc);
2866 }
2867
2868 /// Build a new matrix single subscript expression.
2869 ///
2870 /// By default, performs semantic analysis to build the new expression.
2871 /// Subclasses may override this routine to provide different behavior.
2872 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2873 SourceLocation RBracketLoc) {
2874 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2875 RBracketLoc);
2876 }
2877
2878 /// Build a new matrix subscript expression.
2879 ///
2880 /// By default, performs semantic analysis to build the new expression.
2881 /// Subclasses may override this routine to provide different behavior.
2882 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2883 Expr *ColumnIdx,
2884 SourceLocation RBracketLoc) {
2885 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2886 RBracketLoc);
2887 }
2888
2889 /// Build a new array section expression.
2890 ///
2891 /// By default, performs semantic analysis to build the new expression.
2892 /// Subclasses may override this routine to provide different behavior.
2893 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2894 SourceLocation LBracketLoc,
2895 Expr *LowerBound,
2896 SourceLocation ColonLocFirst,
2897 SourceLocation ColonLocSecond,
2898 Expr *Length, Expr *Stride,
2899 SourceLocation RBracketLoc) {
2900 if (IsOMPArraySection)
2901 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2902 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2903 Stride, RBracketLoc);
2904
2905 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2906 "Stride/second colon not allowed for OpenACC");
2907
2908 return getSema().OpenACC().ActOnArraySectionExpr(
2909 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2910 }
2911
2912 /// Build a new array shaping expression.
2913 ///
2914 /// By default, performs semantic analysis to build the new expression.
2915 /// Subclasses may override this routine to provide different behavior.
2916 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2917 SourceLocation RParenLoc,
2918 ArrayRef<Expr *> Dims,
2919 ArrayRef<SourceRange> BracketsRanges) {
2920 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2921 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2922 }
2923
2924 /// Build a new iterator expression.
2925 ///
2926 /// By default, performs semantic analysis to build the new expression.
2927 /// Subclasses may override this routine to provide different behavior.
2928 ExprResult
2929 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2930 SourceLocation RLoc,
2931 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2932 return getSema().OpenMP().ActOnOMPIteratorExpr(
2933 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2934 }
2935
2936 /// Build a new call expression.
2937 ///
2938 /// By default, performs semantic analysis to build the new expression.
2939 /// Subclasses may override this routine to provide different behavior.
2940 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2941 MultiExprArg Args,
2942 SourceLocation RParenLoc,
2943 Expr *ExecConfig = nullptr) {
2944 return getSema().ActOnCallExpr(
2945 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2946 }
2947
2948 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2949 MultiExprArg Args,
2950 SourceLocation RParenLoc) {
2951 return getSema().ActOnArraySubscriptExpr(
2952 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2953 }
2954
2955 /// Build a new member access 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 RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2960 bool isArrow,
2961 NestedNameSpecifierLoc QualifierLoc,
2962 SourceLocation TemplateKWLoc,
2963 const DeclarationNameInfo &MemberNameInfo,
2964 ValueDecl *Member,
2965 NamedDecl *FoundDecl,
2966 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2967 NamedDecl *FirstQualifierInScope) {
2968 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2969 isArrow);
2970 if (!Member->getDeclName()) {
2971 // We have a reference to an unnamed field. This is always the
2972 // base of an anonymous struct/union member access, i.e. the
2973 // field is always of record type.
2974 assert(Member->getType()->isRecordType() &&
2975 "unnamed member not of record type?");
2976
2977 BaseResult =
2978 getSema().PerformObjectMemberConversion(BaseResult.get(),
2979 QualifierLoc.getNestedNameSpecifier(),
2980 FoundDecl, Member);
2981 if (BaseResult.isInvalid())
2982 return ExprError();
2983 Base = BaseResult.get();
2984
2985 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2986 // from the AST, so we need to re-insert them if needed (since
2987 // `BuildFieldRefereneExpr()` doesn't do this).
2988 if (!isArrow && Base->isPRValue()) {
2989 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2990 if (BaseResult.isInvalid())
2991 return ExprError();
2992 Base = BaseResult.get();
2993 }
2994
2995 CXXScopeSpec EmptySS;
2996 return getSema().BuildFieldReferenceExpr(
2997 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
2998 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
2999 MemberNameInfo);
3000 }
3001
3002 CXXScopeSpec SS;
3003 SS.Adopt(Other: QualifierLoc);
3004
3005 Base = BaseResult.get();
3006 if (Base->containsErrors())
3007 return ExprError();
3008
3009 QualType BaseType = Base->getType();
3010
3011 if (isArrow && !BaseType->isPointerType())
3012 return ExprError();
3013
3014 // FIXME: this involves duplicating earlier analysis in a lot of
3015 // cases; we should avoid this when possible.
3016 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3017 R.addDecl(D: FoundDecl);
3018 R.resolveKind();
3019
3020 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3021 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3022 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3023 ->getType()
3024 ->getPointeeType()
3025 ->getAsCXXRecordDecl()) {
3026 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3027 // In unevaluated contexts, an expression supposed to be a member access
3028 // might reference a member in an unrelated class.
3029 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3030 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3031 VK_LValue, Member->getLocation());
3032 }
3033 }
3034
3035 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3036 SS, TemplateKWLoc,
3037 FirstQualifierInScope,
3038 R, ExplicitTemplateArgs,
3039 /*S*/nullptr);
3040 }
3041
3042 /// Build a new binary operator expression.
3043 ///
3044 /// By default, performs semantic analysis to build the new expression.
3045 /// Subclasses may override this routine to provide different behavior.
3046 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3047 Expr *LHS, Expr *RHS,
3048 bool ForFoldExpression = false) {
3049 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3050 ForFoldExpression);
3051 }
3052
3053 /// Build a new rewritten operator expression.
3054 ///
3055 /// By default, performs semantic analysis to build the new expression.
3056 /// Subclasses may override this routine to provide different behavior.
3057 ExprResult RebuildCXXRewrittenBinaryOperator(
3058 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3059 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3060 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3061 RHS, /*RequiresADL*/false);
3062 }
3063
3064 /// Build a new conditional operator expression.
3065 ///
3066 /// By default, performs semantic analysis to build the new expression.
3067 /// Subclasses may override this routine to provide different behavior.
3068 ExprResult RebuildConditionalOperator(Expr *Cond,
3069 SourceLocation QuestionLoc,
3070 Expr *LHS,
3071 SourceLocation ColonLoc,
3072 Expr *RHS) {
3073 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3074 LHS, RHS);
3075 }
3076
3077 /// Build a new C-style cast expression.
3078 ///
3079 /// By default, performs semantic analysis to build the new expression.
3080 /// Subclasses may override this routine to provide different behavior.
3081 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3082 TypeSourceInfo *TInfo,
3083 SourceLocation RParenLoc,
3084 Expr *SubExpr) {
3085 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3086 SubExpr);
3087 }
3088
3089 /// Build a new compound literal expression.
3090 ///
3091 /// By default, performs semantic analysis to build the new expression.
3092 /// Subclasses may override this routine to provide different behavior.
3093 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3094 TypeSourceInfo *TInfo,
3095 SourceLocation RParenLoc,
3096 Expr *Init) {
3097 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3098 Init);
3099 }
3100
3101 /// Build a new extended vector or matrix element access expression.
3102 ///
3103 /// By default, performs semantic analysis to build the new expression.
3104 /// Subclasses may override this routine to provide different behavior.
3105 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3106 SourceLocation OpLoc,
3107 bool IsArrow,
3108 SourceLocation AccessorLoc,
3109 IdentifierInfo &Accessor) {
3110
3111 CXXScopeSpec SS;
3112 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3113 return getSema().BuildMemberReferenceExpr(
3114 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3115 /*FirstQualifierInScope*/ nullptr, NameInfo,
3116 /* TemplateArgs */ nullptr,
3117 /*S*/ nullptr);
3118 }
3119
3120 /// Build a new initializer list 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 RebuildInitList(SourceLocation LBraceLoc,
3125 MultiExprArg Inits,
3126 SourceLocation RBraceLoc) {
3127 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3128 }
3129
3130 /// Build a new designated initializer expression.
3131 ///
3132 /// By default, performs semantic analysis to build the new expression.
3133 /// Subclasses may override this routine to provide different behavior.
3134 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3135 MultiExprArg ArrayExprs,
3136 SourceLocation EqualOrColonLoc,
3137 bool GNUSyntax,
3138 Expr *Init) {
3139 ExprResult Result
3140 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3141 Init);
3142 if (Result.isInvalid())
3143 return ExprError();
3144
3145 return Result;
3146 }
3147
3148 /// Build a new value-initialized expression.
3149 ///
3150 /// By default, builds the implicit value initialization without performing
3151 /// any semantic analysis. Subclasses may override this routine to provide
3152 /// different behavior.
3153 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3154 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3155 }
3156
3157 /// Build a new \c va_arg expression.
3158 ///
3159 /// By default, performs semantic analysis to build the new expression.
3160 /// Subclasses may override this routine to provide different behavior.
3161 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3162 Expr *SubExpr, TypeSourceInfo *TInfo,
3163 SourceLocation RParenLoc) {
3164 return getSema().BuildVAArgExpr(BuiltinLoc,
3165 SubExpr, TInfo,
3166 RParenLoc);
3167 }
3168
3169 /// Build a new expression list in parentheses.
3170 ///
3171 /// By default, performs semantic analysis to build the new expression.
3172 /// Subclasses may override this routine to provide different behavior.
3173 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3174 MultiExprArg SubExprs,
3175 SourceLocation RParenLoc) {
3176 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3177 }
3178
3179 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3180 unsigned NumUserSpecifiedExprs,
3181 SourceLocation InitLoc,
3182 SourceLocation LParenLoc,
3183 SourceLocation RParenLoc) {
3184 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3185 InitLoc, LParenLoc, RParenLoc);
3186 }
3187
3188 /// Build a new address-of-label expression.
3189 ///
3190 /// By default, performs semantic analysis, using the name of the label
3191 /// rather than attempting to map the label statement itself.
3192 /// Subclasses may override this routine to provide different behavior.
3193 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3194 SourceLocation LabelLoc, LabelDecl *Label) {
3195 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3196 }
3197
3198 /// Build a new GNU statement expression.
3199 ///
3200 /// By default, performs semantic analysis to build the new expression.
3201 /// Subclasses may override this routine to provide different behavior.
3202 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3203 SourceLocation RParenLoc, unsigned TemplateDepth) {
3204 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3205 TemplateDepth);
3206 }
3207
3208 /// Build a new __builtin_choose_expr expression.
3209 ///
3210 /// By default, performs semantic analysis to build the new expression.
3211 /// Subclasses may override this routine to provide different behavior.
3212 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3213 Expr *Cond, Expr *LHS, Expr *RHS,
3214 SourceLocation RParenLoc) {
3215 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3216 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3217 RPLoc: RParenLoc);
3218 }
3219
3220 /// Build a new generic selection expression with an expression predicate.
3221 ///
3222 /// By default, performs semantic analysis to build the new expression.
3223 /// Subclasses may override this routine to provide different behavior.
3224 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3225 SourceLocation DefaultLoc,
3226 SourceLocation RParenLoc,
3227 Expr *ControllingExpr,
3228 ArrayRef<TypeSourceInfo *> Types,
3229 ArrayRef<Expr *> Exprs) {
3230 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3231 /*PredicateIsExpr=*/true,
3232 ControllingExpr, Types, Exprs);
3233 }
3234
3235 /// Build a new generic selection expression with a type predicate.
3236 ///
3237 /// By default, performs semantic analysis to build the new expression.
3238 /// Subclasses may override this routine to provide different behavior.
3239 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3240 SourceLocation DefaultLoc,
3241 SourceLocation RParenLoc,
3242 TypeSourceInfo *ControllingType,
3243 ArrayRef<TypeSourceInfo *> Types,
3244 ArrayRef<Expr *> Exprs) {
3245 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3246 /*PredicateIsExpr=*/false,
3247 ControllingType, Types, Exprs);
3248 }
3249
3250 /// Build a new overloaded operator call expression.
3251 ///
3252 /// By default, performs semantic analysis to build the new expression.
3253 /// The semantic analysis provides the behavior of template instantiation,
3254 /// copying with transformations that turn what looks like an overloaded
3255 /// operator call into a use of a builtin operator, performing
3256 /// argument-dependent lookup, etc. Subclasses may override this routine to
3257 /// provide different behavior.
3258 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3259 SourceLocation OpLoc,
3260 SourceLocation CalleeLoc,
3261 bool RequiresADL,
3262 const UnresolvedSetImpl &Functions,
3263 Expr *First, Expr *Second);
3264
3265 /// Build a new C++ "named" cast expression, such as static_cast or
3266 /// reinterpret_cast.
3267 ///
3268 /// By default, this routine dispatches to one of the more-specific routines
3269 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3270 /// Subclasses may override this routine to provide different behavior.
3271 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3272 Stmt::StmtClass Class,
3273 SourceLocation LAngleLoc,
3274 TypeSourceInfo *TInfo,
3275 SourceLocation RAngleLoc,
3276 SourceLocation LParenLoc,
3277 Expr *SubExpr,
3278 SourceLocation RParenLoc) {
3279 switch (Class) {
3280 case Stmt::CXXStaticCastExprClass:
3281 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3282 RAngleLoc, LParenLoc,
3283 SubExpr, RParenLoc);
3284
3285 case Stmt::CXXDynamicCastExprClass:
3286 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3287 RAngleLoc, LParenLoc,
3288 SubExpr, RParenLoc);
3289
3290 case Stmt::CXXReinterpretCastExprClass:
3291 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3292 RAngleLoc, LParenLoc,
3293 SubExpr,
3294 RParenLoc);
3295
3296 case Stmt::CXXConstCastExprClass:
3297 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3298 RAngleLoc, LParenLoc,
3299 SubExpr, RParenLoc);
3300
3301 case Stmt::CXXAddrspaceCastExprClass:
3302 return getDerived().RebuildCXXAddrspaceCastExpr(
3303 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3304
3305 default:
3306 llvm_unreachable("Invalid C++ named cast");
3307 }
3308 }
3309
3310 /// Build a new C++ static_cast expression.
3311 ///
3312 /// By default, performs semantic analysis to build the new expression.
3313 /// Subclasses may override this routine to provide different behavior.
3314 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3315 SourceLocation LAngleLoc,
3316 TypeSourceInfo *TInfo,
3317 SourceLocation RAngleLoc,
3318 SourceLocation LParenLoc,
3319 Expr *SubExpr,
3320 SourceLocation RParenLoc) {
3321 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3322 TInfo, SubExpr,
3323 SourceRange(LAngleLoc, RAngleLoc),
3324 SourceRange(LParenLoc, RParenLoc));
3325 }
3326
3327 /// Build a new C++ dynamic_cast expression.
3328 ///
3329 /// By default, performs semantic analysis to build the new expression.
3330 /// Subclasses may override this routine to provide different behavior.
3331 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3332 SourceLocation LAngleLoc,
3333 TypeSourceInfo *TInfo,
3334 SourceLocation RAngleLoc,
3335 SourceLocation LParenLoc,
3336 Expr *SubExpr,
3337 SourceLocation RParenLoc) {
3338 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3339 TInfo, SubExpr,
3340 SourceRange(LAngleLoc, RAngleLoc),
3341 SourceRange(LParenLoc, RParenLoc));
3342 }
3343
3344 /// Build a new C++ reinterpret_cast expression.
3345 ///
3346 /// By default, performs semantic analysis to build the new expression.
3347 /// Subclasses may override this routine to provide different behavior.
3348 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3349 SourceLocation LAngleLoc,
3350 TypeSourceInfo *TInfo,
3351 SourceLocation RAngleLoc,
3352 SourceLocation LParenLoc,
3353 Expr *SubExpr,
3354 SourceLocation RParenLoc) {
3355 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3356 TInfo, SubExpr,
3357 SourceRange(LAngleLoc, RAngleLoc),
3358 SourceRange(LParenLoc, RParenLoc));
3359 }
3360
3361 /// Build a new C++ const_cast expression.
3362 ///
3363 /// By default, performs semantic analysis to build the new expression.
3364 /// Subclasses may override this routine to provide different behavior.
3365 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3366 SourceLocation LAngleLoc,
3367 TypeSourceInfo *TInfo,
3368 SourceLocation RAngleLoc,
3369 SourceLocation LParenLoc,
3370 Expr *SubExpr,
3371 SourceLocation RParenLoc) {
3372 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3373 TInfo, SubExpr,
3374 SourceRange(LAngleLoc, RAngleLoc),
3375 SourceRange(LParenLoc, RParenLoc));
3376 }
3377
3378 ExprResult
3379 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3380 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3381 SourceLocation LParenLoc, Expr *SubExpr,
3382 SourceLocation RParenLoc) {
3383 return getSema().BuildCXXNamedCast(
3384 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3385 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3386 }
3387
3388 /// Build a new C++ functional-style cast expression.
3389 ///
3390 /// By default, performs semantic analysis to build the new expression.
3391 /// Subclasses may override this routine to provide different behavior.
3392 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3393 SourceLocation LParenLoc,
3394 Expr *Sub,
3395 SourceLocation RParenLoc,
3396 bool ListInitialization) {
3397 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3398 // CXXParenListInitExpr. Pass its expanded arguments so that the
3399 // CXXParenListInitExpr can be rebuilt.
3400 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3401 return getSema().BuildCXXTypeConstructExpr(
3402 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3403 RParenLoc, ListInitialization);
3404
3405 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3406 return getSema().BuildCXXTypeConstructExpr(
3407 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3408
3409 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3410 MultiExprArg(&Sub, 1), RParenLoc,
3411 ListInitialization);
3412 }
3413
3414 /// Build a new C++ __builtin_bit_cast expression.
3415 ///
3416 /// By default, performs semantic analysis to build the new expression.
3417 /// Subclasses may override this routine to provide different behavior.
3418 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3419 TypeSourceInfo *TSI, Expr *Sub,
3420 SourceLocation RParenLoc) {
3421 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3422 }
3423
3424 /// Build a new C++ typeid(type) expression.
3425 ///
3426 /// By default, performs semantic analysis to build the new expression.
3427 /// Subclasses may override this routine to provide different behavior.
3428 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3429 SourceLocation TypeidLoc,
3430 TypeSourceInfo *Operand,
3431 SourceLocation RParenLoc) {
3432 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3433 RParenLoc);
3434 }
3435
3436
3437 /// Build a new C++ typeid(expr) expression.
3438 ///
3439 /// By default, performs semantic analysis to build the new expression.
3440 /// Subclasses may override this routine to provide different behavior.
3441 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3442 SourceLocation TypeidLoc,
3443 Expr *Operand,
3444 SourceLocation RParenLoc) {
3445 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3446 RParenLoc);
3447 }
3448
3449 /// Build a new C++ __uuidof(type) expression.
3450 ///
3451 /// By default, performs semantic analysis to build the new expression.
3452 /// Subclasses may override this routine to provide different behavior.
3453 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3454 TypeSourceInfo *Operand,
3455 SourceLocation RParenLoc) {
3456 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3457 }
3458
3459 /// Build a new C++ __uuidof(expr) expression.
3460 ///
3461 /// By default, performs semantic analysis to build the new expression.
3462 /// Subclasses may override this routine to provide different behavior.
3463 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3464 Expr *Operand, SourceLocation RParenLoc) {
3465 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3466 }
3467
3468 /// Build a new C++ "this" expression.
3469 ///
3470 /// By default, performs semantic analysis to build a new "this" expression.
3471 /// Subclasses may override this routine to provide different behavior.
3472 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3473 QualType ThisType,
3474 bool isImplicit) {
3475 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3476 return ExprError();
3477 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3478 }
3479
3480 /// Build a new C++ throw 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 RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3485 bool IsThrownVariableInScope) {
3486 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3487 }
3488
3489 /// Build a new C++ default-argument expression.
3490 ///
3491 /// By default, builds a new default-argument expression, which does not
3492 /// require any semantic analysis. Subclasses may override this routine to
3493 /// provide different behavior.
3494 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3495 Expr *RewrittenExpr) {
3496 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3497 RewrittenExpr, UsedContext: getSema().CurContext);
3498 }
3499
3500 /// Build a new C++11 default-initialization expression.
3501 ///
3502 /// By default, builds a new default field initialization expression, which
3503 /// does not require any semantic analysis. Subclasses may override this
3504 /// routine to provide different behavior.
3505 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3506 FieldDecl *Field) {
3507 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3508 }
3509
3510 /// Build a new C++ zero-initialization expression.
3511 ///
3512 /// By default, performs semantic analysis to build the new expression.
3513 /// Subclasses may override this routine to provide different behavior.
3514 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3515 SourceLocation LParenLoc,
3516 SourceLocation RParenLoc) {
3517 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3518 /*ListInitialization=*/false);
3519 }
3520
3521 /// Build a new C++ "new" expression.
3522 ///
3523 /// By default, performs semantic analysis to build the new expression.
3524 /// Subclasses may override this routine to provide different behavior.
3525 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3526 SourceLocation PlacementLParen,
3527 MultiExprArg PlacementArgs,
3528 SourceLocation PlacementRParen,
3529 SourceRange TypeIdParens, QualType AllocatedType,
3530 TypeSourceInfo *AllocatedTypeInfo,
3531 std::optional<Expr *> ArraySize,
3532 SourceRange DirectInitRange, Expr *Initializer) {
3533 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3534 PlacementLParen,
3535 PlacementArgs,
3536 PlacementRParen,
3537 TypeIdParens,
3538 AllocatedType,
3539 AllocatedTypeInfo,
3540 ArraySize,
3541 DirectInitRange,
3542 Initializer);
3543 }
3544
3545 /// Build a new C++ "delete" expression.
3546 ///
3547 /// By default, performs semantic analysis to build the new expression.
3548 /// Subclasses may override this routine to provide different behavior.
3549 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3550 bool IsGlobalDelete,
3551 bool IsArrayForm,
3552 Expr *Operand) {
3553 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3554 Operand);
3555 }
3556
3557 /// Build a new type trait expression.
3558 ///
3559 /// By default, performs semantic analysis to build the new expression.
3560 /// Subclasses may override this routine to provide different behavior.
3561 ExprResult RebuildTypeTrait(TypeTrait Trait,
3562 SourceLocation StartLoc,
3563 ArrayRef<TypeSourceInfo *> Args,
3564 SourceLocation RParenLoc) {
3565 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3566 }
3567
3568 /// Build a new array type trait expression.
3569 ///
3570 /// By default, performs semantic analysis to build the new expression.
3571 /// Subclasses may override this routine to provide different behavior.
3572 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3573 SourceLocation StartLoc,
3574 TypeSourceInfo *TSInfo,
3575 Expr *DimExpr,
3576 SourceLocation RParenLoc) {
3577 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3578 }
3579
3580 /// Build a new expression trait expression.
3581 ///
3582 /// By default, performs semantic analysis to build the new expression.
3583 /// Subclasses may override this routine to provide different behavior.
3584 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3585 SourceLocation StartLoc,
3586 Expr *Queried,
3587 SourceLocation RParenLoc) {
3588 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3589 }
3590
3591 /// Build a new (previously unresolved) declaration reference
3592 /// expression.
3593 ///
3594 /// By default, performs semantic analysis to build the new expression.
3595 /// Subclasses may override this routine to provide different behavior.
3596 ExprResult RebuildDependentScopeDeclRefExpr(
3597 NestedNameSpecifierLoc QualifierLoc,
3598 SourceLocation TemplateKWLoc,
3599 const DeclarationNameInfo &NameInfo,
3600 const TemplateArgumentListInfo *TemplateArgs,
3601 bool IsAddressOfOperand,
3602 TypeSourceInfo **RecoveryTSI) {
3603 CXXScopeSpec SS;
3604 SS.Adopt(Other: QualifierLoc);
3605
3606 if (TemplateArgs || TemplateKWLoc.isValid())
3607 return getSema().BuildQualifiedTemplateIdExpr(
3608 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3609
3610 return getSema().BuildQualifiedDeclarationNameExpr(
3611 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3612 }
3613
3614 /// Build a new template-id expression.
3615 ///
3616 /// By default, performs semantic analysis to build the new expression.
3617 /// Subclasses may override this routine to provide different behavior.
3618 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3619 SourceLocation TemplateKWLoc,
3620 LookupResult &R,
3621 bool RequiresADL,
3622 const TemplateArgumentListInfo *TemplateArgs) {
3623 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3624 TemplateArgs);
3625 }
3626
3627 /// Build a new object-construction expression.
3628 ///
3629 /// By default, performs semantic analysis to build the new expression.
3630 /// Subclasses may override this routine to provide different behavior.
3631 ExprResult RebuildCXXConstructExpr(
3632 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3633 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3634 bool ListInitialization, bool StdInitListInitialization,
3635 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3636 SourceRange ParenRange) {
3637 // Reconstruct the constructor we originally found, which might be
3638 // different if this is a call to an inherited constructor.
3639 CXXConstructorDecl *FoundCtor = Constructor;
3640 if (Constructor->isInheritingConstructor())
3641 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3642
3643 SmallVector<Expr *, 8> ConvertedArgs;
3644 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3645 ConvertedArgs))
3646 return ExprError();
3647
3648 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3649 IsElidable,
3650 ConvertedArgs,
3651 HadMultipleCandidates,
3652 ListInitialization,
3653 StdInitListInitialization,
3654 RequiresZeroInit, ConstructKind,
3655 ParenRange);
3656 }
3657
3658 /// Build a new implicit construction via inherited constructor
3659 /// expression.
3660 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3661 CXXConstructorDecl *Constructor,
3662 bool ConstructsVBase,
3663 bool InheritedFromVBase) {
3664 return new (getSema().Context) CXXInheritedCtorInitExpr(
3665 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3666 }
3667
3668 /// Build a new object-construction expression.
3669 ///
3670 /// By default, performs semantic analysis to build the new expression.
3671 /// Subclasses may override this routine to provide different behavior.
3672 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3673 SourceLocation LParenOrBraceLoc,
3674 MultiExprArg Args,
3675 SourceLocation RParenOrBraceLoc,
3676 bool ListInitialization) {
3677 return getSema().BuildCXXTypeConstructExpr(
3678 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3679 }
3680
3681 /// Build a new object-construction expression.
3682 ///
3683 /// By default, performs semantic analysis to build the new expression.
3684 /// Subclasses may override this routine to provide different behavior.
3685 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3686 SourceLocation LParenLoc,
3687 MultiExprArg Args,
3688 SourceLocation RParenLoc,
3689 bool ListInitialization) {
3690 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3691 RParenLoc, ListInitialization);
3692 }
3693
3694 /// Build a new member reference expression.
3695 ///
3696 /// By default, performs semantic analysis to build the new expression.
3697 /// Subclasses may override this routine to provide different behavior.
3698 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3699 QualType BaseType,
3700 bool IsArrow,
3701 SourceLocation OperatorLoc,
3702 NestedNameSpecifierLoc QualifierLoc,
3703 SourceLocation TemplateKWLoc,
3704 NamedDecl *FirstQualifierInScope,
3705 const DeclarationNameInfo &MemberNameInfo,
3706 const TemplateArgumentListInfo *TemplateArgs) {
3707 CXXScopeSpec SS;
3708 SS.Adopt(Other: QualifierLoc);
3709
3710 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3711 OpLoc: OperatorLoc, IsArrow,
3712 SS, TemplateKWLoc,
3713 FirstQualifierInScope,
3714 NameInfo: MemberNameInfo,
3715 TemplateArgs, /*S*/S: nullptr);
3716 }
3717
3718 /// Build a new member reference expression.
3719 ///
3720 /// By default, performs semantic analysis to build the new expression.
3721 /// Subclasses may override this routine to provide different behavior.
3722 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3723 SourceLocation OperatorLoc,
3724 bool IsArrow,
3725 NestedNameSpecifierLoc QualifierLoc,
3726 SourceLocation TemplateKWLoc,
3727 NamedDecl *FirstQualifierInScope,
3728 LookupResult &R,
3729 const TemplateArgumentListInfo *TemplateArgs) {
3730 CXXScopeSpec SS;
3731 SS.Adopt(Other: QualifierLoc);
3732
3733 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3734 OpLoc: OperatorLoc, IsArrow,
3735 SS, TemplateKWLoc,
3736 FirstQualifierInScope,
3737 R, TemplateArgs, /*S*/S: nullptr);
3738 }
3739
3740 /// Build a new noexcept expression.
3741 ///
3742 /// By default, performs semantic analysis to build the new expression.
3743 /// Subclasses may override this routine to provide different behavior.
3744 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3745 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3746 }
3747
3748 UnsignedOrNone
3749 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3750
3751 /// Build a new expression to compute the length of a parameter pack.
3752 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3753 SourceLocation PackLoc,
3754 SourceLocation RParenLoc,
3755 UnsignedOrNone Length,
3756 ArrayRef<TemplateArgument> PartialArgs) {
3757 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3758 RParenLoc, Length, PartialArgs);
3759 }
3760
3761 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3762 SourceLocation RSquareLoc,
3763 Expr *PackIdExpression, Expr *IndexExpr,
3764 ArrayRef<Expr *> ExpandedExprs,
3765 bool FullySubstituted = false) {
3766 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3767 IndexExpr, RSquareLoc, ExpandedExprs,
3768 FullySubstituted);
3769 }
3770
3771 /// Build a new expression representing a call to a source location
3772 /// builtin.
3773 ///
3774 /// By default, performs semantic analysis to build the new expression.
3775 /// Subclasses may override this routine to provide different behavior.
3776 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3777 SourceLocation BuiltinLoc,
3778 SourceLocation RPLoc,
3779 DeclContext *ParentContext) {
3780 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3781 ParentContext);
3782 }
3783
3784 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3785 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3786 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3787 TemplateArgumentListInfo *TALI) {
3788 CXXScopeSpec SS;
3789 SS.Adopt(Other: NNS);
3790 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3791 ConceptNameInfo,
3792 FoundDecl,
3793 NamedConcept, TALI);
3794 if (Result.isInvalid())
3795 return ExprError();
3796 return Result;
3797 }
3798
3799 /// \brief Build a new requires expression.
3800 ///
3801 /// By default, performs semantic analysis to build the new expression.
3802 /// Subclasses may override this routine to provide different behavior.
3803 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3804 RequiresExprBodyDecl *Body,
3805 SourceLocation LParenLoc,
3806 ArrayRef<ParmVarDecl *> LocalParameters,
3807 SourceLocation RParenLoc,
3808 ArrayRef<concepts::Requirement *> Requirements,
3809 SourceLocation ClosingBraceLoc) {
3810 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3811 LocalParameters, RParenLoc, Requirements,
3812 RBraceLoc: ClosingBraceLoc);
3813 }
3814
3815 concepts::TypeRequirement *
3816 RebuildTypeRequirement(
3817 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3818 return SemaRef.BuildTypeRequirement(SubstDiag);
3819 }
3820
3821 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3822 return SemaRef.BuildTypeRequirement(Type: T);
3823 }
3824
3825 concepts::ExprRequirement *
3826 RebuildExprRequirement(
3827 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3828 SourceLocation NoexceptLoc,
3829 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3830 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3831 ReturnTypeRequirement: std::move(Ret));
3832 }
3833
3834 concepts::ExprRequirement *
3835 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3836 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3837 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3838 ReturnTypeRequirement: std::move(Ret));
3839 }
3840
3841 concepts::NestedRequirement *
3842 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3843 const ASTConstraintSatisfaction &Satisfaction) {
3844 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3845 Satisfaction);
3846 }
3847
3848 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3849 return SemaRef.BuildNestedRequirement(E: Constraint);
3850 }
3851
3852 /// \brief Build a new Objective-C boxed expression.
3853 ///
3854 /// By default, performs semantic analysis to build the new expression.
3855 /// Subclasses may override this routine to provide different behavior.
3856 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3857 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3858 }
3859
3860 /// Build a new Objective-C array literal.
3861 ///
3862 /// By default, performs semantic analysis to build the new expression.
3863 /// Subclasses may override this routine to provide different behavior.
3864 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3865 Expr **Elements, unsigned NumElements) {
3866 return getSema().ObjC().BuildObjCArrayLiteral(
3867 Range, MultiExprArg(Elements, NumElements));
3868 }
3869
3870 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3871 Expr *Base, Expr *Key,
3872 ObjCMethodDecl *getterMethod,
3873 ObjCMethodDecl *setterMethod) {
3874 return getSema().ObjC().BuildObjCSubscriptExpression(
3875 RB, Base, Key, getterMethod, setterMethod);
3876 }
3877
3878 /// Build a new Objective-C dictionary literal.
3879 ///
3880 /// By default, performs semantic analysis to build the new expression.
3881 /// Subclasses may override this routine to provide different behavior.
3882 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3883 MutableArrayRef<ObjCDictionaryElement> Elements) {
3884 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3885 }
3886
3887 /// Build a new Objective-C \@encode expression.
3888 ///
3889 /// By default, performs semantic analysis to build the new expression.
3890 /// Subclasses may override this routine to provide different behavior.
3891 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3892 TypeSourceInfo *EncodeTypeInfo,
3893 SourceLocation RParenLoc) {
3894 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3895 RParenLoc);
3896 }
3897
3898 /// Build a new Objective-C class message.
3899 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3900 Selector Sel,
3901 ArrayRef<SourceLocation> SelectorLocs,
3902 ObjCMethodDecl *Method,
3903 SourceLocation LBracLoc,
3904 MultiExprArg Args,
3905 SourceLocation RBracLoc) {
3906 return SemaRef.ObjC().BuildClassMessage(
3907 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3908 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3909 RBracLoc, Args);
3910 }
3911
3912 /// Build a new Objective-C instance message.
3913 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3914 Selector Sel,
3915 ArrayRef<SourceLocation> SelectorLocs,
3916 ObjCMethodDecl *Method,
3917 SourceLocation LBracLoc,
3918 MultiExprArg Args,
3919 SourceLocation RBracLoc) {
3920 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3921 /*SuperLoc=*/SuperLoc: SourceLocation(),
3922 Sel, Method, LBracLoc,
3923 SelectorLocs, RBracLoc, Args);
3924 }
3925
3926 /// Build a new Objective-C instance/class message to 'super'.
3927 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3928 Selector Sel,
3929 ArrayRef<SourceLocation> SelectorLocs,
3930 QualType SuperType,
3931 ObjCMethodDecl *Method,
3932 SourceLocation LBracLoc,
3933 MultiExprArg Args,
3934 SourceLocation RBracLoc) {
3935 return Method->isInstanceMethod()
3936 ? SemaRef.ObjC().BuildInstanceMessage(
3937 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3938 SelectorLocs, RBracLoc, Args)
3939 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3940 Sel, Method, LBracLoc,
3941 SelectorLocs, RBracLoc, Args);
3942 }
3943
3944 /// Build a new Objective-C ivar reference expression.
3945 ///
3946 /// By default, performs semantic analysis to build the new expression.
3947 /// Subclasses may override this routine to provide different behavior.
3948 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3949 SourceLocation IvarLoc,
3950 bool IsArrow, bool IsFreeIvar) {
3951 CXXScopeSpec SS;
3952 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3953 ExprResult Result = getSema().BuildMemberReferenceExpr(
3954 BaseArg, BaseArg->getType(),
3955 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3956 /*FirstQualifierInScope=*/nullptr, NameInfo,
3957 /*TemplateArgs=*/nullptr,
3958 /*S=*/nullptr);
3959 if (IsFreeIvar && Result.isUsable())
3960 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3961 return Result;
3962 }
3963
3964 /// Build a new Objective-C property reference expression.
3965 ///
3966 /// By default, performs semantic analysis to build the new expression.
3967 /// Subclasses may override this routine to provide different behavior.
3968 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3969 ObjCPropertyDecl *Property,
3970 SourceLocation PropertyLoc) {
3971 CXXScopeSpec SS;
3972 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3973 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3974 /*FIXME:*/PropertyLoc,
3975 /*IsArrow=*/false,
3976 SS, SourceLocation(),
3977 /*FirstQualifierInScope=*/nullptr,
3978 NameInfo,
3979 /*TemplateArgs=*/nullptr,
3980 /*S=*/nullptr);
3981 }
3982
3983 /// Build a new Objective-C property reference expression.
3984 ///
3985 /// By default, performs semantic analysis to build the new expression.
3986 /// Subclasses may override this routine to provide different behavior.
3987 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3988 ObjCMethodDecl *Getter,
3989 ObjCMethodDecl *Setter,
3990 SourceLocation PropertyLoc) {
3991 // Since these expressions can only be value-dependent, we do not
3992 // need to perform semantic analysis again.
3993 return Owned(
3994 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3995 VK_LValue, OK_ObjCProperty,
3996 PropertyLoc, Base));
3997 }
3998
3999 /// Build a new Objective-C "isa" expression.
4000 ///
4001 /// By default, performs semantic analysis to build the new expression.
4002 /// Subclasses may override this routine to provide different behavior.
4003 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4004 SourceLocation OpLoc, bool IsArrow) {
4005 CXXScopeSpec SS;
4006 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4007 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4008 OpLoc, IsArrow,
4009 SS, SourceLocation(),
4010 /*FirstQualifierInScope=*/nullptr,
4011 NameInfo,
4012 /*TemplateArgs=*/nullptr,
4013 /*S=*/nullptr);
4014 }
4015
4016 /// Build a new shuffle vector expression.
4017 ///
4018 /// By default, performs semantic analysis to build the new expression.
4019 /// Subclasses may override this routine to provide different behavior.
4020 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4021 MultiExprArg SubExprs,
4022 SourceLocation RParenLoc) {
4023 // Find the declaration for __builtin_shufflevector
4024 const IdentifierInfo &Name
4025 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4026 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4027 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4028 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4029
4030 // Build a reference to the __builtin_shufflevector builtin
4031 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4032 Expr *Callee = new (SemaRef.Context)
4033 DeclRefExpr(SemaRef.Context, Builtin, false,
4034 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4035 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4036 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4037 CK: CK_BuiltinFnToFnPtr).get();
4038
4039 // Build the CallExpr
4040 ExprResult TheCall = CallExpr::Create(
4041 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4042 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4043 FPFeatures: FPOptionsOverride());
4044
4045 // Type-check the __builtin_shufflevector expression.
4046 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4047 }
4048
4049 /// Build a new convert vector expression.
4050 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4051 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4052 SourceLocation RParenLoc) {
4053 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4054 }
4055
4056 /// Build a new template argument pack expansion.
4057 ///
4058 /// By default, performs semantic analysis to build a new pack expansion
4059 /// for a template argument. Subclasses may override this routine to provide
4060 /// different behavior.
4061 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4062 SourceLocation EllipsisLoc,
4063 UnsignedOrNone NumExpansions) {
4064 switch (Pattern.getArgument().getKind()) {
4065 case TemplateArgument::Expression: {
4066 ExprResult Result
4067 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4068 EllipsisLoc, NumExpansions);
4069 if (Result.isInvalid())
4070 return TemplateArgumentLoc();
4071
4072 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4073 /*IsCanonical=*/false),
4074 Result.get());
4075 }
4076
4077 case TemplateArgument::Template:
4078 return TemplateArgumentLoc(
4079 SemaRef.Context,
4080 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4081 NumExpansions),
4082 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4083 Pattern.getTemplateNameLoc(), EllipsisLoc);
4084
4085 case TemplateArgument::Null:
4086 case TemplateArgument::Integral:
4087 case TemplateArgument::Declaration:
4088 case TemplateArgument::StructuralValue:
4089 case TemplateArgument::Pack:
4090 case TemplateArgument::TemplateExpansion:
4091 case TemplateArgument::NullPtr:
4092 llvm_unreachable("Pack expansion pattern has no parameter packs");
4093
4094 case TemplateArgument::Type:
4095 if (TypeSourceInfo *Expansion
4096 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4097 EllipsisLoc,
4098 NumExpansions))
4099 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4100 Expansion);
4101 break;
4102 }
4103
4104 return TemplateArgumentLoc();
4105 }
4106
4107 /// Build a new expression pack expansion.
4108 ///
4109 /// By default, performs semantic analysis to build a new pack expansion
4110 /// for an expression. Subclasses may override this routine to provide
4111 /// different behavior.
4112 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4113 UnsignedOrNone NumExpansions) {
4114 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4115 }
4116
4117 /// Build a new C++1z fold-expression.
4118 ///
4119 /// By default, performs semantic analysis in order to build a new fold
4120 /// expression.
4121 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4122 SourceLocation LParenLoc, Expr *LHS,
4123 BinaryOperatorKind Operator,
4124 SourceLocation EllipsisLoc, Expr *RHS,
4125 SourceLocation RParenLoc,
4126 UnsignedOrNone NumExpansions) {
4127 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4128 EllipsisLoc, RHS, RParenLoc,
4129 NumExpansions);
4130 }
4131
4132 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4133 LambdaScopeInfo *LSI) {
4134 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4135 if (Expr *Init = PVD->getInit())
4136 LSI->ContainsUnexpandedParameterPack |=
4137 Init->containsUnexpandedParameterPack();
4138 else if (PVD->hasUninstantiatedDefaultArg())
4139 LSI->ContainsUnexpandedParameterPack |=
4140 PVD->getUninstantiatedDefaultArg()
4141 ->containsUnexpandedParameterPack();
4142 }
4143 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4144 }
4145
4146 /// Build an empty C++1z fold-expression with the given operator.
4147 ///
4148 /// By default, produces the fallback value for the fold-expression, or
4149 /// produce an error if there is no fallback value.
4150 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4151 BinaryOperatorKind Operator) {
4152 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4153 }
4154
4155 /// Build a new atomic operation expression.
4156 ///
4157 /// By default, performs semantic analysis to build the new expression.
4158 /// Subclasses may override this routine to provide different behavior.
4159 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4160 AtomicExpr::AtomicOp Op,
4161 SourceLocation RParenLoc) {
4162 // Use this for all of the locations, since we don't know the difference
4163 // between the call and the expr at this point.
4164 SourceRange Range{BuiltinLoc, RParenLoc};
4165 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4166 Sema::AtomicArgumentOrder::AST);
4167 }
4168
4169 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4170 ArrayRef<Expr *> SubExprs, QualType Type) {
4171 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4172 }
4173
4174 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4175 SourceLocation BeginLoc,
4176 SourceLocation DirLoc,
4177 SourceLocation EndLoc,
4178 ArrayRef<OpenACCClause *> Clauses,
4179 StmtResult StrBlock) {
4180 return getSema().OpenACC().ActOnEndStmtDirective(
4181 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4182 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4183 }
4184
4185 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4186 SourceLocation DirLoc,
4187 SourceLocation EndLoc,
4188 ArrayRef<OpenACCClause *> Clauses,
4189 StmtResult Loop) {
4190 return getSema().OpenACC().ActOnEndStmtDirective(
4191 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4192 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4193 Clauses, Loop);
4194 }
4195
4196 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4197 SourceLocation BeginLoc,
4198 SourceLocation DirLoc,
4199 SourceLocation EndLoc,
4200 ArrayRef<OpenACCClause *> Clauses,
4201 StmtResult Loop) {
4202 return getSema().OpenACC().ActOnEndStmtDirective(
4203 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4204 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4205 }
4206
4207 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4208 SourceLocation DirLoc,
4209 SourceLocation EndLoc,
4210 ArrayRef<OpenACCClause *> Clauses,
4211 StmtResult StrBlock) {
4212 return getSema().OpenACC().ActOnEndStmtDirective(
4213 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4214 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4215 Clauses, StrBlock);
4216 }
4217
4218 StmtResult
4219 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4220 SourceLocation DirLoc, SourceLocation EndLoc,
4221 ArrayRef<OpenACCClause *> Clauses) {
4222 return getSema().OpenACC().ActOnEndStmtDirective(
4223 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4224 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4225 Clauses, {});
4226 }
4227
4228 StmtResult
4229 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4230 SourceLocation DirLoc, SourceLocation EndLoc,
4231 ArrayRef<OpenACCClause *> Clauses) {
4232 return getSema().OpenACC().ActOnEndStmtDirective(
4233 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4234 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4235 Clauses, {});
4236 }
4237
4238 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4239 SourceLocation DirLoc,
4240 SourceLocation EndLoc,
4241 ArrayRef<OpenACCClause *> Clauses,
4242 StmtResult StrBlock) {
4243 return getSema().OpenACC().ActOnEndStmtDirective(
4244 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4245 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4246 Clauses, StrBlock);
4247 }
4248
4249 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4250 SourceLocation DirLoc,
4251 SourceLocation EndLoc,
4252 ArrayRef<OpenACCClause *> Clauses) {
4253 return getSema().OpenACC().ActOnEndStmtDirective(
4254 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4255 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4256 Clauses, {});
4257 }
4258
4259 StmtResult
4260 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4261 SourceLocation DirLoc, SourceLocation EndLoc,
4262 ArrayRef<OpenACCClause *> Clauses) {
4263 return getSema().OpenACC().ActOnEndStmtDirective(
4264 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4265 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4266 Clauses, {});
4267 }
4268
4269 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4270 SourceLocation DirLoc,
4271 SourceLocation EndLoc,
4272 ArrayRef<OpenACCClause *> Clauses) {
4273 return getSema().OpenACC().ActOnEndStmtDirective(
4274 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4275 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4276 Clauses, {});
4277 }
4278
4279 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4280 SourceLocation DirLoc,
4281 SourceLocation EndLoc,
4282 ArrayRef<OpenACCClause *> Clauses) {
4283 return getSema().OpenACC().ActOnEndStmtDirective(
4284 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4285 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4286 Clauses, {});
4287 }
4288
4289 StmtResult RebuildOpenACCWaitConstruct(
4290 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4291 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4292 SourceLocation RParenLoc, SourceLocation EndLoc,
4293 ArrayRef<OpenACCClause *> Clauses) {
4294 llvm::SmallVector<Expr *> Exprs;
4295 Exprs.push_back(Elt: DevNumExpr);
4296 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4297 return getSema().OpenACC().ActOnEndStmtDirective(
4298 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4299 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4300 }
4301
4302 StmtResult RebuildOpenACCCacheConstruct(
4303 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4304 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4305 SourceLocation RParenLoc, SourceLocation EndLoc) {
4306 return getSema().OpenACC().ActOnEndStmtDirective(
4307 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4308 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4309 }
4310
4311 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4312 SourceLocation DirLoc,
4313 OpenACCAtomicKind AtKind,
4314 SourceLocation EndLoc,
4315 ArrayRef<OpenACCClause *> Clauses,
4316 StmtResult AssociatedStmt) {
4317 return getSema().OpenACC().ActOnEndStmtDirective(
4318 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4319 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4320 AssociatedStmt);
4321 }
4322
4323 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4324 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4325 }
4326
4327 ExprResult
4328 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl,
4329 const NonTypeTemplateParmDecl *NTTP,
4330 SourceLocation Loc, TemplateArgument Arg,
4331 UnsignedOrNone PackIndex, bool Final) {
4332 return getSema().BuildSubstNonTypeTemplateParmExpr(
4333 AssociatedDecl, NTTP, Loc, Arg, PackIndex, Final);
4334 }
4335
4336 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4337 SourceLocation StartLoc,
4338 SourceLocation LParenLoc,
4339 SourceLocation EndLoc) {
4340 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4341 LParenLoc, EndLoc);
4342 }
4343
4344private:
4345 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4346 QualType ObjectType,
4347 NamedDecl *FirstQualifierInScope);
4348
4349 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4350 QualType ObjectType,
4351 NamedDecl *FirstQualifierInScope) {
4352 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4353 return TSInfo;
4354
4355 TypeLocBuilder TLB;
4356 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4357 ObjectType, FirstQualifierInScope);
4358 if (T.isNull())
4359 return nullptr;
4360 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4361 }
4362
4363 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4364 DependentNameTypeLoc TL,
4365 bool DeducibleTSTContext,
4366 QualType ObjectType = QualType(),
4367 NamedDecl *UnqualLookup = nullptr);
4368
4369 llvm::SmallVector<OpenACCClause *>
4370 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4371 ArrayRef<const OpenACCClause *> OldClauses);
4372
4373 OpenACCClause *
4374 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4375 OpenACCDirectiveKind DirKind,
4376 const OpenACCClause *OldClause);
4377};
4378
4379template <typename Derived>
4380StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4381 if (!S)
4382 return S;
4383
4384 switch (S->getStmtClass()) {
4385 case Stmt::NoStmtClass: break;
4386
4387 // Transform individual statement nodes
4388 // Pass SDK into statements that can produce a value
4389#define STMT(Node, Parent) \
4390 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4391#define VALUESTMT(Node, Parent) \
4392 case Stmt::Node##Class: \
4393 return getDerived().Transform##Node(cast<Node>(S), SDK);
4394#define ABSTRACT_STMT(Node)
4395#define EXPR(Node, Parent)
4396#include "clang/AST/StmtNodes.inc"
4397
4398 // Transform expressions by calling TransformExpr.
4399#define STMT(Node, Parent)
4400#define ABSTRACT_STMT(Stmt)
4401#define EXPR(Node, Parent) case Stmt::Node##Class:
4402#include "clang/AST/StmtNodes.inc"
4403 {
4404 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4405
4406 if (SDK == StmtDiscardKind::StmtExprResult)
4407 E = getSema().ActOnStmtExprResult(E);
4408 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4409 }
4410 }
4411
4412 return S;
4413}
4414
4415template<typename Derived>
4416OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4417 if (!S)
4418 return S;
4419
4420 switch (S->getClauseKind()) {
4421 default: break;
4422 // Transform individual clause nodes
4423#define GEN_CLANG_CLAUSE_CLASS
4424#define CLAUSE_CLASS(Enum, Str, Class) \
4425 case Enum: \
4426 return getDerived().Transform##Class(cast<Class>(S));
4427#include "llvm/Frontend/OpenMP/OMP.inc"
4428 }
4429
4430 return S;
4431}
4432
4433
4434template<typename Derived>
4435ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4436 if (!E)
4437 return E;
4438
4439 switch (E->getStmtClass()) {
4440 case Stmt::NoStmtClass: break;
4441#define STMT(Node, Parent) case Stmt::Node##Class: break;
4442#define ABSTRACT_STMT(Stmt)
4443#define EXPR(Node, Parent) \
4444 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4445#include "clang/AST/StmtNodes.inc"
4446 }
4447
4448 return E;
4449}
4450
4451template<typename Derived>
4452ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4453 bool NotCopyInit) {
4454 // Initializers are instantiated like expressions, except that various outer
4455 // layers are stripped.
4456 if (!Init)
4457 return Init;
4458
4459 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4460 Init = FE->getSubExpr();
4461
4462 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4463 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4464 Init = OVE->getSourceExpr();
4465 }
4466
4467 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4468 Init = MTE->getSubExpr();
4469
4470 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4471 Init = Binder->getSubExpr();
4472
4473 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4474 Init = ICE->getSubExprAsWritten();
4475
4476 if (CXXStdInitializerListExpr *ILE =
4477 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4478 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4479
4480 // If this is copy-initialization, we only need to reconstruct
4481 // InitListExprs. Other forms of copy-initialization will be a no-op if
4482 // the initializer is already the right type.
4483 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4484 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4485 return getDerived().TransformExpr(Init);
4486
4487 // Revert value-initialization back to empty parens.
4488 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4489 SourceRange Parens = VIE->getSourceRange();
4490 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4491 Parens.getEnd());
4492 }
4493
4494 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4495 if (isa<ImplicitValueInitExpr>(Val: Init))
4496 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4497 SourceLocation());
4498
4499 // Revert initialization by constructor back to a parenthesized or braced list
4500 // of expressions. Any other form of initializer can just be reused directly.
4501 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4502 return getDerived().TransformExpr(Init);
4503
4504 // If the initialization implicitly converted an initializer list to a
4505 // std::initializer_list object, unwrap the std::initializer_list too.
4506 if (Construct && Construct->isStdInitListInitialization())
4507 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4508
4509 // Enter a list-init context if this was list initialization.
4510 EnterExpressionEvaluationContext Context(
4511 getSema(), EnterExpressionEvaluationContext::InitList,
4512 Construct->isListInitialization());
4513
4514 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4515 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4516 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4517 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4518 SmallVector<Expr*, 8> NewArgs;
4519 bool ArgChanged = false;
4520 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4521 /*IsCall*/true, NewArgs, &ArgChanged))
4522 return ExprError();
4523
4524 // If this was list initialization, revert to syntactic list form.
4525 if (Construct->isListInitialization())
4526 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4527 Construct->getEndLoc());
4528
4529 // Build a ParenListExpr to represent anything else.
4530 SourceRange Parens = Construct->getParenOrBraceRange();
4531 if (Parens.isInvalid()) {
4532 // This was a variable declaration's initialization for which no initializer
4533 // was specified.
4534 assert(NewArgs.empty() &&
4535 "no parens or braces but have direct init with arguments?");
4536 return ExprEmpty();
4537 }
4538 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4539 Parens.getEnd());
4540}
4541
4542template<typename Derived>
4543bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4544 unsigned NumInputs,
4545 bool IsCall,
4546 SmallVectorImpl<Expr *> &Outputs,
4547 bool *ArgChanged) {
4548 for (unsigned I = 0; I != NumInputs; ++I) {
4549 // If requested, drop call arguments that need to be dropped.
4550 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4551 if (ArgChanged)
4552 *ArgChanged = true;
4553
4554 break;
4555 }
4556
4557 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4558 Expr *Pattern = Expansion->getPattern();
4559
4560 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4561 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4562 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4563
4564 // Determine whether the set of unexpanded parameter packs can and should
4565 // be expanded.
4566 bool Expand = true;
4567 bool RetainExpansion = false;
4568 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4569 UnsignedOrNone NumExpansions = OrigNumExpansions;
4570 if (getDerived().TryExpandParameterPacks(
4571 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4572 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4573 RetainExpansion, NumExpansions))
4574 return true;
4575
4576 if (!Expand) {
4577 // The transform has determined that we should perform a simple
4578 // transformation on the pack expansion, producing another pack
4579 // expansion.
4580 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4581 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4582 if (OutPattern.isInvalid())
4583 return true;
4584
4585 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4586 Expansion->getEllipsisLoc(),
4587 NumExpansions);
4588 if (Out.isInvalid())
4589 return true;
4590
4591 if (ArgChanged)
4592 *ArgChanged = true;
4593 Outputs.push_back(Elt: Out.get());
4594 continue;
4595 }
4596
4597 // Record right away that the argument was changed. This needs
4598 // to happen even if the array expands to nothing.
4599 if (ArgChanged) *ArgChanged = true;
4600
4601 // The transform has determined that we should perform an elementwise
4602 // expansion of the pattern. Do so.
4603 for (unsigned I = 0; I != *NumExpansions; ++I) {
4604 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4605 ExprResult Out = getDerived().TransformExpr(Pattern);
4606 if (Out.isInvalid())
4607 return true;
4608
4609 if (Out.get()->containsUnexpandedParameterPack()) {
4610 Out = getDerived().RebuildPackExpansion(
4611 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4612 if (Out.isInvalid())
4613 return true;
4614 }
4615
4616 Outputs.push_back(Elt: Out.get());
4617 }
4618
4619 // If we're supposed to retain a pack expansion, do so by temporarily
4620 // forgetting the partially-substituted parameter pack.
4621 if (RetainExpansion) {
4622 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4623
4624 ExprResult Out = getDerived().TransformExpr(Pattern);
4625 if (Out.isInvalid())
4626 return true;
4627
4628 Out = getDerived().RebuildPackExpansion(
4629 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4630 if (Out.isInvalid())
4631 return true;
4632
4633 Outputs.push_back(Elt: Out.get());
4634 }
4635
4636 continue;
4637 }
4638
4639 ExprResult Result =
4640 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4641 : getDerived().TransformExpr(Inputs[I]);
4642 if (Result.isInvalid())
4643 return true;
4644
4645 if (Result.get() != Inputs[I] && ArgChanged)
4646 *ArgChanged = true;
4647
4648 Outputs.push_back(Elt: Result.get());
4649 }
4650
4651 return false;
4652}
4653
4654template <typename Derived>
4655Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4656 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4657
4658 EnterExpressionEvaluationContext Eval(
4659 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4660 /*LambdaContextDecl=*/nullptr,
4661 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4662 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4663
4664 if (Var) {
4665 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4666 getDerived().TransformDefinition(Var->getLocation(), Var));
4667
4668 if (!ConditionVar)
4669 return Sema::ConditionError();
4670
4671 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4672 }
4673
4674 if (Expr) {
4675 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4676
4677 if (CondExpr.isInvalid())
4678 return Sema::ConditionError();
4679
4680 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4681 /*MissingOK=*/true);
4682 }
4683
4684 return Sema::ConditionResult();
4685}
4686
4687template <typename Derived>
4688NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4689 NestedNameSpecifierLoc NNS, QualType ObjectType,
4690 NamedDecl *FirstQualifierInScope) {
4691 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4692
4693 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4694 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4695 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4696 Qualifiers.push_back(Elt: Qualifier);
4697 };
4698 insertNNS(NNS);
4699
4700 CXXScopeSpec SS;
4701 while (!Qualifiers.empty()) {
4702 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4703 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4704
4705 switch (QNNS.getKind()) {
4706 case NestedNameSpecifier::Kind::Null:
4707 llvm_unreachable("unexpected null nested name specifier");
4708
4709 case NestedNameSpecifier::Kind::Namespace: {
4710 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4711 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4712 QNNS.getAsNamespaceAndPrefix().Namespace)));
4713 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4714 break;
4715 }
4716
4717 case NestedNameSpecifier::Kind::Global:
4718 // There is no meaningful transformation that one could perform on the
4719 // global scope.
4720 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4721 break;
4722
4723 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4724 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4725 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4726 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4727 ColonColonLoc: Q.getEndLoc());
4728 break;
4729 }
4730
4731 case NestedNameSpecifier::Kind::Type: {
4732 assert(SS.isEmpty());
4733 TypeLoc TL = Q.castAsTypeLoc();
4734
4735 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4736 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4737 if (QualifierLoc) {
4738 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4739 QualifierLoc, ObjectType, FirstQualifierInScope);
4740 if (!QualifierLoc)
4741 return NestedNameSpecifierLoc();
4742 ObjectType = QualType();
4743 FirstQualifierInScope = nullptr;
4744 }
4745 SS.Adopt(Other: QualifierLoc);
4746 Sema::NestedNameSpecInfo IdInfo(
4747 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4748 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4749 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4750 EnteringContext: false, SS,
4751 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4752 return NestedNameSpecifierLoc();
4753 return SS.getWithLocInContext(Context&: SemaRef.Context);
4754 }
4755
4756 QualType T = TL.getType();
4757 TypeLocBuilder TLB;
4758 if (!getDerived().AlreadyTransformed(T)) {
4759 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4760 FirstQualifierInScope);
4761 if (T.isNull())
4762 return NestedNameSpecifierLoc();
4763 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4764 }
4765
4766 if (T->isDependentType() || T->isRecordType() ||
4767 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4768 if (T->isEnumeralType())
4769 SemaRef.Diag(Loc: TL.getBeginLoc(),
4770 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4771 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4772 break;
4773 }
4774 // If the nested-name-specifier is an invalid type def, don't emit an
4775 // error because a previous error should have already been emitted.
4776 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4777 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4778 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4779 << T << SS.getRange();
4780 }
4781 return NestedNameSpecifierLoc();
4782 }
4783 }
4784 }
4785
4786 // Don't rebuild the nested-name-specifier if we don't have to.
4787 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4788 !getDerived().AlwaysRebuild())
4789 return NNS;
4790
4791 // If we can re-use the source-location data from the original
4792 // nested-name-specifier, do so.
4793 if (SS.location_size() == NNS.getDataLength() &&
4794 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4795 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4796
4797 // Allocate new nested-name-specifier location information.
4798 return SS.getWithLocInContext(Context&: SemaRef.Context);
4799}
4800
4801template<typename Derived>
4802DeclarationNameInfo
4803TreeTransform<Derived>
4804::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4805 DeclarationName Name = NameInfo.getName();
4806 if (!Name)
4807 return DeclarationNameInfo();
4808
4809 switch (Name.getNameKind()) {
4810 case DeclarationName::Identifier:
4811 case DeclarationName::ObjCZeroArgSelector:
4812 case DeclarationName::ObjCOneArgSelector:
4813 case DeclarationName::ObjCMultiArgSelector:
4814 case DeclarationName::CXXOperatorName:
4815 case DeclarationName::CXXLiteralOperatorName:
4816 case DeclarationName::CXXUsingDirective:
4817 return NameInfo;
4818
4819 case DeclarationName::CXXDeductionGuideName: {
4820 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4821 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4822 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4823 if (!NewTemplate)
4824 return DeclarationNameInfo();
4825
4826 DeclarationNameInfo NewNameInfo(NameInfo);
4827 NewNameInfo.setName(
4828 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4829 return NewNameInfo;
4830 }
4831
4832 case DeclarationName::CXXConstructorName:
4833 case DeclarationName::CXXDestructorName:
4834 case DeclarationName::CXXConversionFunctionName: {
4835 TypeSourceInfo *NewTInfo;
4836 CanQualType NewCanTy;
4837 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4838 NewTInfo = getDerived().TransformType(OldTInfo);
4839 if (!NewTInfo)
4840 return DeclarationNameInfo();
4841 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4842 }
4843 else {
4844 NewTInfo = nullptr;
4845 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4846 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4847 if (NewT.isNull())
4848 return DeclarationNameInfo();
4849 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4850 }
4851
4852 DeclarationName NewName
4853 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4854 Ty: NewCanTy);
4855 DeclarationNameInfo NewNameInfo(NameInfo);
4856 NewNameInfo.setName(NewName);
4857 NewNameInfo.setNamedTypeInfo(NewTInfo);
4858 return NewNameInfo;
4859 }
4860 }
4861
4862 llvm_unreachable("Unknown name kind.");
4863}
4864
4865template <typename Derived>
4866TemplateName TreeTransform<Derived>::RebuildTemplateName(
4867 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4868 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4869 QualType ObjectType, bool AllowInjectedClassName) {
4870 if (const IdentifierInfo *II = IO.getIdentifier())
4871 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4872 ObjectType, AllowInjectedClassName);
4873 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4874 NameLoc, ObjectType,
4875 AllowInjectedClassName);
4876}
4877
4878template <typename Derived>
4879TemplateName TreeTransform<Derived>::TransformTemplateName(
4880 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4881 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4882 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4883 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4884 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4885
4886 if (QualifierLoc) {
4887 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4888 QualifierLoc, ObjectType, FirstQualifierInScope);
4889 if (!QualifierLoc)
4890 return TemplateName();
4891 }
4892
4893 NestedNameSpecifierLoc UnderlyingQualifier;
4894 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4895 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4896 FirstQualifierInScope, AllowInjectedClassName);
4897 if (NewUnderlyingName.isNull())
4898 return TemplateName();
4899 assert(!UnderlyingQualifier && "unexpected qualifier");
4900
4901 if (!getDerived().AlwaysRebuild() &&
4902 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4903 NewUnderlyingName == UnderlyingName)
4904 return Name;
4905 CXXScopeSpec SS;
4906 SS.Adopt(Other: QualifierLoc);
4907 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4908 NewUnderlyingName);
4909 }
4910
4911 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4912 if (QualifierLoc) {
4913 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4914 QualifierLoc, ObjectType, FirstQualifierInScope);
4915 if (!QualifierLoc)
4916 return TemplateName();
4917 // The qualifier-in-scope and object type only apply to the leftmost
4918 // entity.
4919 ObjectType = QualType();
4920 }
4921
4922 if (!getDerived().AlwaysRebuild() &&
4923 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4924 ObjectType.isNull())
4925 return Name;
4926
4927 CXXScopeSpec SS;
4928 SS.Adopt(Other: QualifierLoc);
4929 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4930 NameLoc, ObjectType,
4931 AllowInjectedClassName);
4932 }
4933
4934 if (SubstTemplateTemplateParmStorage *S =
4935 Name.getAsSubstTemplateTemplateParm()) {
4936 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4937
4938 NestedNameSpecifierLoc ReplacementQualifierLoc;
4939 TemplateName ReplacementName = S->getReplacement();
4940 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4941 NestedNameSpecifierLocBuilder Builder;
4942 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4943 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4944 }
4945
4946 TemplateName NewName = getDerived().TransformTemplateName(
4947 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4948 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4949 if (NewName.isNull())
4950 return TemplateName();
4951 Decl *AssociatedDecl =
4952 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4953 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4954 AssociatedDecl == S->getAssociatedDecl())
4955 return Name;
4956 return SemaRef.Context.getSubstTemplateTemplateParm(
4957 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4958 Final: S->getFinal());
4959 }
4960
4961 assert(!Name.getAsDeducedTemplateName() &&
4962 "DeducedTemplateName should not escape partial ordering");
4963
4964 // FIXME: Preserve UsingTemplateName.
4965 if (auto *Template = Name.getAsTemplateDecl()) {
4966 assert(!QualifierLoc && "Unexpected qualifier");
4967 return TemplateName(cast_or_null<TemplateDecl>(
4968 getDerived().TransformDecl(NameLoc, Template)));
4969 }
4970
4971 if (SubstTemplateTemplateParmPackStorage *SubstPack
4972 = Name.getAsSubstTemplateTemplateParmPack()) {
4973 assert(!QualifierLoc &&
4974 "Unexpected qualified SubstTemplateTemplateParmPack");
4975 return getDerived().RebuildTemplateName(
4976 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4977 SubstPack->getIndex(), SubstPack->getFinal());
4978 }
4979
4980 // These should be getting filtered out before they reach the AST.
4981 llvm_unreachable("overloaded function decl survived to here");
4982}
4983
4984template <typename Derived>
4985TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
4986 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
4987 TemplateName Name, SourceLocation NameLoc) {
4988 TemplateName TN = getDerived().TransformTemplateName(
4989 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
4990 if (TN.isNull())
4991 return TemplateArgument();
4992 return TemplateArgument(TN);
4993}
4994
4995template<typename Derived>
4996void TreeTransform<Derived>::InventTemplateArgumentLoc(
4997 const TemplateArgument &Arg,
4998 TemplateArgumentLoc &Output) {
4999 Output = getSema().getTrivialTemplateArgumentLoc(
5000 Arg, QualType(), getDerived().getBaseLocation());
5001}
5002
5003template <typename Derived>
5004bool TreeTransform<Derived>::TransformTemplateArgument(
5005 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5006 bool Uneval) {
5007 const TemplateArgument &Arg = Input.getArgument();
5008 switch (Arg.getKind()) {
5009 case TemplateArgument::Null:
5010 case TemplateArgument::Pack:
5011 llvm_unreachable("Unexpected TemplateArgument");
5012
5013 case TemplateArgument::Integral:
5014 case TemplateArgument::NullPtr:
5015 case TemplateArgument::Declaration:
5016 case TemplateArgument::StructuralValue: {
5017 // Transform a resolved template argument straight to a resolved template
5018 // argument. We get here when substituting into an already-substituted
5019 // template type argument during concept satisfaction checking.
5020 QualType T = Arg.getNonTypeTemplateArgumentType();
5021 QualType NewT = getDerived().TransformType(T);
5022 if (NewT.isNull())
5023 return true;
5024
5025 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5026 ? Arg.getAsDecl()
5027 : nullptr;
5028 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5029 getDerived().getBaseLocation(), D))
5030 : nullptr;
5031 if (D && !NewD)
5032 return true;
5033
5034 if (NewT == T && D == NewD)
5035 Output = Input;
5036 else if (Arg.getKind() == TemplateArgument::Integral)
5037 Output = TemplateArgumentLoc(
5038 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5039 TemplateArgumentLocInfo());
5040 else if (Arg.getKind() == TemplateArgument::NullPtr)
5041 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5042 TemplateArgumentLocInfo());
5043 else if (Arg.getKind() == TemplateArgument::Declaration)
5044 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5045 TemplateArgumentLocInfo());
5046 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5047 Output = TemplateArgumentLoc(
5048 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5049 TemplateArgumentLocInfo());
5050 else
5051 llvm_unreachable("unexpected template argument kind");
5052
5053 return false;
5054 }
5055
5056 case TemplateArgument::Type: {
5057 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5058 if (!TSI)
5059 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5060
5061 TSI = getDerived().TransformType(TSI);
5062 if (!TSI)
5063 return true;
5064
5065 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5066 return false;
5067 }
5068
5069 case TemplateArgument::Template: {
5070 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5071
5072 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5073 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5074 Input.getTemplateNameLoc());
5075 if (Out.isNull())
5076 return true;
5077 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5078 QualifierLoc, Input.getTemplateNameLoc());
5079 return false;
5080 }
5081
5082 case TemplateArgument::TemplateExpansion:
5083 llvm_unreachable("Caller should expand pack expansions");
5084
5085 case TemplateArgument::Expression: {
5086 // Template argument expressions are constant expressions.
5087 EnterExpressionEvaluationContext Unevaluated(
5088 getSema(),
5089 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5090 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5091 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5092 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5093
5094 Expr *InputExpr = Input.getSourceExpression();
5095 if (!InputExpr)
5096 InputExpr = Input.getArgument().getAsExpr();
5097
5098 ExprResult E = getDerived().TransformExpr(InputExpr);
5099 E = SemaRef.ActOnConstantExpression(Res: E);
5100 if (E.isInvalid())
5101 return true;
5102 Output = TemplateArgumentLoc(
5103 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5104 return false;
5105 }
5106 }
5107
5108 // Work around bogus GCC warning
5109 return true;
5110}
5111
5112/// Iterator adaptor that invents template argument location information
5113/// for each of the template arguments in its underlying iterator.
5114template<typename Derived, typename InputIterator>
5115class TemplateArgumentLocInventIterator {
5116 TreeTransform<Derived> &Self;
5117 InputIterator Iter;
5118
5119public:
5120 typedef TemplateArgumentLoc value_type;
5121 typedef TemplateArgumentLoc reference;
5122 typedef typename std::iterator_traits<InputIterator>::difference_type
5123 difference_type;
5124 typedef std::input_iterator_tag iterator_category;
5125
5126 class pointer {
5127 TemplateArgumentLoc Arg;
5128
5129 public:
5130 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5131
5132 const TemplateArgumentLoc *operator->() const { return &Arg; }
5133 };
5134
5135 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5136 InputIterator Iter)
5137 : Self(Self), Iter(Iter) { }
5138
5139 TemplateArgumentLocInventIterator &operator++() {
5140 ++Iter;
5141 return *this;
5142 }
5143
5144 TemplateArgumentLocInventIterator operator++(int) {
5145 TemplateArgumentLocInventIterator Old(*this);
5146 ++(*this);
5147 return Old;
5148 }
5149
5150 reference operator*() const {
5151 TemplateArgumentLoc Result;
5152 Self.InventTemplateArgumentLoc(*Iter, Result);
5153 return Result;
5154 }
5155
5156 pointer operator->() const { return pointer(**this); }
5157
5158 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5159 const TemplateArgumentLocInventIterator &Y) {
5160 return X.Iter == Y.Iter;
5161 }
5162
5163 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5164 const TemplateArgumentLocInventIterator &Y) {
5165 return X.Iter != Y.Iter;
5166 }
5167};
5168
5169template<typename Derived>
5170template<typename InputIterator>
5171bool TreeTransform<Derived>::TransformTemplateArguments(
5172 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5173 bool Uneval) {
5174 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5175 TemplateArgumentLoc Out;
5176 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5177 // Unpack argument packs, which we translate them into separate
5178 // arguments.
5179 // FIXME: We could do much better if we could guarantee that the
5180 // TemplateArgumentLocInfo for the pack expansion would be usable for
5181 // all of the template arguments in the argument pack.
5182 typedef TemplateArgumentLocInventIterator<Derived,
5183 TemplateArgument::pack_iterator>
5184 PackLocIterator;
5185
5186 TemplateArgumentListInfo *PackOutput = &Outputs;
5187 TemplateArgumentListInfo New;
5188
5189 if (TransformTemplateArguments(
5190 PackLocIterator(*this, In.getArgument().pack_begin()),
5191 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5192 Uneval))
5193 return true;
5194
5195 continue;
5196 }
5197
5198 if (In.getArgument().isPackExpansion()) {
5199 UnexpandedInfo Info;
5200 TemplateArgumentLoc Prepared;
5201 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5202 return true;
5203 if (!Info.Expand) {
5204 Outputs.addArgument(Loc: Prepared);
5205 continue;
5206 }
5207
5208 // The transform has determined that we should perform an elementwise
5209 // expansion of the pattern. Do so.
5210 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5211 if (Info.ExpandUnderForgetSubstitions)
5212 ForgetSubst.emplace(getDerived());
5213 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5214 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5215
5216 TemplateArgumentLoc Out;
5217 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5218 return true;
5219
5220 if (Out.getArgument().containsUnexpandedParameterPack()) {
5221 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5222 Info.OrigNumExpansions);
5223 if (Out.getArgument().isNull())
5224 return true;
5225 }
5226
5227 Outputs.addArgument(Loc: Out);
5228 }
5229
5230 // If we're supposed to retain a pack expansion, do so by temporarily
5231 // forgetting the partially-substituted parameter pack.
5232 if (Info.RetainExpansion) {
5233 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5234
5235 TemplateArgumentLoc Out;
5236 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5237 return true;
5238
5239 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5240 Info.OrigNumExpansions);
5241 if (Out.getArgument().isNull())
5242 return true;
5243
5244 Outputs.addArgument(Loc: Out);
5245 }
5246
5247 continue;
5248 }
5249
5250 // The simple case:
5251 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5252 return true;
5253
5254 Outputs.addArgument(Loc: Out);
5255 }
5256
5257 return false;
5258}
5259
5260template <typename Derived>
5261template <typename InputIterator>
5262bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5263 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5264 bool Uneval) {
5265
5266 // [C++26][temp.constr.normal]
5267 // any non-dependent concept template argument
5268 // is substituted into the constraint-expression of C.
5269 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5270 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5271 };
5272
5273 for (; First != Last; ++First) {
5274 TemplateArgumentLoc Out;
5275 TemplateArgumentLoc In = *First;
5276
5277 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5278 typedef TemplateArgumentLocInventIterator<Derived,
5279 TemplateArgument::pack_iterator>
5280 PackLocIterator;
5281 if (TransformConceptTemplateArguments(
5282 PackLocIterator(*this, In.getArgument().pack_begin()),
5283 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5284 Uneval))
5285 return true;
5286 continue;
5287 }
5288
5289 if (!isNonDependentConceptArgument(In.getArgument())) {
5290 Outputs.addArgument(Loc: In);
5291 continue;
5292 }
5293
5294 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5295 return true;
5296
5297 Outputs.addArgument(Loc: Out);
5298 }
5299
5300 return false;
5301}
5302
5303// FIXME: Find ways to reduce code duplication for pack expansions.
5304template <typename Derived>
5305bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5306 bool Uneval,
5307 TemplateArgumentLoc &Out,
5308 UnexpandedInfo &Info) {
5309 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5310 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5311 TemplateArgumentLoc &Pattern) {
5312 assert(Arg.getArgument().isPackExpansion());
5313 // We have a pack expansion, for which we will be substituting into the
5314 // pattern.
5315 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5316 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5317 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5318 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5319 if (IsLateExpansionAttempt) {
5320 // Request expansion only when there is an opportunity to expand a pack
5321 // that required a substituion first.
5322 bool SawPackTypes =
5323 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5324 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5325 });
5326 if (!SawPackTypes) {
5327 Info.Expand = false;
5328 return false;
5329 }
5330 }
5331 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5332
5333 // Determine whether the set of unexpanded parameter packs can and
5334 // should be expanded.
5335 Info.Expand = true;
5336 Info.RetainExpansion = false;
5337 Info.NumExpansions = Info.OrigNumExpansions;
5338 return getDerived().TryExpandParameterPacks(
5339 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5340 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5341 Info.RetainExpansion, Info.NumExpansions);
5342 };
5343
5344 TemplateArgumentLoc Pattern;
5345 if (ComputeInfo(In, false, Info, Pattern))
5346 return true;
5347
5348 if (Info.Expand) {
5349 Out = Pattern;
5350 return false;
5351 }
5352
5353 // The transform has determined that we should perform a simple
5354 // transformation on the pack expansion, producing another pack
5355 // expansion.
5356 TemplateArgumentLoc OutPattern;
5357 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5358 std::in_place, getSema(), std::nullopt);
5359 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5360 return true;
5361
5362 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5363 Info.NumExpansions);
5364 if (Out.getArgument().isNull())
5365 return true;
5366 SubstIndex.reset();
5367
5368 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5369 return false;
5370
5371 // Some packs will learn their length after substitution, e.g.
5372 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5373 // value of `T`.
5374 //
5375 // We only expand after we know sizes of all packs, check if this is the case
5376 // or not. However, we avoid a full template substitution and only do
5377 // expanstions after this point.
5378
5379 // E.g. when substituting template arguments of tuple with {T -> int} in the
5380 // following example:
5381 // template <class T>
5382 // struct TupleWithInt {
5383 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5384 // };
5385 // TupleWithInt<int>::type y;
5386 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5387 // length and run `ComputeInfo()` to provide the necessary information to our
5388 // caller.
5389 //
5390 // Note that we may still have situations where builtin is not going to be
5391 // expanded. For example:
5392 // template <class T>
5393 // struct Foo {
5394 // template <class U> using tuple_with_t =
5395 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5396 // tuple_with_t<short>;
5397 // }
5398 // Because the substitution into `type` happens in dependent context, `type`
5399 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5400 // and the caller will not be able to expand it.
5401 ForgetSubstitutionRAII ForgetSubst(getDerived());
5402 if (ComputeInfo(Out, true, Info, OutPattern))
5403 return true;
5404 if (!Info.Expand)
5405 return false;
5406 Out = OutPattern;
5407 Info.ExpandUnderForgetSubstitions = true;
5408 return false;
5409}
5410
5411//===----------------------------------------------------------------------===//
5412// Type transformation
5413//===----------------------------------------------------------------------===//
5414
5415template<typename Derived>
5416QualType TreeTransform<Derived>::TransformType(QualType T) {
5417 if (getDerived().AlreadyTransformed(T))
5418 return T;
5419
5420 // Temporary workaround. All of these transformations should
5421 // eventually turn into transformations on TypeLocs.
5422 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5423 T, getDerived().getBaseLocation());
5424
5425 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5426
5427 if (!NewTSI)
5428 return QualType();
5429
5430 return NewTSI->getType();
5431}
5432
5433template <typename Derived>
5434TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5435 // Refine the base location to the type's location.
5436 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5437 getDerived().getBaseEntity());
5438 if (getDerived().AlreadyTransformed(TSI->getType()))
5439 return TSI;
5440
5441 TypeLocBuilder TLB;
5442
5443 TypeLoc TL = TSI->getTypeLoc();
5444 TLB.reserve(Requested: TL.getFullDataSize());
5445
5446 QualType Result = getDerived().TransformType(TLB, TL);
5447 if (Result.isNull())
5448 return nullptr;
5449
5450 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5451}
5452
5453template<typename Derived>
5454QualType
5455TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5456 switch (T.getTypeLocClass()) {
5457#define ABSTRACT_TYPELOC(CLASS, PARENT)
5458#define TYPELOC(CLASS, PARENT) \
5459 case TypeLoc::CLASS: \
5460 return getDerived().Transform##CLASS##Type(TLB, \
5461 T.castAs<CLASS##TypeLoc>());
5462#include "clang/AST/TypeLocNodes.def"
5463 }
5464
5465 llvm_unreachable("unhandled type loc!");
5466}
5467
5468template<typename Derived>
5469QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5470 if (!isa<DependentNameType>(Val: T))
5471 return TransformType(T);
5472
5473 if (getDerived().AlreadyTransformed(T))
5474 return T;
5475 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5476 T, getDerived().getBaseLocation());
5477 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5478 return NewTSI ? NewTSI->getType() : QualType();
5479}
5480
5481template <typename Derived>
5482TypeSourceInfo *
5483TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5484 if (!isa<DependentNameType>(Val: TSI->getType()))
5485 return TransformType(TSI);
5486
5487 // Refine the base location to the type's location.
5488 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5489 getDerived().getBaseEntity());
5490 if (getDerived().AlreadyTransformed(TSI->getType()))
5491 return TSI;
5492
5493 TypeLocBuilder TLB;
5494
5495 TypeLoc TL = TSI->getTypeLoc();
5496 TLB.reserve(Requested: TL.getFullDataSize());
5497
5498 auto QTL = TL.getAs<QualifiedTypeLoc>();
5499 if (QTL)
5500 TL = QTL.getUnqualifiedLoc();
5501
5502 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5503
5504 QualType Result = getDerived().TransformDependentNameType(
5505 TLB, DNTL, /*DeducedTSTContext*/true);
5506 if (Result.isNull())
5507 return nullptr;
5508
5509 if (QTL) {
5510 Result = getDerived().RebuildQualifiedType(Result, QTL);
5511 if (Result.isNull())
5512 return nullptr;
5513 TLB.TypeWasModifiedSafely(T: Result);
5514 }
5515
5516 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5517}
5518
5519template<typename Derived>
5520QualType
5521TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5522 QualifiedTypeLoc T) {
5523 QualType Result;
5524 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5525 auto SuppressObjCLifetime =
5526 T.getType().getLocalQualifiers().hasObjCLifetime();
5527 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5528 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5529 SuppressObjCLifetime);
5530 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5531 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5532 TLB, STTP, SuppressObjCLifetime);
5533 } else {
5534 Result = getDerived().TransformType(TLB, UnqualTL);
5535 }
5536
5537 if (Result.isNull())
5538 return QualType();
5539
5540 Result = getDerived().RebuildQualifiedType(Result, T);
5541
5542 if (Result.isNull())
5543 return QualType();
5544
5545 // RebuildQualifiedType might have updated the type, but not in a way
5546 // that invalidates the TypeLoc. (There's no location information for
5547 // qualifiers.)
5548 TLB.TypeWasModifiedSafely(T: Result);
5549
5550 return Result;
5551}
5552
5553template <typename Derived>
5554QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5555 QualifiedTypeLoc TL) {
5556
5557 SourceLocation Loc = TL.getBeginLoc();
5558 Qualifiers Quals = TL.getType().getLocalQualifiers();
5559
5560 if ((T.getAddressSpace() != LangAS::Default &&
5561 Quals.getAddressSpace() != LangAS::Default) &&
5562 T.getAddressSpace() != Quals.getAddressSpace()) {
5563 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5564 << TL.getType() << T;
5565 return QualType();
5566 }
5567
5568 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5569 if (LocalPointerAuth.isPresent()) {
5570 if (T.getPointerAuth().isPresent()) {
5571 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5572 return QualType();
5573 }
5574 if (!T->isDependentType()) {
5575 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5576 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5577 return QualType();
5578 }
5579 }
5580 }
5581 // C++ [dcl.fct]p7:
5582 // [When] adding cv-qualifications on top of the function type [...] the
5583 // cv-qualifiers are ignored.
5584 if (T->isFunctionType()) {
5585 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5586 AddressSpace: Quals.getAddressSpace());
5587 return T;
5588 }
5589
5590 // C++ [dcl.ref]p1:
5591 // when the cv-qualifiers are introduced through the use of a typedef-name
5592 // or decltype-specifier [...] the cv-qualifiers are ignored.
5593 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5594 // applied to a reference type.
5595 if (T->isReferenceType()) {
5596 // The only qualifier that applies to a reference type is restrict.
5597 if (!Quals.hasRestrict())
5598 return T;
5599 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5600 }
5601
5602 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5603 // resulting type.
5604 if (Quals.hasObjCLifetime()) {
5605 if (!T->isObjCLifetimeType() && !T->isDependentType())
5606 Quals.removeObjCLifetime();
5607 else if (T.getObjCLifetime()) {
5608 // Objective-C ARC:
5609 // A lifetime qualifier applied to a substituted template parameter
5610 // overrides the lifetime qualifier from the template argument.
5611 const AutoType *AutoTy;
5612 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5613 // 'auto' types behave the same way as template parameters.
5614 QualType Deduced = AutoTy->getDeducedType();
5615 Qualifiers Qs = Deduced.getQualifiers();
5616 Qs.removeObjCLifetime();
5617 Deduced =
5618 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5619 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5620 IsDependent: AutoTy->isDependentType(),
5621 /*isPack=*/IsPack: false,
5622 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5623 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5624 } else {
5625 // Otherwise, complain about the addition of a qualifier to an
5626 // already-qualified type.
5627 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5628 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5629 Quals.removeObjCLifetime();
5630 }
5631 }
5632 }
5633
5634 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5635}
5636
5637template <typename Derived>
5638QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5639 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5640 NamedDecl *FirstQualifierInScope) {
5641 assert(!getDerived().AlreadyTransformed(TL.getType()));
5642
5643 switch (TL.getTypeLocClass()) {
5644 case TypeLoc::TemplateSpecialization:
5645 return getDerived().TransformTemplateSpecializationType(
5646 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5647 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5648 case TypeLoc::DependentName:
5649 return getDerived().TransformDependentNameType(
5650 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5651 ObjectType, FirstQualifierInScope);
5652 default:
5653 // Any dependent canonical type can appear here, through type alias
5654 // templates.
5655 return getDerived().TransformType(TLB, TL);
5656 }
5657}
5658
5659template <class TyLoc> static inline
5660QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5661 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5662 NewT.setNameLoc(T.getNameLoc());
5663 return T.getType();
5664}
5665
5666template<typename Derived>
5667QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5668 BuiltinTypeLoc T) {
5669 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5670 NewT.setBuiltinLoc(T.getBuiltinLoc());
5671 if (T.needsExtraLocalData())
5672 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5673 return T.getType();
5674}
5675
5676template<typename Derived>
5677QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5678 ComplexTypeLoc T) {
5679 // FIXME: recurse?
5680 return TransformTypeSpecType(TLB, T);
5681}
5682
5683template <typename Derived>
5684QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5685 AdjustedTypeLoc TL) {
5686 // Adjustments applied during transformation are handled elsewhere.
5687 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5688}
5689
5690template<typename Derived>
5691QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5692 DecayedTypeLoc TL) {
5693 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5694 if (OriginalType.isNull())
5695 return QualType();
5696
5697 QualType Result = TL.getType();
5698 if (getDerived().AlwaysRebuild() ||
5699 OriginalType != TL.getOriginalLoc().getType())
5700 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5701 TLB.push<DecayedTypeLoc>(T: Result);
5702 // Nothing to set for DecayedTypeLoc.
5703 return Result;
5704}
5705
5706template <typename Derived>
5707QualType
5708TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5709 ArrayParameterTypeLoc TL) {
5710 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5711 if (OriginalType.isNull())
5712 return QualType();
5713
5714 QualType Result = TL.getType();
5715 if (getDerived().AlwaysRebuild() ||
5716 OriginalType != TL.getElementLoc().getType())
5717 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5718 TLB.push<ArrayParameterTypeLoc>(T: Result);
5719 // Nothing to set for ArrayParameterTypeLoc.
5720 return Result;
5721}
5722
5723template<typename Derived>
5724QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5725 PointerTypeLoc TL) {
5726 QualType PointeeType
5727 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5728 if (PointeeType.isNull())
5729 return QualType();
5730
5731 QualType Result = TL.getType();
5732 if (PointeeType->getAs<ObjCObjectType>()) {
5733 // A dependent pointer type 'T *' has is being transformed such
5734 // that an Objective-C class type is being replaced for 'T'. The
5735 // resulting pointer type is an ObjCObjectPointerType, not a
5736 // PointerType.
5737 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5738
5739 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5740 NewT.setStarLoc(TL.getStarLoc());
5741 return Result;
5742 }
5743
5744 if (getDerived().AlwaysRebuild() ||
5745 PointeeType != TL.getPointeeLoc().getType()) {
5746 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5747 if (Result.isNull())
5748 return QualType();
5749 }
5750
5751 // Objective-C ARC can add lifetime qualifiers to the type that we're
5752 // pointing to.
5753 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5754
5755 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5756 NewT.setSigilLoc(TL.getSigilLoc());
5757 return Result;
5758}
5759
5760template<typename Derived>
5761QualType
5762TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5763 BlockPointerTypeLoc TL) {
5764 QualType PointeeType
5765 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5766 if (PointeeType.isNull())
5767 return QualType();
5768
5769 QualType Result = TL.getType();
5770 if (getDerived().AlwaysRebuild() ||
5771 PointeeType != TL.getPointeeLoc().getType()) {
5772 Result = getDerived().RebuildBlockPointerType(PointeeType,
5773 TL.getSigilLoc());
5774 if (Result.isNull())
5775 return QualType();
5776 }
5777
5778 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5779 NewT.setSigilLoc(TL.getSigilLoc());
5780 return Result;
5781}
5782
5783/// Transforms a reference type. Note that somewhat paradoxically we
5784/// don't care whether the type itself is an l-value type or an r-value
5785/// type; we only care if the type was *written* as an l-value type
5786/// or an r-value type.
5787template<typename Derived>
5788QualType
5789TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5790 ReferenceTypeLoc TL) {
5791 const ReferenceType *T = TL.getTypePtr();
5792
5793 // Note that this works with the pointee-as-written.
5794 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5795 if (PointeeType.isNull())
5796 return QualType();
5797
5798 QualType Result = TL.getType();
5799 if (getDerived().AlwaysRebuild() ||
5800 PointeeType != T->getPointeeTypeAsWritten()) {
5801 Result = getDerived().RebuildReferenceType(PointeeType,
5802 T->isSpelledAsLValue(),
5803 TL.getSigilLoc());
5804 if (Result.isNull())
5805 return QualType();
5806 }
5807
5808 // Objective-C ARC can add lifetime qualifiers to the type that we're
5809 // referring to.
5810 TLB.TypeWasModifiedSafely(
5811 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5812
5813 // r-value references can be rebuilt as l-value references.
5814 ReferenceTypeLoc NewTL;
5815 if (isa<LValueReferenceType>(Val: Result))
5816 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5817 else
5818 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5819 NewTL.setSigilLoc(TL.getSigilLoc());
5820
5821 return Result;
5822}
5823
5824template<typename Derived>
5825QualType
5826TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5827 LValueReferenceTypeLoc TL) {
5828 return TransformReferenceType(TLB, TL);
5829}
5830
5831template<typename Derived>
5832QualType
5833TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5834 RValueReferenceTypeLoc TL) {
5835 return TransformReferenceType(TLB, TL);
5836}
5837
5838template<typename Derived>
5839QualType
5840TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5841 MemberPointerTypeLoc TL) {
5842 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5843 if (PointeeType.isNull())
5844 return QualType();
5845
5846 const MemberPointerType *T = TL.getTypePtr();
5847
5848 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5849 NestedNameSpecifierLoc NewQualifierLoc =
5850 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5851 if (!NewQualifierLoc)
5852 return QualType();
5853
5854 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5855 if (OldCls) {
5856 NewCls = cast_or_null<CXXRecordDecl>(
5857 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5858 if (!NewCls)
5859 return QualType();
5860 }
5861
5862 QualType Result = TL.getType();
5863 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5864 NewQualifierLoc.getNestedNameSpecifier() !=
5865 OldQualifierLoc.getNestedNameSpecifier() ||
5866 NewCls != OldCls) {
5867 CXXScopeSpec SS;
5868 SS.Adopt(Other: NewQualifierLoc);
5869 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5870 TL.getStarLoc());
5871 if (Result.isNull())
5872 return QualType();
5873 }
5874
5875 // If we had to adjust the pointee type when building a member pointer, make
5876 // sure to push TypeLoc info for it.
5877 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5878 if (MPT && PointeeType != MPT->getPointeeType()) {
5879 assert(isa<AdjustedType>(MPT->getPointeeType()));
5880 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5881 }
5882
5883 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5884 NewTL.setSigilLoc(TL.getSigilLoc());
5885 NewTL.setQualifierLoc(NewQualifierLoc);
5886
5887 return Result;
5888}
5889
5890template<typename Derived>
5891QualType
5892TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5893 ConstantArrayTypeLoc TL) {
5894 const ConstantArrayType *T = TL.getTypePtr();
5895 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5896 if (ElementType.isNull())
5897 return QualType();
5898
5899 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5900 Expr *OldSize = TL.getSizeExpr();
5901 if (!OldSize)
5902 OldSize = const_cast<Expr*>(T->getSizeExpr());
5903 Expr *NewSize = nullptr;
5904 if (OldSize) {
5905 EnterExpressionEvaluationContext Unevaluated(
5906 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5907 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5908 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5909 }
5910
5911 QualType Result = TL.getType();
5912 if (getDerived().AlwaysRebuild() ||
5913 ElementType != T->getElementType() ||
5914 (T->getSizeExpr() && NewSize != OldSize)) {
5915 Result = getDerived().RebuildConstantArrayType(ElementType,
5916 T->getSizeModifier(),
5917 T->getSize(), NewSize,
5918 T->getIndexTypeCVRQualifiers(),
5919 TL.getBracketsRange());
5920 if (Result.isNull())
5921 return QualType();
5922 }
5923
5924 // We might have either a ConstantArrayType or a VariableArrayType now:
5925 // a ConstantArrayType is allowed to have an element type which is a
5926 // VariableArrayType if the type is dependent. Fortunately, all array
5927 // types have the same location layout.
5928 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5929 NewTL.setLBracketLoc(TL.getLBracketLoc());
5930 NewTL.setRBracketLoc(TL.getRBracketLoc());
5931 NewTL.setSizeExpr(NewSize);
5932
5933 return Result;
5934}
5935
5936template<typename Derived>
5937QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5938 TypeLocBuilder &TLB,
5939 IncompleteArrayTypeLoc TL) {
5940 const IncompleteArrayType *T = TL.getTypePtr();
5941 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5942 if (ElementType.isNull())
5943 return QualType();
5944
5945 QualType Result = TL.getType();
5946 if (getDerived().AlwaysRebuild() ||
5947 ElementType != T->getElementType()) {
5948 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5949 T->getSizeModifier(),
5950 T->getIndexTypeCVRQualifiers(),
5951 TL.getBracketsRange());
5952 if (Result.isNull())
5953 return QualType();
5954 }
5955
5956 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5957 NewTL.setLBracketLoc(TL.getLBracketLoc());
5958 NewTL.setRBracketLoc(TL.getRBracketLoc());
5959 NewTL.setSizeExpr(nullptr);
5960
5961 return Result;
5962}
5963
5964template<typename Derived>
5965QualType
5966TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5967 VariableArrayTypeLoc TL) {
5968 const VariableArrayType *T = TL.getTypePtr();
5969 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5970 if (ElementType.isNull())
5971 return QualType();
5972
5973 ExprResult SizeResult;
5974 {
5975 EnterExpressionEvaluationContext Context(
5976 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5977 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5978 }
5979 if (SizeResult.isInvalid())
5980 return QualType();
5981 SizeResult =
5982 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5983 if (SizeResult.isInvalid())
5984 return QualType();
5985
5986 Expr *Size = SizeResult.get();
5987
5988 QualType Result = TL.getType();
5989 if (getDerived().AlwaysRebuild() ||
5990 ElementType != T->getElementType() ||
5991 Size != T->getSizeExpr()) {
5992 Result = getDerived().RebuildVariableArrayType(ElementType,
5993 T->getSizeModifier(),
5994 Size,
5995 T->getIndexTypeCVRQualifiers(),
5996 TL.getBracketsRange());
5997 if (Result.isNull())
5998 return QualType();
5999 }
6000
6001 // We might have constant size array now, but fortunately it has the same
6002 // location layout.
6003 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6004 NewTL.setLBracketLoc(TL.getLBracketLoc());
6005 NewTL.setRBracketLoc(TL.getRBracketLoc());
6006 NewTL.setSizeExpr(Size);
6007
6008 return Result;
6009}
6010
6011template<typename Derived>
6012QualType
6013TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6014 DependentSizedArrayTypeLoc TL) {
6015 const DependentSizedArrayType *T = TL.getTypePtr();
6016 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6017 if (ElementType.isNull())
6018 return QualType();
6019
6020 // Array bounds are constant expressions.
6021 EnterExpressionEvaluationContext Unevaluated(
6022 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6023
6024 // If we have a VLA then it won't be a constant.
6025 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6026
6027 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6028 Expr *origSize = TL.getSizeExpr();
6029 if (!origSize) origSize = T->getSizeExpr();
6030
6031 ExprResult sizeResult
6032 = getDerived().TransformExpr(origSize);
6033 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6034 if (sizeResult.isInvalid())
6035 return QualType();
6036
6037 Expr *size = sizeResult.get();
6038
6039 QualType Result = TL.getType();
6040 if (getDerived().AlwaysRebuild() ||
6041 ElementType != T->getElementType() ||
6042 size != origSize) {
6043 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6044 T->getSizeModifier(),
6045 size,
6046 T->getIndexTypeCVRQualifiers(),
6047 TL.getBracketsRange());
6048 if (Result.isNull())
6049 return QualType();
6050 }
6051
6052 // We might have any sort of array type now, but fortunately they
6053 // all have the same location layout.
6054 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6055 NewTL.setLBracketLoc(TL.getLBracketLoc());
6056 NewTL.setRBracketLoc(TL.getRBracketLoc());
6057 NewTL.setSizeExpr(size);
6058
6059 return Result;
6060}
6061
6062template <typename Derived>
6063QualType TreeTransform<Derived>::TransformDependentVectorType(
6064 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6065 const DependentVectorType *T = TL.getTypePtr();
6066 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6067 if (ElementType.isNull())
6068 return QualType();
6069
6070 EnterExpressionEvaluationContext Unevaluated(
6071 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6072
6073 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6074 Size = SemaRef.ActOnConstantExpression(Res: Size);
6075 if (Size.isInvalid())
6076 return QualType();
6077
6078 QualType Result = TL.getType();
6079 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6080 Size.get() != T->getSizeExpr()) {
6081 Result = getDerived().RebuildDependentVectorType(
6082 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6083 if (Result.isNull())
6084 return QualType();
6085 }
6086
6087 // Result might be dependent or not.
6088 if (isa<DependentVectorType>(Val: Result)) {
6089 DependentVectorTypeLoc NewTL =
6090 TLB.push<DependentVectorTypeLoc>(T: Result);
6091 NewTL.setNameLoc(TL.getNameLoc());
6092 } else {
6093 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6094 NewTL.setNameLoc(TL.getNameLoc());
6095 }
6096
6097 return Result;
6098}
6099
6100template<typename Derived>
6101QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6102 TypeLocBuilder &TLB,
6103 DependentSizedExtVectorTypeLoc TL) {
6104 const DependentSizedExtVectorType *T = TL.getTypePtr();
6105
6106 // FIXME: ext vector locs should be nested
6107 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6108 if (ElementType.isNull())
6109 return QualType();
6110
6111 // Vector sizes are constant expressions.
6112 EnterExpressionEvaluationContext Unevaluated(
6113 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6114
6115 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6116 Size = SemaRef.ActOnConstantExpression(Res: Size);
6117 if (Size.isInvalid())
6118 return QualType();
6119
6120 QualType Result = TL.getType();
6121 if (getDerived().AlwaysRebuild() ||
6122 ElementType != T->getElementType() ||
6123 Size.get() != T->getSizeExpr()) {
6124 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6125 Size.get(),
6126 T->getAttributeLoc());
6127 if (Result.isNull())
6128 return QualType();
6129 }
6130
6131 // Result might be dependent or not.
6132 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6133 DependentSizedExtVectorTypeLoc NewTL
6134 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6135 NewTL.setNameLoc(TL.getNameLoc());
6136 } else {
6137 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6138 NewTL.setNameLoc(TL.getNameLoc());
6139 }
6140
6141 return Result;
6142}
6143
6144template <typename Derived>
6145QualType
6146TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6147 ConstantMatrixTypeLoc TL) {
6148 const ConstantMatrixType *T = TL.getTypePtr();
6149 QualType ElementType = getDerived().TransformType(T->getElementType());
6150 if (ElementType.isNull())
6151 return QualType();
6152
6153 QualType Result = TL.getType();
6154 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6155 Result = getDerived().RebuildConstantMatrixType(
6156 ElementType, T->getNumRows(), T->getNumColumns());
6157 if (Result.isNull())
6158 return QualType();
6159 }
6160
6161 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6162 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6163 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6164 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6165 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6166
6167 return Result;
6168}
6169
6170template <typename Derived>
6171QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6172 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6173 const DependentSizedMatrixType *T = TL.getTypePtr();
6174
6175 QualType ElementType = getDerived().TransformType(T->getElementType());
6176 if (ElementType.isNull()) {
6177 return QualType();
6178 }
6179
6180 // Matrix dimensions are constant expressions.
6181 EnterExpressionEvaluationContext Unevaluated(
6182 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6183
6184 Expr *origRows = TL.getAttrRowOperand();
6185 if (!origRows)
6186 origRows = T->getRowExpr();
6187 Expr *origColumns = TL.getAttrColumnOperand();
6188 if (!origColumns)
6189 origColumns = T->getColumnExpr();
6190
6191 ExprResult rowResult = getDerived().TransformExpr(origRows);
6192 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6193 if (rowResult.isInvalid())
6194 return QualType();
6195
6196 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6197 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6198 if (columnResult.isInvalid())
6199 return QualType();
6200
6201 Expr *rows = rowResult.get();
6202 Expr *columns = columnResult.get();
6203
6204 QualType Result = TL.getType();
6205 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6206 rows != origRows || columns != origColumns) {
6207 Result = getDerived().RebuildDependentSizedMatrixType(
6208 ElementType, rows, columns, T->getAttributeLoc());
6209
6210 if (Result.isNull())
6211 return QualType();
6212 }
6213
6214 // We might have any sort of matrix type now, but fortunately they
6215 // all have the same location layout.
6216 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6217 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6218 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6219 NewTL.setAttrRowOperand(rows);
6220 NewTL.setAttrColumnOperand(columns);
6221 return Result;
6222}
6223
6224template <typename Derived>
6225QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6226 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6227 const DependentAddressSpaceType *T = TL.getTypePtr();
6228
6229 QualType pointeeType =
6230 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6231
6232 if (pointeeType.isNull())
6233 return QualType();
6234
6235 // Address spaces are constant expressions.
6236 EnterExpressionEvaluationContext Unevaluated(
6237 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6238
6239 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6240 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6241 if (AddrSpace.isInvalid())
6242 return QualType();
6243
6244 QualType Result = TL.getType();
6245 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6246 AddrSpace.get() != T->getAddrSpaceExpr()) {
6247 Result = getDerived().RebuildDependentAddressSpaceType(
6248 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6249 if (Result.isNull())
6250 return QualType();
6251 }
6252
6253 // Result might be dependent or not.
6254 if (isa<DependentAddressSpaceType>(Val: Result)) {
6255 DependentAddressSpaceTypeLoc NewTL =
6256 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6257
6258 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6259 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6260 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6261
6262 } else {
6263 TLB.TypeWasModifiedSafely(T: Result);
6264 }
6265
6266 return Result;
6267}
6268
6269template <typename Derived>
6270QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6271 VectorTypeLoc TL) {
6272 const VectorType *T = TL.getTypePtr();
6273 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6274 if (ElementType.isNull())
6275 return QualType();
6276
6277 QualType Result = TL.getType();
6278 if (getDerived().AlwaysRebuild() ||
6279 ElementType != T->getElementType()) {
6280 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6281 T->getVectorKind());
6282 if (Result.isNull())
6283 return QualType();
6284 }
6285
6286 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6287 NewTL.setNameLoc(TL.getNameLoc());
6288
6289 return Result;
6290}
6291
6292template<typename Derived>
6293QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6294 ExtVectorTypeLoc TL) {
6295 const VectorType *T = TL.getTypePtr();
6296 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6297 if (ElementType.isNull())
6298 return QualType();
6299
6300 QualType Result = TL.getType();
6301 if (getDerived().AlwaysRebuild() ||
6302 ElementType != T->getElementType()) {
6303 Result = getDerived().RebuildExtVectorType(ElementType,
6304 T->getNumElements(),
6305 /*FIXME*/ SourceLocation());
6306 if (Result.isNull())
6307 return QualType();
6308 }
6309
6310 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6311 NewTL.setNameLoc(TL.getNameLoc());
6312
6313 return Result;
6314}
6315
6316template <typename Derived>
6317ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6318 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6319 bool ExpectParameterPack) {
6320 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6321 TypeSourceInfo *NewTSI = nullptr;
6322
6323 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6324 // If we're substituting into a pack expansion type and we know the
6325 // length we want to expand to, just substitute for the pattern.
6326 TypeLoc OldTL = OldTSI->getTypeLoc();
6327 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6328
6329 TypeLocBuilder TLB;
6330 TypeLoc NewTL = OldTSI->getTypeLoc();
6331 TLB.reserve(Requested: NewTL.getFullDataSize());
6332
6333 QualType Result = getDerived().TransformType(TLB,
6334 OldExpansionTL.getPatternLoc());
6335 if (Result.isNull())
6336 return nullptr;
6337
6338 Result = RebuildPackExpansionType(Pattern: Result,
6339 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6340 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6341 NumExpansions);
6342 if (Result.isNull())
6343 return nullptr;
6344
6345 PackExpansionTypeLoc NewExpansionTL
6346 = TLB.push<PackExpansionTypeLoc>(T: Result);
6347 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6348 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6349 } else
6350 NewTSI = getDerived().TransformType(OldTSI);
6351 if (!NewTSI)
6352 return nullptr;
6353
6354 if (NewTSI == OldTSI && indexAdjustment == 0)
6355 return OldParm;
6356
6357 ParmVarDecl *newParm = ParmVarDecl::Create(
6358 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6359 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6360 TInfo: NewTSI, S: OldParm->getStorageClass(),
6361 /* DefArg */ DefArg: nullptr);
6362 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6363 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6364 getDerived().transformedLocalDecl(OldParm, {newParm});
6365 return newParm;
6366}
6367
6368template <typename Derived>
6369bool TreeTransform<Derived>::TransformFunctionTypeParams(
6370 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6371 const QualType *ParamTypes,
6372 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6373 SmallVectorImpl<QualType> &OutParamTypes,
6374 SmallVectorImpl<ParmVarDecl *> *PVars,
6375 Sema::ExtParameterInfoBuilder &PInfos,
6376 unsigned *LastParamTransformed) {
6377 int indexAdjustment = 0;
6378
6379 unsigned NumParams = Params.size();
6380 for (unsigned i = 0; i != NumParams; ++i) {
6381 if (LastParamTransformed)
6382 *LastParamTransformed = i;
6383 if (ParmVarDecl *OldParm = Params[i]) {
6384 assert(OldParm->getFunctionScopeIndex() == i);
6385
6386 UnsignedOrNone NumExpansions = std::nullopt;
6387 ParmVarDecl *NewParm = nullptr;
6388 if (OldParm->isParameterPack()) {
6389 // We have a function parameter pack that may need to be expanded.
6390 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6391
6392 // Find the parameter packs that could be expanded.
6393 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6394 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6395 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6396 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6397
6398 // Determine whether we should expand the parameter packs.
6399 bool ShouldExpand = false;
6400 bool RetainExpansion = false;
6401 UnsignedOrNone OrigNumExpansions = std::nullopt;
6402 if (Unexpanded.size() > 0) {
6403 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6404 NumExpansions = OrigNumExpansions;
6405 if (getDerived().TryExpandParameterPacks(
6406 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6407 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6408 ShouldExpand, RetainExpansion, NumExpansions)) {
6409 return true;
6410 }
6411 } else {
6412#ifndef NDEBUG
6413 const AutoType *AT =
6414 Pattern.getType().getTypePtr()->getContainedAutoType();
6415 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6416 "Could not find parameter packs or undeduced auto type!");
6417#endif
6418 }
6419
6420 if (ShouldExpand) {
6421 // Expand the function parameter pack into multiple, separate
6422 // parameters.
6423 getDerived().ExpandingFunctionParameterPack(OldParm);
6424 for (unsigned I = 0; I != *NumExpansions; ++I) {
6425 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6426 ParmVarDecl *NewParm
6427 = getDerived().TransformFunctionTypeParam(OldParm,
6428 indexAdjustment++,
6429 OrigNumExpansions,
6430 /*ExpectParameterPack=*/false);
6431 if (!NewParm)
6432 return true;
6433
6434 if (ParamInfos)
6435 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6436 OutParamTypes.push_back(Elt: NewParm->getType());
6437 if (PVars)
6438 PVars->push_back(Elt: NewParm);
6439 }
6440
6441 // If we're supposed to retain a pack expansion, do so by temporarily
6442 // forgetting the partially-substituted parameter pack.
6443 if (RetainExpansion) {
6444 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6445 ParmVarDecl *NewParm
6446 = getDerived().TransformFunctionTypeParam(OldParm,
6447 indexAdjustment++,
6448 OrigNumExpansions,
6449 /*ExpectParameterPack=*/false);
6450 if (!NewParm)
6451 return true;
6452
6453 if (ParamInfos)
6454 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6455 OutParamTypes.push_back(Elt: NewParm->getType());
6456 if (PVars)
6457 PVars->push_back(Elt: NewParm);
6458 }
6459
6460 // The next parameter should have the same adjustment as the
6461 // last thing we pushed, but we post-incremented indexAdjustment
6462 // on every push. Also, if we push nothing, the adjustment should
6463 // go down by one.
6464 indexAdjustment--;
6465
6466 // We're done with the pack expansion.
6467 continue;
6468 }
6469
6470 // We'll substitute the parameter now without expanding the pack
6471 // expansion.
6472 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6473 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6474 indexAdjustment,
6475 NumExpansions,
6476 /*ExpectParameterPack=*/true);
6477 assert(NewParm->isParameterPack() &&
6478 "Parameter pack no longer a parameter pack after "
6479 "transformation.");
6480 } else {
6481 NewParm = getDerived().TransformFunctionTypeParam(
6482 OldParm, indexAdjustment, std::nullopt,
6483 /*ExpectParameterPack=*/false);
6484 }
6485
6486 if (!NewParm)
6487 return true;
6488
6489 if (ParamInfos)
6490 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6491 OutParamTypes.push_back(Elt: NewParm->getType());
6492 if (PVars)
6493 PVars->push_back(Elt: NewParm);
6494 continue;
6495 }
6496
6497 // Deal with the possibility that we don't have a parameter
6498 // declaration for this parameter.
6499 assert(ParamTypes);
6500 QualType OldType = ParamTypes[i];
6501 bool IsPackExpansion = false;
6502 UnsignedOrNone NumExpansions = std::nullopt;
6503 QualType NewType;
6504 if (const PackExpansionType *Expansion
6505 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6506 // We have a function parameter pack that may need to be expanded.
6507 QualType Pattern = Expansion->getPattern();
6508 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6509 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6510
6511 // Determine whether we should expand the parameter packs.
6512 bool ShouldExpand = false;
6513 bool RetainExpansion = false;
6514 if (getDerived().TryExpandParameterPacks(
6515 Loc, SourceRange(), Unexpanded,
6516 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6517 RetainExpansion, NumExpansions)) {
6518 return true;
6519 }
6520
6521 if (ShouldExpand) {
6522 // Expand the function parameter pack into multiple, separate
6523 // parameters.
6524 for (unsigned I = 0; I != *NumExpansions; ++I) {
6525 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6526 QualType NewType = getDerived().TransformType(Pattern);
6527 if (NewType.isNull())
6528 return true;
6529
6530 if (NewType->containsUnexpandedParameterPack()) {
6531 NewType = getSema().getASTContext().getPackExpansionType(
6532 NewType, std::nullopt);
6533
6534 if (NewType.isNull())
6535 return true;
6536 }
6537
6538 if (ParamInfos)
6539 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6540 OutParamTypes.push_back(Elt: NewType);
6541 if (PVars)
6542 PVars->push_back(Elt: nullptr);
6543 }
6544
6545 // We're done with the pack expansion.
6546 continue;
6547 }
6548
6549 // If we're supposed to retain a pack expansion, do so by temporarily
6550 // forgetting the partially-substituted parameter pack.
6551 if (RetainExpansion) {
6552 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6553 QualType NewType = getDerived().TransformType(Pattern);
6554 if (NewType.isNull())
6555 return true;
6556
6557 if (ParamInfos)
6558 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6559 OutParamTypes.push_back(Elt: NewType);
6560 if (PVars)
6561 PVars->push_back(Elt: nullptr);
6562 }
6563
6564 // We'll substitute the parameter now without expanding the pack
6565 // expansion.
6566 OldType = Expansion->getPattern();
6567 IsPackExpansion = true;
6568 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6569 NewType = getDerived().TransformType(OldType);
6570 } else {
6571 NewType = getDerived().TransformType(OldType);
6572 }
6573
6574 if (NewType.isNull())
6575 return true;
6576
6577 if (IsPackExpansion)
6578 NewType = getSema().Context.getPackExpansionType(NewType,
6579 NumExpansions);
6580
6581 if (ParamInfos)
6582 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6583 OutParamTypes.push_back(Elt: NewType);
6584 if (PVars)
6585 PVars->push_back(Elt: nullptr);
6586 }
6587
6588#ifndef NDEBUG
6589 if (PVars) {
6590 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6591 if (ParmVarDecl *parm = (*PVars)[i])
6592 assert(parm->getFunctionScopeIndex() == i);
6593 }
6594#endif
6595
6596 return false;
6597}
6598
6599template<typename Derived>
6600QualType
6601TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6602 FunctionProtoTypeLoc TL) {
6603 SmallVector<QualType, 4> ExceptionStorage;
6604 return getDerived().TransformFunctionProtoType(
6605 TLB, TL, nullptr, Qualifiers(),
6606 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6607 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6608 ExceptionStorage, Changed);
6609 });
6610}
6611
6612template<typename Derived> template<typename Fn>
6613QualType TreeTransform<Derived>::TransformFunctionProtoType(
6614 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6615 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6616
6617 // Transform the parameters and return type.
6618 //
6619 // We are required to instantiate the params and return type in source order.
6620 // When the function has a trailing return type, we instantiate the
6621 // parameters before the return type, since the return type can then refer
6622 // to the parameters themselves (via decltype, sizeof, etc.).
6623 //
6624 SmallVector<QualType, 4> ParamTypes;
6625 SmallVector<ParmVarDecl*, 4> ParamDecls;
6626 Sema::ExtParameterInfoBuilder ExtParamInfos;
6627 const FunctionProtoType *T = TL.getTypePtr();
6628
6629 QualType ResultType;
6630
6631 if (T->hasTrailingReturn()) {
6632 if (getDerived().TransformFunctionTypeParams(
6633 TL.getBeginLoc(), TL.getParams(),
6634 TL.getTypePtr()->param_type_begin(),
6635 T->getExtParameterInfosOrNull(),
6636 ParamTypes, &ParamDecls, ExtParamInfos))
6637 return QualType();
6638
6639 {
6640 // C++11 [expr.prim.general]p3:
6641 // If a declaration declares a member function or member function
6642 // template of a class X, the expression this is a prvalue of type
6643 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6644 // and the end of the function-definition, member-declarator, or
6645 // declarator.
6646 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6647 Sema::CXXThisScopeRAII ThisScope(
6648 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6649
6650 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6651 if (ResultType.isNull())
6652 return QualType();
6653 }
6654 }
6655 else {
6656 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6657 if (ResultType.isNull())
6658 return QualType();
6659
6660 if (getDerived().TransformFunctionTypeParams(
6661 TL.getBeginLoc(), TL.getParams(),
6662 TL.getTypePtr()->param_type_begin(),
6663 T->getExtParameterInfosOrNull(),
6664 ParamTypes, &ParamDecls, ExtParamInfos))
6665 return QualType();
6666 }
6667
6668 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6669
6670 bool EPIChanged = false;
6671 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6672 return QualType();
6673
6674 // Handle extended parameter information.
6675 if (auto NewExtParamInfos =
6676 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6677 if (!EPI.ExtParameterInfos ||
6678 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6679 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6680 EPIChanged = true;
6681 }
6682 EPI.ExtParameterInfos = NewExtParamInfos;
6683 } else if (EPI.ExtParameterInfos) {
6684 EPIChanged = true;
6685 EPI.ExtParameterInfos = nullptr;
6686 }
6687
6688 // Transform any function effects with unevaluated conditions.
6689 // Hold this set in a local for the rest of this function, since EPI
6690 // may need to hold a FunctionEffectsRef pointing into it.
6691 std::optional<FunctionEffectSet> NewFX;
6692 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6693 NewFX.emplace();
6694 EnterExpressionEvaluationContext Unevaluated(
6695 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6696
6697 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6698 FunctionEffectWithCondition NewEC = PrevEC;
6699 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6700 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6701 if (NewExpr.isInvalid())
6702 return QualType();
6703 std::optional<FunctionEffectMode> Mode =
6704 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6705 if (!Mode)
6706 return QualType();
6707
6708 // The condition expression has been transformed, and re-evaluated.
6709 // It may or may not have become constant.
6710 switch (*Mode) {
6711 case FunctionEffectMode::True:
6712 NewEC.Cond = {};
6713 break;
6714 case FunctionEffectMode::False:
6715 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6716 NewEC.Cond = {};
6717 break;
6718 case FunctionEffectMode::Dependent:
6719 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6720 break;
6721 case FunctionEffectMode::None:
6722 llvm_unreachable(
6723 "FunctionEffectMode::None shouldn't be possible here");
6724 }
6725 }
6726 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6727 NewAttrLoc: TL.getBeginLoc())) {
6728 FunctionEffectSet::Conflicts Errs;
6729 NewFX->insert(NewEC, Errs);
6730 assert(Errs.empty());
6731 }
6732 }
6733 EPI.FunctionEffects = *NewFX;
6734 EPIChanged = true;
6735 }
6736
6737 QualType Result = TL.getType();
6738 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6739 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6740 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6741 if (Result.isNull())
6742 return QualType();
6743 }
6744
6745 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6746 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6747 NewTL.setLParenLoc(TL.getLParenLoc());
6748 NewTL.setRParenLoc(TL.getRParenLoc());
6749 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6750 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6751 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6752 NewTL.setParam(i, VD: ParamDecls[i]);
6753
6754 return Result;
6755}
6756
6757template<typename Derived>
6758bool TreeTransform<Derived>::TransformExceptionSpec(
6759 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6760 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6761 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6762
6763 // Instantiate a dynamic noexcept expression, if any.
6764 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6765 // Update this scrope because ContextDecl in Sema will be used in
6766 // TransformExpr.
6767 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6768 Sema::CXXThisScopeRAII ThisScope(
6769 SemaRef, Method ? Method->getParent() : nullptr,
6770 Method ? Method->getMethodQualifiers() : Qualifiers{},
6771 Method != nullptr);
6772 EnterExpressionEvaluationContext Unevaluated(
6773 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6774 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6775 if (NoexceptExpr.isInvalid())
6776 return true;
6777
6778 ExceptionSpecificationType EST = ESI.Type;
6779 NoexceptExpr =
6780 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6781 if (NoexceptExpr.isInvalid())
6782 return true;
6783
6784 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6785 Changed = true;
6786 ESI.NoexceptExpr = NoexceptExpr.get();
6787 ESI.Type = EST;
6788 }
6789
6790 if (ESI.Type != EST_Dynamic)
6791 return false;
6792
6793 // Instantiate a dynamic exception specification's type.
6794 for (QualType T : ESI.Exceptions) {
6795 if (const PackExpansionType *PackExpansion =
6796 T->getAs<PackExpansionType>()) {
6797 Changed = true;
6798
6799 // We have a pack expansion. Instantiate it.
6800 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6801 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6802 Unexpanded);
6803 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6804
6805 // Determine whether the set of unexpanded parameter packs can and
6806 // should
6807 // be expanded.
6808 bool Expand = false;
6809 bool RetainExpansion = false;
6810 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6811 // FIXME: Track the location of the ellipsis (and track source location
6812 // information for the types in the exception specification in general).
6813 if (getDerived().TryExpandParameterPacks(
6814 Loc, SourceRange(), Unexpanded,
6815 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6816 NumExpansions))
6817 return true;
6818
6819 if (!Expand) {
6820 // We can't expand this pack expansion into separate arguments yet;
6821 // just substitute into the pattern and create a new pack expansion
6822 // type.
6823 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6824 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6825 if (U.isNull())
6826 return true;
6827
6828 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6829 Exceptions.push_back(Elt: U);
6830 continue;
6831 }
6832
6833 // Substitute into the pack expansion pattern for each slice of the
6834 // pack.
6835 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6836 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6837
6838 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6839 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6840 return true;
6841
6842 Exceptions.push_back(Elt: U);
6843 }
6844 } else {
6845 QualType U = getDerived().TransformType(T);
6846 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6847 return true;
6848 if (T != U)
6849 Changed = true;
6850
6851 Exceptions.push_back(Elt: U);
6852 }
6853 }
6854
6855 ESI.Exceptions = Exceptions;
6856 if (ESI.Exceptions.empty())
6857 ESI.Type = EST_DynamicNone;
6858 return false;
6859}
6860
6861template<typename Derived>
6862QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6863 TypeLocBuilder &TLB,
6864 FunctionNoProtoTypeLoc TL) {
6865 const FunctionNoProtoType *T = TL.getTypePtr();
6866 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6867 if (ResultType.isNull())
6868 return QualType();
6869
6870 QualType Result = TL.getType();
6871 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6872 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6873
6874 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6875 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6876 NewTL.setLParenLoc(TL.getLParenLoc());
6877 NewTL.setRParenLoc(TL.getRParenLoc());
6878 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6879
6880 return Result;
6881}
6882
6883template <typename Derived>
6884QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6885 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6886
6887 const UnresolvedUsingType *T = TL.getTypePtr();
6888 bool Changed = false;
6889
6890 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6891 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6892 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6893 if (!QualifierLoc)
6894 return QualType();
6895 Changed |= QualifierLoc != OldQualifierLoc;
6896 }
6897
6898 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6899 if (!D)
6900 return QualType();
6901 Changed |= D != T->getDecl();
6902
6903 QualType Result = TL.getType();
6904 if (getDerived().AlwaysRebuild() || Changed) {
6905 Result = getDerived().RebuildUnresolvedUsingType(
6906 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
6907 D);
6908 if (Result.isNull())
6909 return QualType();
6910 }
6911
6912 if (isa<UsingType>(Val: Result))
6913 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6914 QualifierLoc, NameLoc: TL.getNameLoc());
6915 else
6916 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6917 QualifierLoc, NameLoc: TL.getNameLoc());
6918 return Result;
6919}
6920
6921template <typename Derived>
6922QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6923 UsingTypeLoc TL) {
6924 const UsingType *T = TL.getTypePtr();
6925 bool Changed = false;
6926
6927 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6928 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6929 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6930 if (!QualifierLoc)
6931 return QualType();
6932 Changed |= QualifierLoc != OldQualifierLoc;
6933 }
6934
6935 auto *D = cast_or_null<UsingShadowDecl>(
6936 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6937 if (!D)
6938 return QualType();
6939 Changed |= D != T->getDecl();
6940
6941 QualType UnderlyingType = getDerived().TransformType(T->desugar());
6942 if (UnderlyingType.isNull())
6943 return QualType();
6944 Changed |= UnderlyingType != T->desugar();
6945
6946 QualType Result = TL.getType();
6947 if (getDerived().AlwaysRebuild() || Changed) {
6948 Result = getDerived().RebuildUsingType(
6949 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
6950 UnderlyingType);
6951 if (Result.isNull())
6952 return QualType();
6953 }
6954 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
6955 NameLoc: TL.getNameLoc());
6956 return Result;
6957}
6958
6959template<typename Derived>
6960QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6961 TypedefTypeLoc TL) {
6962 const TypedefType *T = TL.getTypePtr();
6963 bool Changed = false;
6964
6965 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6966 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6967 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6968 if (!QualifierLoc)
6969 return QualType();
6970 Changed |= QualifierLoc != OldQualifierLoc;
6971 }
6972
6973 auto *Typedef = cast_or_null<TypedefNameDecl>(
6974 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6975 if (!Typedef)
6976 return QualType();
6977 Changed |= Typedef != T->getDecl();
6978
6979 // FIXME: Transform the UnderlyingType if different from decl.
6980
6981 QualType Result = TL.getType();
6982 if (getDerived().AlwaysRebuild() || Changed) {
6983 Result = getDerived().RebuildTypedefType(
6984 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
6985 if (Result.isNull())
6986 return QualType();
6987 }
6988
6989 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6990 QualifierLoc, NameLoc: TL.getNameLoc());
6991 return Result;
6992}
6993
6994template<typename Derived>
6995QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6996 TypeOfExprTypeLoc TL) {
6997 // typeof expressions are not potentially evaluated contexts
6998 EnterExpressionEvaluationContext Unevaluated(
6999 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7000 Sema::ReuseLambdaContextDecl);
7001
7002 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7003 if (E.isInvalid())
7004 return QualType();
7005
7006 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7007 if (E.isInvalid())
7008 return QualType();
7009
7010 QualType Result = TL.getType();
7011 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7012 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7013 Result =
7014 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7015 if (Result.isNull())
7016 return QualType();
7017 }
7018
7019 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7020 NewTL.setTypeofLoc(TL.getTypeofLoc());
7021 NewTL.setLParenLoc(TL.getLParenLoc());
7022 NewTL.setRParenLoc(TL.getRParenLoc());
7023
7024 return Result;
7025}
7026
7027template<typename Derived>
7028QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7029 TypeOfTypeLoc TL) {
7030 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7031 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7032 if (!New_Under_TI)
7033 return QualType();
7034
7035 QualType Result = TL.getType();
7036 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7037 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7038 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7039 if (Result.isNull())
7040 return QualType();
7041 }
7042
7043 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7044 NewTL.setTypeofLoc(TL.getTypeofLoc());
7045 NewTL.setLParenLoc(TL.getLParenLoc());
7046 NewTL.setRParenLoc(TL.getRParenLoc());
7047 NewTL.setUnmodifiedTInfo(New_Under_TI);
7048
7049 return Result;
7050}
7051
7052template<typename Derived>
7053QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7054 DecltypeTypeLoc TL) {
7055 const DecltypeType *T = TL.getTypePtr();
7056
7057 // decltype expressions are not potentially evaluated contexts
7058 EnterExpressionEvaluationContext Unevaluated(
7059 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7060 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7061
7062 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7063 if (E.isInvalid())
7064 return QualType();
7065
7066 E = getSema().ActOnDecltypeExpression(E.get());
7067 if (E.isInvalid())
7068 return QualType();
7069
7070 QualType Result = TL.getType();
7071 if (getDerived().AlwaysRebuild() ||
7072 E.get() != T->getUnderlyingExpr()) {
7073 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7074 if (Result.isNull())
7075 return QualType();
7076 }
7077 else E.get();
7078
7079 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7080 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7081 NewTL.setRParenLoc(TL.getRParenLoc());
7082 return Result;
7083}
7084
7085template <typename Derived>
7086QualType
7087TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7088 PackIndexingTypeLoc TL) {
7089 // Transform the index
7090 ExprResult IndexExpr;
7091 {
7092 EnterExpressionEvaluationContext ConstantContext(
7093 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7094
7095 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7096 if (IndexExpr.isInvalid())
7097 return QualType();
7098 }
7099 QualType Pattern = TL.getPattern();
7100
7101 const PackIndexingType *PIT = TL.getTypePtr();
7102 SmallVector<QualType, 5> SubtitutedTypes;
7103 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7104
7105 bool NotYetExpanded = Types.empty();
7106 bool FullySubstituted = true;
7107
7108 if (Types.empty() && !PIT->expandsToEmptyPack())
7109 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7110
7111 for (QualType T : Types) {
7112 if (!T->containsUnexpandedParameterPack()) {
7113 QualType Transformed = getDerived().TransformType(T);
7114 if (Transformed.isNull())
7115 return QualType();
7116 SubtitutedTypes.push_back(Elt: Transformed);
7117 continue;
7118 }
7119
7120 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7121 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7122 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7123 // Determine whether the set of unexpanded parameter packs can and should
7124 // be expanded.
7125 bool ShouldExpand = true;
7126 bool RetainExpansion = false;
7127 UnsignedOrNone NumExpansions = std::nullopt;
7128 if (getDerived().TryExpandParameterPacks(
7129 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7130 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7131 RetainExpansion, NumExpansions))
7132 return QualType();
7133 if (!ShouldExpand) {
7134 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7135 // FIXME: should we keep TypeLoc for individual expansions in
7136 // PackIndexingTypeLoc?
7137 TypeSourceInfo *TI =
7138 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7139 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7140 if (Pack.isNull())
7141 return QualType();
7142 if (NotYetExpanded) {
7143 FullySubstituted = false;
7144 QualType Out = getDerived().RebuildPackIndexingType(
7145 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7146 FullySubstituted);
7147 if (Out.isNull())
7148 return QualType();
7149
7150 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7151 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7152 return Out;
7153 }
7154 SubtitutedTypes.push_back(Elt: Pack);
7155 continue;
7156 }
7157 for (unsigned I = 0; I != *NumExpansions; ++I) {
7158 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7159 QualType Out = getDerived().TransformType(T);
7160 if (Out.isNull())
7161 return QualType();
7162 SubtitutedTypes.push_back(Elt: Out);
7163 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7164 }
7165 // If we're supposed to retain a pack expansion, do so by temporarily
7166 // forgetting the partially-substituted parameter pack.
7167 if (RetainExpansion) {
7168 FullySubstituted = false;
7169 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7170 QualType Out = getDerived().TransformType(T);
7171 if (Out.isNull())
7172 return QualType();
7173 SubtitutedTypes.push_back(Elt: Out);
7174 }
7175 }
7176
7177 // A pack indexing type can appear in a larger pack expansion,
7178 // e.g. `Pack...[pack_of_indexes]...`
7179 // so we need to temporarily disable substitution of pack elements
7180 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7181 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7182
7183 QualType Out = getDerived().RebuildPackIndexingType(
7184 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7185 FullySubstituted, SubtitutedTypes);
7186 if (Out.isNull())
7187 return Out;
7188
7189 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7190 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7191 return Out;
7192}
7193
7194template<typename Derived>
7195QualType TreeTransform<Derived>::TransformUnaryTransformType(
7196 TypeLocBuilder &TLB,
7197 UnaryTransformTypeLoc TL) {
7198 QualType Result = TL.getType();
7199 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7200 if (Result->isDependentType()) {
7201 const UnaryTransformType *T = TL.getTypePtr();
7202
7203 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7204 if (!NewBaseTSI)
7205 return QualType();
7206 QualType NewBase = NewBaseTSI->getType();
7207
7208 Result = getDerived().RebuildUnaryTransformType(NewBase,
7209 T->getUTTKind(),
7210 TL.getKWLoc());
7211 if (Result.isNull())
7212 return QualType();
7213 }
7214
7215 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7216 NewTL.setKWLoc(TL.getKWLoc());
7217 NewTL.setParensRange(TL.getParensRange());
7218 NewTL.setUnderlyingTInfo(NewBaseTSI);
7219 return Result;
7220}
7221
7222template<typename Derived>
7223QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7224 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7225 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7226
7227 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7228 TemplateName TemplateName = getDerived().TransformTemplateName(
7229 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7230 TL.getTemplateNameLoc());
7231 if (TemplateName.isNull())
7232 return QualType();
7233
7234 QualType OldDeduced = T->getDeducedType();
7235 QualType NewDeduced;
7236 if (!OldDeduced.isNull()) {
7237 NewDeduced = getDerived().TransformType(OldDeduced);
7238 if (NewDeduced.isNull())
7239 return QualType();
7240 }
7241
7242 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7243 T->getKeyword(), TemplateName, NewDeduced);
7244 if (Result.isNull())
7245 return QualType();
7246
7247 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7248 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7249 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7250 NewTL.setQualifierLoc(QualifierLoc);
7251 return Result;
7252}
7253
7254template <typename Derived>
7255QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7256 TagTypeLoc TL) {
7257 const TagType *T = TL.getTypePtr();
7258
7259 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7260 if (QualifierLoc) {
7261 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7262 if (!QualifierLoc)
7263 return QualType();
7264 }
7265
7266 auto *TD = cast_or_null<TagDecl>(
7267 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7268 if (!TD)
7269 return QualType();
7270
7271 QualType Result = TL.getType();
7272 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7273 TD != T->getDecl()) {
7274 if (T->isCanonicalUnqualified())
7275 Result = getDerived().RebuildCanonicalTagType(TD);
7276 else
7277 Result = getDerived().RebuildTagType(
7278 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7279 if (Result.isNull())
7280 return QualType();
7281 }
7282
7283 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7284 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7285 NewTL.setQualifierLoc(QualifierLoc);
7286 NewTL.setNameLoc(TL.getNameLoc());
7287
7288 return Result;
7289}
7290
7291template <typename Derived>
7292QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7293 EnumTypeLoc TL) {
7294 return getDerived().TransformTagType(TLB, TL);
7295}
7296
7297template <typename Derived>
7298QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7299 RecordTypeLoc TL) {
7300 return getDerived().TransformTagType(TLB, TL);
7301}
7302
7303template<typename Derived>
7304QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7305 TypeLocBuilder &TLB,
7306 InjectedClassNameTypeLoc TL) {
7307 return getDerived().TransformTagType(TLB, TL);
7308}
7309
7310template<typename Derived>
7311QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7312 TypeLocBuilder &TLB,
7313 TemplateTypeParmTypeLoc TL) {
7314 return getDerived().TransformTemplateTypeParmType(
7315 TLB, TL,
7316 /*SuppressObjCLifetime=*/false);
7317}
7318
7319template <typename Derived>
7320QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7321 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7322 return TransformTypeSpecType(TLB, T: TL);
7323}
7324
7325template<typename Derived>
7326QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7327 TypeLocBuilder &TLB,
7328 SubstTemplateTypeParmTypeLoc TL) {
7329 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7330
7331 Decl *NewReplaced =
7332 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7333
7334 // Substitute into the replacement type, which itself might involve something
7335 // that needs to be transformed. This only tends to occur with default
7336 // template arguments of template template parameters.
7337 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7338 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7339 if (Replacement.isNull())
7340 return QualType();
7341
7342 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7343 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7344 Final: T->getFinal());
7345
7346 // Propagate type-source information.
7347 SubstTemplateTypeParmTypeLoc NewTL
7348 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7349 NewTL.setNameLoc(TL.getNameLoc());
7350 return Result;
7351
7352}
7353template <typename Derived>
7354QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7355 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7356 return TransformTypeSpecType(TLB, T: TL);
7357}
7358
7359template<typename Derived>
7360QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7361 TypeLocBuilder &TLB,
7362 SubstTemplateTypeParmPackTypeLoc TL) {
7363 return getDerived().TransformSubstTemplateTypeParmPackType(
7364 TLB, TL, /*SuppressObjCLifetime=*/false);
7365}
7366
7367template <typename Derived>
7368QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7369 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7370 return TransformTypeSpecType(TLB, T: TL);
7371}
7372
7373template<typename Derived>
7374QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7375 AtomicTypeLoc TL) {
7376 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7377 if (ValueType.isNull())
7378 return QualType();
7379
7380 QualType Result = TL.getType();
7381 if (getDerived().AlwaysRebuild() ||
7382 ValueType != TL.getValueLoc().getType()) {
7383 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7384 if (Result.isNull())
7385 return QualType();
7386 }
7387
7388 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7389 NewTL.setKWLoc(TL.getKWLoc());
7390 NewTL.setLParenLoc(TL.getLParenLoc());
7391 NewTL.setRParenLoc(TL.getRParenLoc());
7392
7393 return Result;
7394}
7395
7396template <typename Derived>
7397QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7398 PipeTypeLoc TL) {
7399 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7400 if (ValueType.isNull())
7401 return QualType();
7402
7403 QualType Result = TL.getType();
7404 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7405 const PipeType *PT = Result->castAs<PipeType>();
7406 bool isReadPipe = PT->isReadOnly();
7407 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7408 if (Result.isNull())
7409 return QualType();
7410 }
7411
7412 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7413 NewTL.setKWLoc(TL.getKWLoc());
7414
7415 return Result;
7416}
7417
7418template <typename Derived>
7419QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7420 BitIntTypeLoc TL) {
7421 const BitIntType *EIT = TL.getTypePtr();
7422 QualType Result = TL.getType();
7423
7424 if (getDerived().AlwaysRebuild()) {
7425 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7426 EIT->getNumBits(), TL.getNameLoc());
7427 if (Result.isNull())
7428 return QualType();
7429 }
7430
7431 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7432 NewTL.setNameLoc(TL.getNameLoc());
7433 return Result;
7434}
7435
7436template <typename Derived>
7437QualType TreeTransform<Derived>::TransformDependentBitIntType(
7438 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7439 const DependentBitIntType *EIT = TL.getTypePtr();
7440
7441 EnterExpressionEvaluationContext Unevaluated(
7442 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7443 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7444 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7445
7446 if (BitsExpr.isInvalid())
7447 return QualType();
7448
7449 QualType Result = TL.getType();
7450
7451 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7452 Result = getDerived().RebuildDependentBitIntType(
7453 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7454
7455 if (Result.isNull())
7456 return QualType();
7457 }
7458
7459 if (isa<DependentBitIntType>(Val: Result)) {
7460 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7461 NewTL.setNameLoc(TL.getNameLoc());
7462 } else {
7463 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7464 NewTL.setNameLoc(TL.getNameLoc());
7465 }
7466 return Result;
7467}
7468
7469template <typename Derived>
7470QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7471 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7472 llvm_unreachable("This type does not need to be transformed.");
7473}
7474
7475 /// Simple iterator that traverses the template arguments in a
7476 /// container that provides a \c getArgLoc() member function.
7477 ///
7478 /// This iterator is intended to be used with the iterator form of
7479 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7480 template<typename ArgLocContainer>
7481 class TemplateArgumentLocContainerIterator {
7482 ArgLocContainer *Container;
7483 unsigned Index;
7484
7485 public:
7486 typedef TemplateArgumentLoc value_type;
7487 typedef TemplateArgumentLoc reference;
7488 typedef int difference_type;
7489 typedef std::input_iterator_tag iterator_category;
7490
7491 class pointer {
7492 TemplateArgumentLoc Arg;
7493
7494 public:
7495 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7496
7497 const TemplateArgumentLoc *operator->() const {
7498 return &Arg;
7499 }
7500 };
7501
7502
7503 TemplateArgumentLocContainerIterator() {}
7504
7505 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7506 unsigned Index)
7507 : Container(&Container), Index(Index) { }
7508
7509 TemplateArgumentLocContainerIterator &operator++() {
7510 ++Index;
7511 return *this;
7512 }
7513
7514 TemplateArgumentLocContainerIterator operator++(int) {
7515 TemplateArgumentLocContainerIterator Old(*this);
7516 ++(*this);
7517 return Old;
7518 }
7519
7520 TemplateArgumentLoc operator*() const {
7521 return Container->getArgLoc(Index);
7522 }
7523
7524 pointer operator->() const {
7525 return pointer(Container->getArgLoc(Index));
7526 }
7527
7528 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7529 const TemplateArgumentLocContainerIterator &Y) {
7530 return X.Container == Y.Container && X.Index == Y.Index;
7531 }
7532
7533 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7534 const TemplateArgumentLocContainerIterator &Y) {
7535 return !(X == Y);
7536 }
7537 };
7538
7539template<typename Derived>
7540QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7541 AutoTypeLoc TL) {
7542 const AutoType *T = TL.getTypePtr();
7543 QualType OldDeduced = T->getDeducedType();
7544 QualType NewDeduced;
7545 if (!OldDeduced.isNull()) {
7546 NewDeduced = getDerived().TransformType(OldDeduced);
7547 if (NewDeduced.isNull())
7548 return QualType();
7549 }
7550
7551 ConceptDecl *NewCD = nullptr;
7552 TemplateArgumentListInfo NewTemplateArgs;
7553 NestedNameSpecifierLoc NewNestedNameSpec;
7554 if (T->isConstrained()) {
7555 assert(TL.getConceptReference());
7556 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7557 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7558
7559 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7560 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7561 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7562 if (getDerived().TransformTemplateArguments(
7563 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7564 NewTemplateArgs))
7565 return QualType();
7566
7567 if (TL.getNestedNameSpecifierLoc()) {
7568 NewNestedNameSpec
7569 = getDerived().TransformNestedNameSpecifierLoc(
7570 TL.getNestedNameSpecifierLoc());
7571 if (!NewNestedNameSpec)
7572 return QualType();
7573 }
7574 }
7575
7576 QualType Result = TL.getType();
7577 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7578 T->isDependentType() || T->isConstrained()) {
7579 // FIXME: Maybe don't rebuild if all template arguments are the same.
7580 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7581 NewArgList.reserve(N: NewTemplateArgs.size());
7582 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7583 NewArgList.push_back(Elt: ArgLoc.getArgument());
7584 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7585 NewArgList);
7586 if (Result.isNull())
7587 return QualType();
7588 }
7589
7590 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7591 NewTL.setNameLoc(TL.getNameLoc());
7592 NewTL.setRParenLoc(TL.getRParenLoc());
7593 NewTL.setConceptReference(nullptr);
7594
7595 if (T->isConstrained()) {
7596 DeclarationNameInfo DNI = DeclarationNameInfo(
7597 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7598 TL.getConceptNameLoc(),
7599 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7600 auto *CR = ConceptReference::Create(
7601 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7602 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7603 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7604 NewTL.setConceptReference(CR);
7605 }
7606
7607 return Result;
7608}
7609
7610template <typename Derived>
7611QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7612 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7613 return getDerived().TransformTemplateSpecializationType(
7614 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7615 /*AllowInjectedClassName=*/false);
7616}
7617
7618template <typename Derived>
7619QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7620 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7621 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7622 const TemplateSpecializationType *T = TL.getTypePtr();
7623
7624 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7625 TemplateName Template = getDerived().TransformTemplateName(
7626 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7627 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7628 AllowInjectedClassName);
7629 if (Template.isNull())
7630 return QualType();
7631
7632 TemplateArgumentListInfo NewTemplateArgs;
7633 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7634 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7635 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7636 ArgIterator;
7637 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7638 ArgIterator(TL, TL.getNumArgs()),
7639 NewTemplateArgs))
7640 return QualType();
7641
7642 // This needs to be rebuilt if either the arguments changed, or if the
7643 // original template changed. If the template changed, and even if the
7644 // arguments didn't change, these arguments might not correspond to their
7645 // respective parameters, therefore needing conversions.
7646 QualType Result = getDerived().RebuildTemplateSpecializationType(
7647 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7648 NewTemplateArgs);
7649
7650 if (!Result.isNull()) {
7651 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7652 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7653 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7654 }
7655
7656 return Result;
7657}
7658
7659template <typename Derived>
7660QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7661 AttributedTypeLoc TL) {
7662 const AttributedType *oldType = TL.getTypePtr();
7663 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7664 if (modifiedType.isNull())
7665 return QualType();
7666
7667 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7668 const Attr *oldAttr = TL.getAttr();
7669 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7670 if (oldAttr && !newAttr)
7671 return QualType();
7672
7673 QualType result = TL.getType();
7674
7675 // FIXME: dependent operand expressions?
7676 if (getDerived().AlwaysRebuild() ||
7677 modifiedType != oldType->getModifiedType()) {
7678 // If the equivalent type is equal to the modified type, we don't want to
7679 // transform it as well because:
7680 //
7681 // 1. The transformation would yield the same result and is therefore
7682 // superfluous, and
7683 //
7684 // 2. Transforming the same type twice can cause problems, e.g. if it
7685 // is a FunctionProtoType, we may end up instantiating the function
7686 // parameters twice, which causes an assertion since the parameters
7687 // are already bound to their counterparts in the template for this
7688 // instantiation.
7689 //
7690 QualType equivalentType = modifiedType;
7691 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7692 TypeLocBuilder AuxiliaryTLB;
7693 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7694 equivalentType =
7695 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7696 if (equivalentType.isNull())
7697 return QualType();
7698 }
7699
7700 // Check whether we can add nullability; it is only represented as
7701 // type sugar, and therefore cannot be diagnosed in any other way.
7702 if (auto nullability = oldType->getImmediateNullability()) {
7703 if (!modifiedType->canHaveNullability()) {
7704 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7705 : TL.getModifiedLoc().getBeginLoc()),
7706 DiagID: diag::err_nullability_nonpointer)
7707 << DiagNullabilityKind(*nullability, false) << modifiedType;
7708 return QualType();
7709 }
7710 }
7711
7712 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7713 modifiedType,
7714 equivalentType,
7715 attr: TL.getAttr());
7716 }
7717
7718 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7719 newTL.setAttr(newAttr);
7720 return result;
7721}
7722
7723template <typename Derived>
7724QualType TreeTransform<Derived>::TransformCountAttributedType(
7725 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7726 const CountAttributedType *OldTy = TL.getTypePtr();
7727 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7728 if (InnerTy.isNull())
7729 return QualType();
7730
7731 Expr *OldCount = TL.getCountExpr();
7732 Expr *NewCount = nullptr;
7733 if (OldCount) {
7734 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7735 if (CountResult.isInvalid())
7736 return QualType();
7737 NewCount = CountResult.get();
7738 }
7739
7740 QualType Result = TL.getType();
7741 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7742 OldCount != NewCount) {
7743 // Currently, CountAttributedType can only wrap incomplete array types.
7744 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7745 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7746 }
7747
7748 TLB.push<CountAttributedTypeLoc>(T: Result);
7749 return Result;
7750}
7751
7752template <typename Derived>
7753QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7754 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7755 // The BTFTagAttributedType is available for C only.
7756 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7757}
7758
7759template <typename Derived>
7760QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7761 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7762 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7763 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7764 if (InnerTy.isNull())
7765 return QualType();
7766
7767 QualType Result = TL.getType();
7768 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7769 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7770 Wrapped: InnerTy);
7771 if (Result.isNull())
7772 return QualType();
7773 }
7774
7775 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7776 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7777 return Result;
7778}
7779
7780template <typename Derived>
7781QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7782 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7783
7784 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7785
7786 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7787 if (WrappedTy.isNull())
7788 return QualType();
7789
7790 QualType ContainedTy = QualType();
7791 QualType OldContainedTy = oldType->getContainedType();
7792 TypeSourceInfo *ContainedTSI = nullptr;
7793 if (!OldContainedTy.isNull()) {
7794 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7795 if (!oldContainedTSI)
7796 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7797 OldContainedTy, SourceLocation());
7798 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7799 if (!ContainedTSI)
7800 return QualType();
7801 ContainedTy = ContainedTSI->getType();
7802 }
7803
7804 QualType Result = TL.getType();
7805 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7806 ContainedTy != oldType->getContainedType()) {
7807 Result = SemaRef.Context.getHLSLAttributedResourceType(
7808 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7809 }
7810
7811 HLSLAttributedResourceTypeLoc NewTL =
7812 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7813 NewTL.setSourceRange(TL.getLocalSourceRange());
7814 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7815 return Result;
7816}
7817
7818template <typename Derived>
7819QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7820 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7821 // No transformations needed.
7822 return TL.getType();
7823}
7824
7825template<typename Derived>
7826QualType
7827TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7828 ParenTypeLoc TL) {
7829 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7830 if (Inner.isNull())
7831 return QualType();
7832
7833 QualType Result = TL.getType();
7834 if (getDerived().AlwaysRebuild() ||
7835 Inner != TL.getInnerLoc().getType()) {
7836 Result = getDerived().RebuildParenType(Inner);
7837 if (Result.isNull())
7838 return QualType();
7839 }
7840
7841 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7842 NewTL.setLParenLoc(TL.getLParenLoc());
7843 NewTL.setRParenLoc(TL.getRParenLoc());
7844 return Result;
7845}
7846
7847template <typename Derived>
7848QualType
7849TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7850 MacroQualifiedTypeLoc TL) {
7851 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7852 if (Inner.isNull())
7853 return QualType();
7854
7855 QualType Result = TL.getType();
7856 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7857 Result =
7858 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7859 if (Result.isNull())
7860 return QualType();
7861 }
7862
7863 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7864 NewTL.setExpansionLoc(TL.getExpansionLoc());
7865 return Result;
7866}
7867
7868template<typename Derived>
7869QualType TreeTransform<Derived>::TransformDependentNameType(
7870 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7871 return TransformDependentNameType(TLB, TL, false);
7872}
7873
7874template <typename Derived>
7875QualType TreeTransform<Derived>::TransformDependentNameType(
7876 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
7877 QualType ObjectType, NamedDecl *UnqualLookup) {
7878 const DependentNameType *T = TL.getTypePtr();
7879
7880 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7881 if (QualifierLoc) {
7882 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
7883 QualifierLoc, ObjectType, UnqualLookup);
7884 if (!QualifierLoc)
7885 return QualType();
7886 } else {
7887 assert((ObjectType.isNull() && !UnqualLookup) &&
7888 "must be transformed by TransformNestedNameSpecifierLoc");
7889 }
7890
7891 QualType Result
7892 = getDerived().RebuildDependentNameType(T->getKeyword(),
7893 TL.getElaboratedKeywordLoc(),
7894 QualifierLoc,
7895 T->getIdentifier(),
7896 TL.getNameLoc(),
7897 DeducedTSTContext);
7898 if (Result.isNull())
7899 return QualType();
7900
7901 if (isa<TagType>(Val: Result)) {
7902 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
7903 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7904 NewTL.setQualifierLoc(QualifierLoc);
7905 NewTL.setNameLoc(TL.getNameLoc());
7906 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
7907 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7908 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7909 NewTL.setTemplateNameLoc(TL.getNameLoc());
7910 NewTL.setQualifierLoc(QualifierLoc);
7911 } else if (isa<TypedefType>(Val: Result)) {
7912 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7913 QualifierLoc, NameLoc: TL.getNameLoc());
7914 } else if (isa<UnresolvedUsingType>(Val: Result)) {
7915 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
7916 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
7917 } else {
7918 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7919 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7920 NewTL.setQualifierLoc(QualifierLoc);
7921 NewTL.setNameLoc(TL.getNameLoc());
7922 }
7923 return Result;
7924}
7925
7926template<typename Derived>
7927QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7928 PackExpansionTypeLoc TL) {
7929 QualType Pattern
7930 = getDerived().TransformType(TLB, TL.getPatternLoc());
7931 if (Pattern.isNull())
7932 return QualType();
7933
7934 QualType Result = TL.getType();
7935 if (getDerived().AlwaysRebuild() ||
7936 Pattern != TL.getPatternLoc().getType()) {
7937 Result = getDerived().RebuildPackExpansionType(Pattern,
7938 TL.getPatternLoc().getSourceRange(),
7939 TL.getEllipsisLoc(),
7940 TL.getTypePtr()->getNumExpansions());
7941 if (Result.isNull())
7942 return QualType();
7943 }
7944
7945 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7946 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7947 return Result;
7948}
7949
7950template<typename Derived>
7951QualType
7952TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7953 ObjCInterfaceTypeLoc TL) {
7954 // ObjCInterfaceType is never dependent.
7955 TLB.pushFullCopy(L: TL);
7956 return TL.getType();
7957}
7958
7959template<typename Derived>
7960QualType
7961TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7962 ObjCTypeParamTypeLoc TL) {
7963 const ObjCTypeParamType *T = TL.getTypePtr();
7964 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7965 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7966 if (!OTP)
7967 return QualType();
7968
7969 QualType Result = TL.getType();
7970 if (getDerived().AlwaysRebuild() ||
7971 OTP != T->getDecl()) {
7972 Result = getDerived().RebuildObjCTypeParamType(
7973 OTP, TL.getProtocolLAngleLoc(),
7974 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7975 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7976 if (Result.isNull())
7977 return QualType();
7978 }
7979
7980 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7981 if (TL.getNumProtocols()) {
7982 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7983 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7984 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7985 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7986 }
7987 return Result;
7988}
7989
7990template<typename Derived>
7991QualType
7992TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7993 ObjCObjectTypeLoc TL) {
7994 // Transform base type.
7995 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7996 if (BaseType.isNull())
7997 return QualType();
7998
7999 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8000
8001 // Transform type arguments.
8002 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8003 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8004 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8005 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8006 QualType TypeArg = TypeArgInfo->getType();
8007 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8008 AnyChanged = true;
8009
8010 // We have a pack expansion. Instantiate it.
8011 const auto *PackExpansion = PackExpansionLoc.getType()
8012 ->castAs<PackExpansionType>();
8013 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8014 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8015 Unexpanded);
8016 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8017
8018 // Determine whether the set of unexpanded parameter packs can
8019 // and should be expanded.
8020 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8021 bool Expand = false;
8022 bool RetainExpansion = false;
8023 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8024 if (getDerived().TryExpandParameterPacks(
8025 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8026 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8027 RetainExpansion, NumExpansions))
8028 return QualType();
8029
8030 if (!Expand) {
8031 // We can't expand this pack expansion into separate arguments yet;
8032 // just substitute into the pattern and create a new pack expansion
8033 // type.
8034 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8035
8036 TypeLocBuilder TypeArgBuilder;
8037 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8038 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8039 PatternLoc);
8040 if (NewPatternType.isNull())
8041 return QualType();
8042
8043 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8044 Pattern: NewPatternType, NumExpansions);
8045 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8046 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8047 NewTypeArgInfos.push_back(
8048 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8049 continue;
8050 }
8051
8052 // Substitute into the pack expansion pattern for each slice of the
8053 // pack.
8054 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8055 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8056
8057 TypeLocBuilder TypeArgBuilder;
8058 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8059
8060 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8061 PatternLoc);
8062 if (NewTypeArg.isNull())
8063 return QualType();
8064
8065 NewTypeArgInfos.push_back(
8066 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8067 }
8068
8069 continue;
8070 }
8071
8072 TypeLocBuilder TypeArgBuilder;
8073 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8074 QualType NewTypeArg =
8075 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8076 if (NewTypeArg.isNull())
8077 return QualType();
8078
8079 // If nothing changed, just keep the old TypeSourceInfo.
8080 if (NewTypeArg == TypeArg) {
8081 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8082 continue;
8083 }
8084
8085 NewTypeArgInfos.push_back(
8086 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8087 AnyChanged = true;
8088 }
8089
8090 QualType Result = TL.getType();
8091 if (getDerived().AlwaysRebuild() || AnyChanged) {
8092 // Rebuild the type.
8093 Result = getDerived().RebuildObjCObjectType(
8094 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8095 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8096 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8097 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8098
8099 if (Result.isNull())
8100 return QualType();
8101 }
8102
8103 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8104 NewT.setHasBaseTypeAsWritten(true);
8105 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8106 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8107 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8108 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8109 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8110 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8111 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8112 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8113 return Result;
8114}
8115
8116template<typename Derived>
8117QualType
8118TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8119 ObjCObjectPointerTypeLoc TL) {
8120 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8121 if (PointeeType.isNull())
8122 return QualType();
8123
8124 QualType Result = TL.getType();
8125 if (getDerived().AlwaysRebuild() ||
8126 PointeeType != TL.getPointeeLoc().getType()) {
8127 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8128 TL.getStarLoc());
8129 if (Result.isNull())
8130 return QualType();
8131 }
8132
8133 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8134 NewT.setStarLoc(TL.getStarLoc());
8135 return Result;
8136}
8137
8138//===----------------------------------------------------------------------===//
8139// Statement transformation
8140//===----------------------------------------------------------------------===//
8141template<typename Derived>
8142StmtResult
8143TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8144 return S;
8145}
8146
8147template<typename Derived>
8148StmtResult
8149TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8150 return getDerived().TransformCompoundStmt(S, false);
8151}
8152
8153template<typename Derived>
8154StmtResult
8155TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8156 bool IsStmtExpr) {
8157 Sema::CompoundScopeRAII CompoundScope(getSema());
8158 Sema::FPFeaturesStateRAII FPSave(getSema());
8159 if (S->hasStoredFPFeatures())
8160 getSema().resetFPOptions(
8161 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8162
8163 bool SubStmtInvalid = false;
8164 bool SubStmtChanged = false;
8165 SmallVector<Stmt*, 8> Statements;
8166 for (auto *B : S->body()) {
8167 StmtResult Result = getDerived().TransformStmt(
8168 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8169 : StmtDiscardKind::Discarded);
8170
8171 if (Result.isInvalid()) {
8172 // Immediately fail if this was a DeclStmt, since it's very
8173 // likely that this will cause problems for future statements.
8174 if (isa<DeclStmt>(Val: B))
8175 return StmtError();
8176
8177 // Otherwise, just keep processing substatements and fail later.
8178 SubStmtInvalid = true;
8179 continue;
8180 }
8181
8182 SubStmtChanged = SubStmtChanged || Result.get() != B;
8183 Statements.push_back(Elt: Result.getAs<Stmt>());
8184 }
8185
8186 if (SubStmtInvalid)
8187 return StmtError();
8188
8189 if (!getDerived().AlwaysRebuild() &&
8190 !SubStmtChanged)
8191 return S;
8192
8193 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8194 Statements,
8195 S->getRBracLoc(),
8196 IsStmtExpr);
8197}
8198
8199template<typename Derived>
8200StmtResult
8201TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8202 ExprResult LHS, RHS;
8203 {
8204 EnterExpressionEvaluationContext Unevaluated(
8205 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8206
8207 // Transform the left-hand case value.
8208 LHS = getDerived().TransformExpr(S->getLHS());
8209 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8210 if (LHS.isInvalid())
8211 return StmtError();
8212
8213 // Transform the right-hand case value (for the GNU case-range extension).
8214 RHS = getDerived().TransformExpr(S->getRHS());
8215 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8216 if (RHS.isInvalid())
8217 return StmtError();
8218 }
8219
8220 // Build the case statement.
8221 // Case statements are always rebuilt so that they will attached to their
8222 // transformed switch statement.
8223 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8224 LHS.get(),
8225 S->getEllipsisLoc(),
8226 RHS.get(),
8227 S->getColonLoc());
8228 if (Case.isInvalid())
8229 return StmtError();
8230
8231 // Transform the statement following the case
8232 StmtResult SubStmt =
8233 getDerived().TransformStmt(S->getSubStmt());
8234 if (SubStmt.isInvalid())
8235 return StmtError();
8236
8237 // Attach the body to the case statement
8238 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8239}
8240
8241template <typename Derived>
8242StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8243 // Transform the statement following the default case
8244 StmtResult SubStmt =
8245 getDerived().TransformStmt(S->getSubStmt());
8246 if (SubStmt.isInvalid())
8247 return StmtError();
8248
8249 // Default statements are always rebuilt
8250 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8251 SubStmt.get());
8252}
8253
8254template<typename Derived>
8255StmtResult
8256TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8257 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8258 if (SubStmt.isInvalid())
8259 return StmtError();
8260
8261 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8262 S->getDecl());
8263 if (!LD)
8264 return StmtError();
8265
8266 // If we're transforming "in-place" (we're not creating new local
8267 // declarations), assume we're replacing the old label statement
8268 // and clear out the reference to it.
8269 if (LD == S->getDecl())
8270 S->getDecl()->setStmt(nullptr);
8271
8272 // FIXME: Pass the real colon location in.
8273 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8274 cast<LabelDecl>(Val: LD), SourceLocation(),
8275 SubStmt.get());
8276}
8277
8278template <typename Derived>
8279const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8280 if (!R)
8281 return R;
8282
8283 switch (R->getKind()) {
8284// Transform attributes by calling TransformXXXAttr.
8285#define ATTR(X) \
8286 case attr::X: \
8287 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8288#include "clang/Basic/AttrList.inc"
8289 }
8290 return R;
8291}
8292
8293template <typename Derived>
8294const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8295 const Stmt *InstS,
8296 const Attr *R) {
8297 if (!R)
8298 return R;
8299
8300 switch (R->getKind()) {
8301// Transform attributes by calling TransformStmtXXXAttr.
8302#define ATTR(X) \
8303 case attr::X: \
8304 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8305#include "clang/Basic/AttrList.inc"
8306 }
8307 return TransformAttr(R);
8308}
8309
8310template <typename Derived>
8311StmtResult
8312TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8313 StmtDiscardKind SDK) {
8314 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8315 if (SubStmt.isInvalid())
8316 return StmtError();
8317
8318 bool AttrsChanged = false;
8319 SmallVector<const Attr *, 1> Attrs;
8320
8321 // Visit attributes and keep track if any are transformed.
8322 for (const auto *I : S->getAttrs()) {
8323 const Attr *R =
8324 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8325 AttrsChanged |= (I != R);
8326 if (R)
8327 Attrs.push_back(Elt: R);
8328 }
8329
8330 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8331 return S;
8332
8333 // If transforming the attributes failed for all of the attributes in the
8334 // statement, don't make an AttributedStmt without attributes.
8335 if (Attrs.empty())
8336 return SubStmt;
8337
8338 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8339 SubStmt.get());
8340}
8341
8342template<typename Derived>
8343StmtResult
8344TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8345 // Transform the initialization statement
8346 StmtResult Init = getDerived().TransformStmt(S->getInit());
8347 if (Init.isInvalid())
8348 return StmtError();
8349
8350 Sema::ConditionResult Cond;
8351 if (!S->isConsteval()) {
8352 // Transform the condition
8353 Cond = getDerived().TransformCondition(
8354 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8355 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8356 : Sema::ConditionKind::Boolean);
8357 if (Cond.isInvalid())
8358 return StmtError();
8359 }
8360
8361 // If this is a constexpr if, determine which arm we should instantiate.
8362 std::optional<bool> ConstexprConditionValue;
8363 if (S->isConstexpr())
8364 ConstexprConditionValue = Cond.getKnownValue();
8365
8366 // Transform the "then" branch.
8367 StmtResult Then;
8368 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8369 EnterExpressionEvaluationContext Ctx(
8370 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8371 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8372 S->isNonNegatedConsteval());
8373
8374 Then = getDerived().TransformStmt(S->getThen());
8375 if (Then.isInvalid())
8376 return StmtError();
8377 } else {
8378 // Discarded branch is replaced with empty CompoundStmt so we can keep
8379 // proper source location for start and end of original branch, so
8380 // subsequent transformations like CoverageMapping work properly
8381 Then = new (getSema().Context)
8382 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8383 }
8384
8385 // Transform the "else" branch.
8386 StmtResult Else;
8387 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8388 EnterExpressionEvaluationContext Ctx(
8389 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8390 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8391 S->isNegatedConsteval());
8392
8393 Else = getDerived().TransformStmt(S->getElse());
8394 if (Else.isInvalid())
8395 return StmtError();
8396 } else if (S->getElse() && ConstexprConditionValue &&
8397 *ConstexprConditionValue) {
8398 // Same thing here as with <then> branch, we are discarding it, we can't
8399 // replace it with NULL nor NullStmt as we need to keep for source location
8400 // range, for CoverageMapping
8401 Else = new (getSema().Context)
8402 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8403 }
8404
8405 if (!getDerived().AlwaysRebuild() &&
8406 Init.get() == S->getInit() &&
8407 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8408 Then.get() == S->getThen() &&
8409 Else.get() == S->getElse())
8410 return S;
8411
8412 return getDerived().RebuildIfStmt(
8413 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8414 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8415}
8416
8417template<typename Derived>
8418StmtResult
8419TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8420 // Transform the initialization statement
8421 StmtResult Init = getDerived().TransformStmt(S->getInit());
8422 if (Init.isInvalid())
8423 return StmtError();
8424
8425 // Transform the condition.
8426 Sema::ConditionResult Cond = getDerived().TransformCondition(
8427 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8428 Sema::ConditionKind::Switch);
8429 if (Cond.isInvalid())
8430 return StmtError();
8431
8432 // Rebuild the switch statement.
8433 StmtResult Switch =
8434 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8435 Init.get(), Cond, S->getRParenLoc());
8436 if (Switch.isInvalid())
8437 return StmtError();
8438
8439 // Transform the body of the switch statement.
8440 StmtResult Body = getDerived().TransformStmt(S->getBody());
8441 if (Body.isInvalid())
8442 return StmtError();
8443
8444 // Complete the switch statement.
8445 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8446 Body.get());
8447}
8448
8449template<typename Derived>
8450StmtResult
8451TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8452 // Transform the condition
8453 Sema::ConditionResult Cond = getDerived().TransformCondition(
8454 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8455 Sema::ConditionKind::Boolean);
8456 if (Cond.isInvalid())
8457 return StmtError();
8458
8459 // OpenACC Restricts a while-loop inside of certain construct/clause
8460 // combinations, so diagnose that here in OpenACC mode.
8461 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8462 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8463
8464 // Transform the body
8465 StmtResult Body = getDerived().TransformStmt(S->getBody());
8466 if (Body.isInvalid())
8467 return StmtError();
8468
8469 if (!getDerived().AlwaysRebuild() &&
8470 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8471 Body.get() == S->getBody())
8472 return Owned(S);
8473
8474 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8475 Cond, S->getRParenLoc(), Body.get());
8476}
8477
8478template<typename Derived>
8479StmtResult
8480TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8481 // OpenACC Restricts a do-loop inside of certain construct/clause
8482 // combinations, so diagnose that here in OpenACC mode.
8483 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8484 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8485
8486 // Transform the body
8487 StmtResult Body = getDerived().TransformStmt(S->getBody());
8488 if (Body.isInvalid())
8489 return StmtError();
8490
8491 // Transform the condition
8492 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8493 if (Cond.isInvalid())
8494 return StmtError();
8495
8496 if (!getDerived().AlwaysRebuild() &&
8497 Cond.get() == S->getCond() &&
8498 Body.get() == S->getBody())
8499 return S;
8500
8501 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8502 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8503 S->getRParenLoc());
8504}
8505
8506template<typename Derived>
8507StmtResult
8508TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8509 if (getSema().getLangOpts().OpenMP)
8510 getSema().OpenMP().startOpenMPLoop();
8511
8512 // Transform the initialization statement
8513 StmtResult Init = getDerived().TransformStmt(S->getInit());
8514 if (Init.isInvalid())
8515 return StmtError();
8516
8517 // In OpenMP loop region loop control variable must be captured and be
8518 // private. Perform analysis of first part (if any).
8519 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8520 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8521 Init.get());
8522
8523 // Transform the condition
8524 Sema::ConditionResult Cond = getDerived().TransformCondition(
8525 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8526 Sema::ConditionKind::Boolean);
8527 if (Cond.isInvalid())
8528 return StmtError();
8529
8530 // Transform the increment
8531 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8532 if (Inc.isInvalid())
8533 return StmtError();
8534
8535 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8536 if (S->getInc() && !FullInc.get())
8537 return StmtError();
8538
8539 // OpenACC Restricts a for-loop inside of certain construct/clause
8540 // combinations, so diagnose that here in OpenACC mode.
8541 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8542 SemaRef.OpenACC().ActOnForStmtBegin(
8543 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8544 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8545
8546 // Transform the body
8547 StmtResult Body = getDerived().TransformStmt(S->getBody());
8548 if (Body.isInvalid())
8549 return StmtError();
8550
8551 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8552
8553 if (!getDerived().AlwaysRebuild() &&
8554 Init.get() == S->getInit() &&
8555 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8556 Inc.get() == S->getInc() &&
8557 Body.get() == S->getBody())
8558 return S;
8559
8560 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8561 Init.get(), Cond, FullInc,
8562 S->getRParenLoc(), Body.get());
8563}
8564
8565template<typename Derived>
8566StmtResult
8567TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8568 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8569 S->getLabel());
8570 if (!LD)
8571 return StmtError();
8572
8573 // Goto statements must always be rebuilt, to resolve the label.
8574 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8575 cast<LabelDecl>(Val: LD));
8576}
8577
8578template<typename Derived>
8579StmtResult
8580TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8581 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8582 if (Target.isInvalid())
8583 return StmtError();
8584 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8585
8586 if (!getDerived().AlwaysRebuild() &&
8587 Target.get() == S->getTarget())
8588 return S;
8589
8590 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8591 Target.get());
8592}
8593
8594template<typename Derived>
8595StmtResult
8596TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8597 if (!S->hasLabelTarget())
8598 return S;
8599
8600 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8601 S->getLabelDecl());
8602 if (!LD)
8603 return StmtError();
8604
8605 return new (SemaRef.Context)
8606 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8607}
8608
8609template<typename Derived>
8610StmtResult
8611TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8612 if (!S->hasLabelTarget())
8613 return S;
8614
8615 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8616 S->getLabelDecl());
8617 if (!LD)
8618 return StmtError();
8619
8620 return new (SemaRef.Context)
8621 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8622}
8623
8624template <typename Derived>
8625StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8626 StmtResult Result = getDerived().TransformStmt(S->getBody());
8627 if (!Result.isUsable())
8628 return StmtError();
8629 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8630}
8631
8632template<typename Derived>
8633StmtResult
8634TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8635 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8636 /*NotCopyInit*/false);
8637 if (Result.isInvalid())
8638 return StmtError();
8639
8640 // FIXME: We always rebuild the return statement because there is no way
8641 // to tell whether the return type of the function has changed.
8642 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8643}
8644
8645template<typename Derived>
8646StmtResult
8647TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8648 bool DeclChanged = false;
8649 SmallVector<Decl *, 4> Decls;
8650 LambdaScopeInfo *LSI = getSema().getCurLambda();
8651 for (auto *D : S->decls()) {
8652 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8653 if (!Transformed)
8654 return StmtError();
8655
8656 if (Transformed != D)
8657 DeclChanged = true;
8658
8659 if (LSI) {
8660 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8661 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8662 LSI->ContainsUnexpandedParameterPack |=
8663 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8664 } else {
8665 LSI->ContainsUnexpandedParameterPack |=
8666 getSema()
8667 .getASTContext()
8668 .getTypeDeclType(TD)
8669 ->containsUnexpandedParameterPack();
8670 }
8671 }
8672 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8673 LSI->ContainsUnexpandedParameterPack |=
8674 VD->getType()->containsUnexpandedParameterPack();
8675 }
8676
8677 Decls.push_back(Elt: Transformed);
8678 }
8679
8680 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8681 return S;
8682
8683 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8684}
8685
8686template<typename Derived>
8687StmtResult
8688TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8689
8690 SmallVector<Expr*, 8> Constraints;
8691 SmallVector<Expr*, 8> Exprs;
8692 SmallVector<IdentifierInfo *, 4> Names;
8693
8694 SmallVector<Expr*, 8> Clobbers;
8695
8696 bool ExprsChanged = false;
8697
8698 auto RebuildString = [&](Expr *E) {
8699 ExprResult Result = getDerived().TransformExpr(E);
8700 if (!Result.isUsable())
8701 return Result;
8702 if (Result.get() != E) {
8703 ExprsChanged = true;
8704 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8705 }
8706 return Result;
8707 };
8708
8709 // Go through the outputs.
8710 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8711 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8712
8713 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8714 if (Result.isInvalid())
8715 return StmtError();
8716
8717 Constraints.push_back(Elt: Result.get());
8718
8719 // Transform the output expr.
8720 Expr *OutputExpr = S->getOutputExpr(i: I);
8721 Result = getDerived().TransformExpr(OutputExpr);
8722 if (Result.isInvalid())
8723 return StmtError();
8724
8725 ExprsChanged |= Result.get() != OutputExpr;
8726
8727 Exprs.push_back(Elt: Result.get());
8728 }
8729
8730 // Go through the inputs.
8731 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8732 Names.push_back(Elt: S->getInputIdentifier(i: I));
8733
8734 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8735 if (Result.isInvalid())
8736 return StmtError();
8737
8738 Constraints.push_back(Elt: Result.get());
8739
8740 // Transform the input expr.
8741 Expr *InputExpr = S->getInputExpr(i: I);
8742 Result = getDerived().TransformExpr(InputExpr);
8743 if (Result.isInvalid())
8744 return StmtError();
8745
8746 ExprsChanged |= Result.get() != InputExpr;
8747
8748 Exprs.push_back(Elt: Result.get());
8749 }
8750
8751 // Go through the Labels.
8752 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8753 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8754
8755 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8756 if (Result.isInvalid())
8757 return StmtError();
8758 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8759 Exprs.push_back(Elt: Result.get());
8760 }
8761
8762 // Go through the clobbers.
8763 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8764 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8765 if (Result.isInvalid())
8766 return StmtError();
8767 Clobbers.push_back(Elt: Result.get());
8768 }
8769
8770 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8771 if (AsmString.isInvalid())
8772 return StmtError();
8773
8774 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8775 return S;
8776
8777 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8778 S->isVolatile(), S->getNumOutputs(),
8779 S->getNumInputs(), Names.data(),
8780 Constraints, Exprs, AsmString.get(),
8781 Clobbers, S->getNumLabels(),
8782 S->getRParenLoc());
8783}
8784
8785template<typename Derived>
8786StmtResult
8787TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8788 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8789
8790 bool HadError = false, HadChange = false;
8791
8792 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8793 SmallVector<Expr*, 8> TransformedExprs;
8794 TransformedExprs.reserve(N: SrcExprs.size());
8795 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8796 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8797 if (!Result.isUsable()) {
8798 HadError = true;
8799 } else {
8800 HadChange |= (Result.get() != SrcExprs[i]);
8801 TransformedExprs.push_back(Elt: Result.get());
8802 }
8803 }
8804
8805 if (HadError) return StmtError();
8806 if (!HadChange && !getDerived().AlwaysRebuild())
8807 return Owned(S);
8808
8809 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8810 AsmToks, S->getAsmString(),
8811 S->getNumOutputs(), S->getNumInputs(),
8812 S->getAllConstraints(), S->getClobbers(),
8813 TransformedExprs, S->getEndLoc());
8814}
8815
8816// C++ Coroutines
8817template<typename Derived>
8818StmtResult
8819TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8820 auto *ScopeInfo = SemaRef.getCurFunction();
8821 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8822 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8823 ScopeInfo->NeedsCoroutineSuspends &&
8824 ScopeInfo->CoroutineSuspends.first == nullptr &&
8825 ScopeInfo->CoroutineSuspends.second == nullptr &&
8826 "expected clean scope info");
8827
8828 // Set that we have (possibly-invalid) suspend points before we do anything
8829 // that may fail.
8830 ScopeInfo->setNeedsCoroutineSuspends(false);
8831
8832 // We re-build the coroutine promise object (and the coroutine parameters its
8833 // type and constructor depend on) based on the types used in our current
8834 // function. We must do so, and set it on the current FunctionScopeInfo,
8835 // before attempting to transform the other parts of the coroutine body
8836 // statement, such as the implicit suspend statements (because those
8837 // statements reference the FunctionScopeInfo::CoroutinePromise).
8838 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8839 return StmtError();
8840 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8841 if (!Promise)
8842 return StmtError();
8843 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8844 ScopeInfo->CoroutinePromise = Promise;
8845
8846 // Transform the implicit coroutine statements constructed using dependent
8847 // types during the previous parse: initial and final suspensions, the return
8848 // object, and others. We also transform the coroutine function's body.
8849 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8850 if (InitSuspend.isInvalid())
8851 return StmtError();
8852 StmtResult FinalSuspend =
8853 getDerived().TransformStmt(S->getFinalSuspendStmt());
8854 if (FinalSuspend.isInvalid() ||
8855 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8856 return StmtError();
8857 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8858 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8859
8860 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8861 if (BodyRes.isInvalid())
8862 return StmtError();
8863
8864 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8865 if (Builder.isInvalid())
8866 return StmtError();
8867
8868 Expr *ReturnObject = S->getReturnValueInit();
8869 assert(ReturnObject && "the return object is expected to be valid");
8870 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8871 /*NoCopyInit*/ false);
8872 if (Res.isInvalid())
8873 return StmtError();
8874 Builder.ReturnValue = Res.get();
8875
8876 // If during the previous parse the coroutine still had a dependent promise
8877 // statement, we may need to build some implicit coroutine statements
8878 // (such as exception and fallthrough handlers) for the first time.
8879 if (S->hasDependentPromiseType()) {
8880 // We can only build these statements, however, if the current promise type
8881 // is not dependent.
8882 if (!Promise->getType()->isDependentType()) {
8883 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8884 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8885 "these nodes should not have been built yet");
8886 if (!Builder.buildDependentStatements())
8887 return StmtError();
8888 }
8889 } else {
8890 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8891 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8892 if (Res.isInvalid())
8893 return StmtError();
8894 Builder.OnFallthrough = Res.get();
8895 }
8896
8897 if (auto *OnException = S->getExceptionHandler()) {
8898 StmtResult Res = getDerived().TransformStmt(OnException);
8899 if (Res.isInvalid())
8900 return StmtError();
8901 Builder.OnException = Res.get();
8902 }
8903
8904 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8905 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8906 if (Res.isInvalid())
8907 return StmtError();
8908 Builder.ReturnStmtOnAllocFailure = Res.get();
8909 }
8910
8911 // Transform any additional statements we may have already built
8912 assert(S->getAllocate() && S->getDeallocate() &&
8913 "allocation and deallocation calls must already be built");
8914 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8915 if (AllocRes.isInvalid())
8916 return StmtError();
8917 Builder.Allocate = AllocRes.get();
8918
8919 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8920 if (DeallocRes.isInvalid())
8921 return StmtError();
8922 Builder.Deallocate = DeallocRes.get();
8923
8924 if (auto *ResultDecl = S->getResultDecl()) {
8925 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8926 if (Res.isInvalid())
8927 return StmtError();
8928 Builder.ResultDecl = Res.get();
8929 }
8930
8931 if (auto *ReturnStmt = S->getReturnStmt()) {
8932 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8933 if (Res.isInvalid())
8934 return StmtError();
8935 Builder.ReturnStmt = Res.get();
8936 }
8937 }
8938
8939 return getDerived().RebuildCoroutineBodyStmt(Builder);
8940}
8941
8942template<typename Derived>
8943StmtResult
8944TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8945 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8946 /*NotCopyInit*/false);
8947 if (Result.isInvalid())
8948 return StmtError();
8949
8950 // Always rebuild; we don't know if this needs to be injected into a new
8951 // context or if the promise type has changed.
8952 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8953 S->isImplicit());
8954}
8955
8956template <typename Derived>
8957ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8958 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8959 /*NotCopyInit*/ false);
8960 if (Operand.isInvalid())
8961 return ExprError();
8962
8963 // Rebuild the common-expr from the operand rather than transforming it
8964 // separately.
8965
8966 // FIXME: getCurScope() should not be used during template instantiation.
8967 // We should pick up the set of unqualified lookup results for operator
8968 // co_await during the initial parse.
8969 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8970 getSema().getCurScope(), E->getKeywordLoc());
8971
8972 // Always rebuild; we don't know if this needs to be injected into a new
8973 // context or if the promise type has changed.
8974 return getDerived().RebuildCoawaitExpr(
8975 E->getKeywordLoc(), Operand.get(),
8976 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8977}
8978
8979template <typename Derived>
8980ExprResult
8981TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8982 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8983 /*NotCopyInit*/ false);
8984 if (OperandResult.isInvalid())
8985 return ExprError();
8986
8987 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8988 E->getOperatorCoawaitLookup());
8989
8990 if (LookupResult.isInvalid())
8991 return ExprError();
8992
8993 // Always rebuild; we don't know if this needs to be injected into a new
8994 // context or if the promise type has changed.
8995 return getDerived().RebuildDependentCoawaitExpr(
8996 E->getKeywordLoc(), OperandResult.get(),
8997 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8998}
8999
9000template<typename Derived>
9001ExprResult
9002TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9003 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9004 /*NotCopyInit*/false);
9005 if (Result.isInvalid())
9006 return ExprError();
9007
9008 // Always rebuild; we don't know if this needs to be injected into a new
9009 // context or if the promise type has changed.
9010 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9011}
9012
9013// Objective-C Statements.
9014
9015template<typename Derived>
9016StmtResult
9017TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9018 // Transform the body of the @try.
9019 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9020 if (TryBody.isInvalid())
9021 return StmtError();
9022
9023 // Transform the @catch statements (if present).
9024 bool AnyCatchChanged = false;
9025 SmallVector<Stmt*, 8> CatchStmts;
9026 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9027 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9028 if (Catch.isInvalid())
9029 return StmtError();
9030 if (Catch.get() != S->getCatchStmt(I))
9031 AnyCatchChanged = true;
9032 CatchStmts.push_back(Elt: Catch.get());
9033 }
9034
9035 // Transform the @finally statement (if present).
9036 StmtResult Finally;
9037 if (S->getFinallyStmt()) {
9038 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9039 if (Finally.isInvalid())
9040 return StmtError();
9041 }
9042
9043 // If nothing changed, just retain this statement.
9044 if (!getDerived().AlwaysRebuild() &&
9045 TryBody.get() == S->getTryBody() &&
9046 !AnyCatchChanged &&
9047 Finally.get() == S->getFinallyStmt())
9048 return S;
9049
9050 // Build a new statement.
9051 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9052 CatchStmts, Finally.get());
9053}
9054
9055template<typename Derived>
9056StmtResult
9057TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9058 // Transform the @catch parameter, if there is one.
9059 VarDecl *Var = nullptr;
9060 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9061 TypeSourceInfo *TSInfo = nullptr;
9062 if (FromVar->getTypeSourceInfo()) {
9063 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9064 if (!TSInfo)
9065 return StmtError();
9066 }
9067
9068 QualType T;
9069 if (TSInfo)
9070 T = TSInfo->getType();
9071 else {
9072 T = getDerived().TransformType(FromVar->getType());
9073 if (T.isNull())
9074 return StmtError();
9075 }
9076
9077 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9078 if (!Var)
9079 return StmtError();
9080 }
9081
9082 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9083 if (Body.isInvalid())
9084 return StmtError();
9085
9086 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9087 S->getRParenLoc(),
9088 Var, Body.get());
9089}
9090
9091template<typename Derived>
9092StmtResult
9093TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9094 // Transform the body.
9095 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9096 if (Body.isInvalid())
9097 return StmtError();
9098
9099 // If nothing changed, just retain this statement.
9100 if (!getDerived().AlwaysRebuild() &&
9101 Body.get() == S->getFinallyBody())
9102 return S;
9103
9104 // Build a new statement.
9105 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9106 Body.get());
9107}
9108
9109template<typename Derived>
9110StmtResult
9111TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9112 ExprResult Operand;
9113 if (S->getThrowExpr()) {
9114 Operand = getDerived().TransformExpr(S->getThrowExpr());
9115 if (Operand.isInvalid())
9116 return StmtError();
9117 }
9118
9119 if (!getDerived().AlwaysRebuild() &&
9120 Operand.get() == S->getThrowExpr())
9121 return S;
9122
9123 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9124}
9125
9126template<typename Derived>
9127StmtResult
9128TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9129 ObjCAtSynchronizedStmt *S) {
9130 // Transform the object we are locking.
9131 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9132 if (Object.isInvalid())
9133 return StmtError();
9134 Object =
9135 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9136 Object.get());
9137 if (Object.isInvalid())
9138 return StmtError();
9139
9140 // Transform the body.
9141 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9142 if (Body.isInvalid())
9143 return StmtError();
9144
9145 // If nothing change, just retain the current statement.
9146 if (!getDerived().AlwaysRebuild() &&
9147 Object.get() == S->getSynchExpr() &&
9148 Body.get() == S->getSynchBody())
9149 return S;
9150
9151 // Build a new statement.
9152 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9153 Object.get(), Body.get());
9154}
9155
9156template<typename Derived>
9157StmtResult
9158TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9159 ObjCAutoreleasePoolStmt *S) {
9160 // Transform the body.
9161 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9162 if (Body.isInvalid())
9163 return StmtError();
9164
9165 // If nothing changed, just retain this statement.
9166 if (!getDerived().AlwaysRebuild() &&
9167 Body.get() == S->getSubStmt())
9168 return S;
9169
9170 // Build a new statement.
9171 return getDerived().RebuildObjCAutoreleasePoolStmt(
9172 S->getAtLoc(), Body.get());
9173}
9174
9175template<typename Derived>
9176StmtResult
9177TreeTransform<Derived>::TransformObjCForCollectionStmt(
9178 ObjCForCollectionStmt *S) {
9179 // Transform the element statement.
9180 StmtResult Element = getDerived().TransformStmt(
9181 S->getElement(), StmtDiscardKind::NotDiscarded);
9182 if (Element.isInvalid())
9183 return StmtError();
9184
9185 // Transform the collection expression.
9186 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9187 if (Collection.isInvalid())
9188 return StmtError();
9189
9190 // Transform the body.
9191 StmtResult Body = getDerived().TransformStmt(S->getBody());
9192 if (Body.isInvalid())
9193 return StmtError();
9194
9195 // If nothing changed, just retain this statement.
9196 if (!getDerived().AlwaysRebuild() &&
9197 Element.get() == S->getElement() &&
9198 Collection.get() == S->getCollection() &&
9199 Body.get() == S->getBody())
9200 return S;
9201
9202 // Build a new statement.
9203 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9204 Element.get(),
9205 Collection.get(),
9206 S->getRParenLoc(),
9207 Body.get());
9208}
9209
9210template <typename Derived>
9211StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9212 // Transform the exception declaration, if any.
9213 VarDecl *Var = nullptr;
9214 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9215 TypeSourceInfo *T =
9216 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9217 if (!T)
9218 return StmtError();
9219
9220 Var = getDerived().RebuildExceptionDecl(
9221 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9222 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9223 if (!Var || Var->isInvalidDecl())
9224 return StmtError();
9225 }
9226
9227 // Transform the actual exception handler.
9228 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9229 if (Handler.isInvalid())
9230 return StmtError();
9231
9232 if (!getDerived().AlwaysRebuild() && !Var &&
9233 Handler.get() == S->getHandlerBlock())
9234 return S;
9235
9236 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9237}
9238
9239template <typename Derived>
9240StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9241 // Transform the try block itself.
9242 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9243 if (TryBlock.isInvalid())
9244 return StmtError();
9245
9246 // Transform the handlers.
9247 bool HandlerChanged = false;
9248 SmallVector<Stmt *, 8> Handlers;
9249 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9250 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9251 if (Handler.isInvalid())
9252 return StmtError();
9253
9254 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9255 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9256 }
9257
9258 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9259
9260 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9261 !HandlerChanged)
9262 return S;
9263
9264 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9265 Handlers);
9266}
9267
9268template<typename Derived>
9269StmtResult
9270TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9271 EnterExpressionEvaluationContext ForRangeInitContext(
9272 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9273 /*LambdaContextDecl=*/nullptr,
9274 Sema::ExpressionEvaluationContextRecord::EK_Other,
9275 getSema().getLangOpts().CPlusPlus23);
9276
9277 // P2718R0 - Lifetime extension in range-based for loops.
9278 if (getSema().getLangOpts().CPlusPlus23) {
9279 auto &LastRecord = getSema().currentEvaluationContext();
9280 LastRecord.InLifetimeExtendingContext = true;
9281 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9282 }
9283 StmtResult Init =
9284 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9285 if (Init.isInvalid())
9286 return StmtError();
9287
9288 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9289 if (Range.isInvalid())
9290 return StmtError();
9291
9292 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9293 assert(getSema().getLangOpts().CPlusPlus23 ||
9294 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9295 auto ForRangeLifetimeExtendTemps =
9296 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9297
9298 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9299 if (Begin.isInvalid())
9300 return StmtError();
9301 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9302 if (End.isInvalid())
9303 return StmtError();
9304
9305 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9306 if (Cond.isInvalid())
9307 return StmtError();
9308 if (Cond.get())
9309 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9310 if (Cond.isInvalid())
9311 return StmtError();
9312 if (Cond.get())
9313 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9314
9315 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9316 if (Inc.isInvalid())
9317 return StmtError();
9318 if (Inc.get())
9319 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9320
9321 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9322 if (LoopVar.isInvalid())
9323 return StmtError();
9324
9325 StmtResult NewStmt = S;
9326 if (getDerived().AlwaysRebuild() ||
9327 Init.get() != S->getInit() ||
9328 Range.get() != S->getRangeStmt() ||
9329 Begin.get() != S->getBeginStmt() ||
9330 End.get() != S->getEndStmt() ||
9331 Cond.get() != S->getCond() ||
9332 Inc.get() != S->getInc() ||
9333 LoopVar.get() != S->getLoopVarStmt()) {
9334 NewStmt = getDerived().RebuildCXXForRangeStmt(
9335 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9336 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9337 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9338 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9339 // Might not have attached any initializer to the loop variable.
9340 getSema().ActOnInitializerError(
9341 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9342 return StmtError();
9343 }
9344 }
9345
9346 // OpenACC Restricts a while-loop inside of certain construct/clause
9347 // combinations, so diagnose that here in OpenACC mode.
9348 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9349 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9350
9351 StmtResult Body = getDerived().TransformStmt(S->getBody());
9352 if (Body.isInvalid())
9353 return StmtError();
9354
9355 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9356
9357 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9358 // it now so we have a new statement to attach the body to.
9359 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9360 NewStmt = getDerived().RebuildCXXForRangeStmt(
9361 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9362 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9363 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9364 if (NewStmt.isInvalid())
9365 return StmtError();
9366 }
9367
9368 if (NewStmt.get() == S)
9369 return S;
9370
9371 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9372}
9373
9374template<typename Derived>
9375StmtResult
9376TreeTransform<Derived>::TransformMSDependentExistsStmt(
9377 MSDependentExistsStmt *S) {
9378 // Transform the nested-name-specifier, if any.
9379 NestedNameSpecifierLoc QualifierLoc;
9380 if (S->getQualifierLoc()) {
9381 QualifierLoc
9382 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9383 if (!QualifierLoc)
9384 return StmtError();
9385 }
9386
9387 // Transform the declaration name.
9388 DeclarationNameInfo NameInfo = S->getNameInfo();
9389 if (NameInfo.getName()) {
9390 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9391 if (!NameInfo.getName())
9392 return StmtError();
9393 }
9394
9395 // Check whether anything changed.
9396 if (!getDerived().AlwaysRebuild() &&
9397 QualifierLoc == S->getQualifierLoc() &&
9398 NameInfo.getName() == S->getNameInfo().getName())
9399 return S;
9400
9401 // Determine whether this name exists, if we can.
9402 CXXScopeSpec SS;
9403 SS.Adopt(Other: QualifierLoc);
9404 bool Dependent = false;
9405 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9406 case IfExistsResult::Exists:
9407 if (S->isIfExists())
9408 break;
9409
9410 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9411
9412 case IfExistsResult::DoesNotExist:
9413 if (S->isIfNotExists())
9414 break;
9415
9416 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9417
9418 case IfExistsResult::Dependent:
9419 Dependent = true;
9420 break;
9421
9422 case IfExistsResult::Error:
9423 return StmtError();
9424 }
9425
9426 // We need to continue with the instantiation, so do so now.
9427 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9428 if (SubStmt.isInvalid())
9429 return StmtError();
9430
9431 // If we have resolved the name, just transform to the substatement.
9432 if (!Dependent)
9433 return SubStmt;
9434
9435 // The name is still dependent, so build a dependent expression again.
9436 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9437 S->isIfExists(),
9438 QualifierLoc,
9439 NameInfo,
9440 SubStmt.get());
9441}
9442
9443template<typename Derived>
9444ExprResult
9445TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9446 NestedNameSpecifierLoc QualifierLoc;
9447 if (E->getQualifierLoc()) {
9448 QualifierLoc
9449 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9450 if (!QualifierLoc)
9451 return ExprError();
9452 }
9453
9454 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9455 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9456 if (!PD)
9457 return ExprError();
9458
9459 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9460 if (Base.isInvalid())
9461 return ExprError();
9462
9463 return new (SemaRef.getASTContext())
9464 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9465 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9466 QualifierLoc, E->getMemberLoc());
9467}
9468
9469template <typename Derived>
9470ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9471 MSPropertySubscriptExpr *E) {
9472 auto BaseRes = getDerived().TransformExpr(E->getBase());
9473 if (BaseRes.isInvalid())
9474 return ExprError();
9475 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9476 if (IdxRes.isInvalid())
9477 return ExprError();
9478
9479 if (!getDerived().AlwaysRebuild() &&
9480 BaseRes.get() == E->getBase() &&
9481 IdxRes.get() == E->getIdx())
9482 return E;
9483
9484 return getDerived().RebuildArraySubscriptExpr(
9485 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9486}
9487
9488template <typename Derived>
9489StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9490 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9491 if (TryBlock.isInvalid())
9492 return StmtError();
9493
9494 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9495 if (Handler.isInvalid())
9496 return StmtError();
9497
9498 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9499 Handler.get() == S->getHandler())
9500 return S;
9501
9502 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9503 TryBlock.get(), Handler.get());
9504}
9505
9506template <typename Derived>
9507StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9508 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9509 if (Block.isInvalid())
9510 return StmtError();
9511
9512 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9513}
9514
9515template <typename Derived>
9516StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9517 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9518 if (FilterExpr.isInvalid())
9519 return StmtError();
9520
9521 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9522 if (Block.isInvalid())
9523 return StmtError();
9524
9525 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9526 Block.get());
9527}
9528
9529template <typename Derived>
9530StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9531 if (isa<SEHFinallyStmt>(Val: Handler))
9532 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9533 else
9534 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9535}
9536
9537template<typename Derived>
9538StmtResult
9539TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9540 return S;
9541}
9542
9543//===----------------------------------------------------------------------===//
9544// OpenMP directive transformation
9545//===----------------------------------------------------------------------===//
9546
9547template <typename Derived>
9548StmtResult
9549TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9550 // OMPCanonicalLoops are eliminated during transformation, since they will be
9551 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9552 // after transformation.
9553 return getDerived().TransformStmt(L->getLoopStmt());
9554}
9555
9556template <typename Derived>
9557StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9558 OMPExecutableDirective *D) {
9559
9560 // Transform the clauses
9561 llvm::SmallVector<OMPClause *, 16> TClauses;
9562 ArrayRef<OMPClause *> Clauses = D->clauses();
9563 TClauses.reserve(N: Clauses.size());
9564 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9565 I != E; ++I) {
9566 if (*I) {
9567 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9568 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9569 getDerived().getSema().OpenMP().EndOpenMPClause();
9570 if (Clause)
9571 TClauses.push_back(Elt: Clause);
9572 } else {
9573 TClauses.push_back(Elt: nullptr);
9574 }
9575 }
9576 StmtResult AssociatedStmt;
9577 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9578 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9579 D->getDirectiveKind(),
9580 /*CurScope=*/nullptr);
9581 StmtResult Body;
9582 {
9583 Sema::CompoundScopeRAII CompoundScope(getSema());
9584 Stmt *CS;
9585 if (D->getDirectiveKind() == OMPD_atomic ||
9586 D->getDirectiveKind() == OMPD_critical ||
9587 D->getDirectiveKind() == OMPD_section ||
9588 D->getDirectiveKind() == OMPD_master)
9589 CS = D->getAssociatedStmt();
9590 else
9591 CS = D->getRawStmt();
9592 Body = getDerived().TransformStmt(CS);
9593 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9594 getSema().getLangOpts().OpenMPIRBuilder)
9595 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9596 }
9597 AssociatedStmt =
9598 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9599 if (AssociatedStmt.isInvalid()) {
9600 return StmtError();
9601 }
9602 }
9603 if (TClauses.size() != Clauses.size()) {
9604 return StmtError();
9605 }
9606
9607 // Transform directive name for 'omp critical' directive.
9608 DeclarationNameInfo DirName;
9609 if (D->getDirectiveKind() == OMPD_critical) {
9610 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9611 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9612 }
9613 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9614 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9615 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9616 } else if (D->getDirectiveKind() == OMPD_cancel) {
9617 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9618 }
9619
9620 return getDerived().RebuildOMPExecutableDirective(
9621 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9622 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9623}
9624
9625/// This is mostly the same as above, but allows 'informational' class
9626/// directives when rebuilding the stmt. It still takes an
9627/// OMPExecutableDirective-type argument because we're reusing that as the
9628/// superclass for the 'assume' directive at present, instead of defining a
9629/// mostly-identical OMPInformationalDirective parent class.
9630template <typename Derived>
9631StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9632 OMPExecutableDirective *D) {
9633
9634 // Transform the clauses
9635 llvm::SmallVector<OMPClause *, 16> TClauses;
9636 ArrayRef<OMPClause *> Clauses = D->clauses();
9637 TClauses.reserve(N: Clauses.size());
9638 for (OMPClause *C : Clauses) {
9639 if (C) {
9640 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9641 OMPClause *Clause = getDerived().TransformOMPClause(C);
9642 getDerived().getSema().OpenMP().EndOpenMPClause();
9643 if (Clause)
9644 TClauses.push_back(Elt: Clause);
9645 } else {
9646 TClauses.push_back(Elt: nullptr);
9647 }
9648 }
9649 StmtResult AssociatedStmt;
9650 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9651 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9652 D->getDirectiveKind(),
9653 /*CurScope=*/nullptr);
9654 StmtResult Body;
9655 {
9656 Sema::CompoundScopeRAII CompoundScope(getSema());
9657 assert(D->getDirectiveKind() == OMPD_assume &&
9658 "Unexpected informational directive");
9659 Stmt *CS = D->getAssociatedStmt();
9660 Body = getDerived().TransformStmt(CS);
9661 }
9662 AssociatedStmt =
9663 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9664 if (AssociatedStmt.isInvalid())
9665 return StmtError();
9666 }
9667 if (TClauses.size() != Clauses.size())
9668 return StmtError();
9669
9670 DeclarationNameInfo DirName;
9671
9672 return getDerived().RebuildOMPInformationalDirective(
9673 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9674 D->getBeginLoc(), D->getEndLoc());
9675}
9676
9677template <typename Derived>
9678StmtResult
9679TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9680 // TODO: Fix This
9681 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9682 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9683 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9684 return StmtError();
9685}
9686
9687template <typename Derived>
9688StmtResult
9689TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9690 DeclarationNameInfo DirName;
9691 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9692 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9693 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9694 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9695 return Res;
9696}
9697
9698template <typename Derived>
9699StmtResult
9700TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9701 DeclarationNameInfo DirName;
9702 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9703 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9704 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9705 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9706 return Res;
9707}
9708
9709template <typename Derived>
9710StmtResult
9711TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9712 DeclarationNameInfo DirName;
9713 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9714 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9715 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9716 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9717 return Res;
9718}
9719
9720template <typename Derived>
9721StmtResult
9722TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9723 DeclarationNameInfo DirName;
9724 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9725 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9726 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9727 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9728 return Res;
9729}
9730
9731template <typename Derived>
9732StmtResult
9733TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9734 DeclarationNameInfo DirName;
9735 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9736 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9737 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9738 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9739 return Res;
9740}
9741
9742template <typename Derived>
9743StmtResult
9744TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9745 DeclarationNameInfo DirName;
9746 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9747 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9748 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9749 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9750 return Res;
9751}
9752
9753template <typename Derived>
9754StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9755 OMPInterchangeDirective *D) {
9756 DeclarationNameInfo DirName;
9757 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9758 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9759 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9760 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9761 return Res;
9762}
9763
9764template <typename Derived>
9765StmtResult
9766TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
9767 DeclarationNameInfo DirName;
9768 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9769 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9770 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9771 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9772 return Res;
9773}
9774
9775template <typename Derived>
9776StmtResult
9777TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9778 DeclarationNameInfo DirName;
9779 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9780 OMPD_for, DirName, nullptr, D->getBeginLoc());
9781 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9782 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9783 return Res;
9784}
9785
9786template <typename Derived>
9787StmtResult
9788TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9789 DeclarationNameInfo DirName;
9790 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9791 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9792 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9793 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9794 return Res;
9795}
9796
9797template <typename Derived>
9798StmtResult
9799TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9800 DeclarationNameInfo DirName;
9801 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9802 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9803 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9804 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9805 return Res;
9806}
9807
9808template <typename Derived>
9809StmtResult
9810TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9811 DeclarationNameInfo DirName;
9812 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9813 OMPD_section, DirName, nullptr, D->getBeginLoc());
9814 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9815 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9816 return Res;
9817}
9818
9819template <typename Derived>
9820StmtResult
9821TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9822 DeclarationNameInfo DirName;
9823 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9824 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9825 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9826 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9827 return Res;
9828}
9829
9830template <typename Derived>
9831StmtResult
9832TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9833 DeclarationNameInfo DirName;
9834 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9835 OMPD_single, DirName, nullptr, D->getBeginLoc());
9836 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9837 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9838 return Res;
9839}
9840
9841template <typename Derived>
9842StmtResult
9843TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9844 DeclarationNameInfo DirName;
9845 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9846 OMPD_master, DirName, nullptr, D->getBeginLoc());
9847 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9848 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9849 return Res;
9850}
9851
9852template <typename Derived>
9853StmtResult
9854TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9856 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9857 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9858 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9859 return Res;
9860}
9861
9862template <typename Derived>
9863StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9864 OMPParallelForDirective *D) {
9865 DeclarationNameInfo DirName;
9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9867 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9868 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9869 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9870 return Res;
9871}
9872
9873template <typename Derived>
9874StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9875 OMPParallelForSimdDirective *D) {
9876 DeclarationNameInfo DirName;
9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9878 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9879 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9880 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9881 return Res;
9882}
9883
9884template <typename Derived>
9885StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9886 OMPParallelMasterDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9890 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9891 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9892 return Res;
9893}
9894
9895template <typename Derived>
9896StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9897 OMPParallelMaskedDirective *D) {
9898 DeclarationNameInfo DirName;
9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9900 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9901 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9902 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9903 return Res;
9904}
9905
9906template <typename Derived>
9907StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9908 OMPParallelSectionsDirective *D) {
9909 DeclarationNameInfo DirName;
9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9911 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9912 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9913 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9914 return Res;
9915}
9916
9917template <typename Derived>
9918StmtResult
9919TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9920 DeclarationNameInfo DirName;
9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9922 OMPD_task, DirName, nullptr, D->getBeginLoc());
9923 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9924 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9925 return Res;
9926}
9927
9928template <typename Derived>
9929StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9930 OMPTaskyieldDirective *D) {
9931 DeclarationNameInfo DirName;
9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9933 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9934 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9935 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9936 return Res;
9937}
9938
9939template <typename Derived>
9940StmtResult
9941TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9942 DeclarationNameInfo DirName;
9943 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9944 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9945 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9946 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9947 return Res;
9948}
9949
9950template <typename Derived>
9951StmtResult
9952TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9953 DeclarationNameInfo DirName;
9954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9955 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9956 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9957 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9958 return Res;
9959}
9960
9961template <typename Derived>
9962StmtResult
9963TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9964 DeclarationNameInfo DirName;
9965 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9966 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9967 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9968 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9969 return Res;
9970}
9971
9972template <typename Derived>
9973StmtResult
9974TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9975 DeclarationNameInfo DirName;
9976 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9977 OMPD_error, DirName, nullptr, D->getBeginLoc());
9978 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9979 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9980 return Res;
9981}
9982
9983template <typename Derived>
9984StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9985 OMPTaskgroupDirective *D) {
9986 DeclarationNameInfo DirName;
9987 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9988 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9989 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9990 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9991 return Res;
9992}
9993
9994template <typename Derived>
9995StmtResult
9996TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9997 DeclarationNameInfo DirName;
9998 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9999 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10000 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10001 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10002 return Res;
10003}
10004
10005template <typename Derived>
10006StmtResult
10007TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10008 DeclarationNameInfo DirName;
10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10010 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10011 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10012 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10013 return Res;
10014}
10015
10016template <typename Derived>
10017StmtResult
10018TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10019 DeclarationNameInfo DirName;
10020 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10021 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10022 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10023 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10024 return Res;
10025}
10026
10027template <typename Derived>
10028StmtResult
10029TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
10030 DeclarationNameInfo DirName;
10031 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10032 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
10033 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10034 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10035 return Res;
10036}
10037
10038template <typename Derived>
10039StmtResult
10040TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10041 DeclarationNameInfo DirName;
10042 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10043 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10044 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10045 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10046 return Res;
10047}
10048
10049template <typename Derived>
10050StmtResult
10051TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10052 DeclarationNameInfo DirName;
10053 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10054 OMPD_target, DirName, nullptr, D->getBeginLoc());
10055 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10056 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10057 return Res;
10058}
10059
10060template <typename Derived>
10061StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10062 OMPTargetDataDirective *D) {
10063 DeclarationNameInfo DirName;
10064 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10065 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10066 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10067 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10068 return Res;
10069}
10070
10071template <typename Derived>
10072StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10073 OMPTargetEnterDataDirective *D) {
10074 DeclarationNameInfo DirName;
10075 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10076 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10077 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10078 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10079 return Res;
10080}
10081
10082template <typename Derived>
10083StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10084 OMPTargetExitDataDirective *D) {
10085 DeclarationNameInfo DirName;
10086 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10087 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10088 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10089 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10090 return Res;
10091}
10092
10093template <typename Derived>
10094StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10095 OMPTargetParallelDirective *D) {
10096 DeclarationNameInfo DirName;
10097 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10098 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10099 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10100 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10101 return Res;
10102}
10103
10104template <typename Derived>
10105StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10106 OMPTargetParallelForDirective *D) {
10107 DeclarationNameInfo DirName;
10108 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10109 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10110 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10111 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10112 return Res;
10113}
10114
10115template <typename Derived>
10116StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10117 OMPTargetUpdateDirective *D) {
10118 DeclarationNameInfo DirName;
10119 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10120 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10121 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10122 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10123 return Res;
10124}
10125
10126template <typename Derived>
10127StmtResult
10128TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10129 DeclarationNameInfo DirName;
10130 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10131 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10132 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10133 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10134 return Res;
10135}
10136
10137template <typename Derived>
10138StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10139 OMPCancellationPointDirective *D) {
10140 DeclarationNameInfo DirName;
10141 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10142 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10143 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10144 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10145 return Res;
10146}
10147
10148template <typename Derived>
10149StmtResult
10150TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10151 DeclarationNameInfo DirName;
10152 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10153 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10154 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10155 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10156 return Res;
10157}
10158
10159template <typename Derived>
10160StmtResult
10161TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10162 DeclarationNameInfo DirName;
10163 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10164 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10165 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10166 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10167 return Res;
10168}
10169
10170template <typename Derived>
10171StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10172 OMPTaskLoopSimdDirective *D) {
10173 DeclarationNameInfo DirName;
10174 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10175 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10176 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10177 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10178 return Res;
10179}
10180
10181template <typename Derived>
10182StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10183 OMPMasterTaskLoopDirective *D) {
10184 DeclarationNameInfo DirName;
10185 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10186 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10187 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10188 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10189 return Res;
10190}
10191
10192template <typename Derived>
10193StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10194 OMPMaskedTaskLoopDirective *D) {
10195 DeclarationNameInfo DirName;
10196 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10197 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10198 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10199 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10200 return Res;
10201}
10202
10203template <typename Derived>
10204StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10205 OMPMasterTaskLoopSimdDirective *D) {
10206 DeclarationNameInfo DirName;
10207 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10208 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10209 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10210 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10211 return Res;
10212}
10213
10214template <typename Derived>
10215StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10216 OMPMaskedTaskLoopSimdDirective *D) {
10217 DeclarationNameInfo DirName;
10218 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10219 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10220 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10221 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10222 return Res;
10223}
10224
10225template <typename Derived>
10226StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10227 OMPParallelMasterTaskLoopDirective *D) {
10228 DeclarationNameInfo DirName;
10229 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10230 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10231 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10232 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10233 return Res;
10234}
10235
10236template <typename Derived>
10237StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10238 OMPParallelMaskedTaskLoopDirective *D) {
10239 DeclarationNameInfo DirName;
10240 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10241 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10242 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10243 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10244 return Res;
10245}
10246
10247template <typename Derived>
10248StmtResult
10249TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10250 OMPParallelMasterTaskLoopSimdDirective *D) {
10251 DeclarationNameInfo DirName;
10252 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10253 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10254 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10255 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10256 return Res;
10257}
10258
10259template <typename Derived>
10260StmtResult
10261TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10262 OMPParallelMaskedTaskLoopSimdDirective *D) {
10263 DeclarationNameInfo DirName;
10264 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10265 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10266 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10267 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10268 return Res;
10269}
10270
10271template <typename Derived>
10272StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10273 OMPDistributeDirective *D) {
10274 DeclarationNameInfo DirName;
10275 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10276 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10277 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10278 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10279 return Res;
10280}
10281
10282template <typename Derived>
10283StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10284 OMPDistributeParallelForDirective *D) {
10285 DeclarationNameInfo DirName;
10286 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10287 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10288 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10289 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10290 return Res;
10291}
10292
10293template <typename Derived>
10294StmtResult
10295TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10296 OMPDistributeParallelForSimdDirective *D) {
10297 DeclarationNameInfo DirName;
10298 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10299 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10300 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10301 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10302 return Res;
10303}
10304
10305template <typename Derived>
10306StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10307 OMPDistributeSimdDirective *D) {
10308 DeclarationNameInfo DirName;
10309 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10310 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10311 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10312 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10313 return Res;
10314}
10315
10316template <typename Derived>
10317StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10318 OMPTargetParallelForSimdDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10323 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10324 return Res;
10325}
10326
10327template <typename Derived>
10328StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10329 OMPTargetSimdDirective *D) {
10330 DeclarationNameInfo DirName;
10331 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10332 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10333 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10334 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10335 return Res;
10336}
10337
10338template <typename Derived>
10339StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10340 OMPTeamsDistributeDirective *D) {
10341 DeclarationNameInfo DirName;
10342 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10343 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10344 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10345 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10346 return Res;
10347}
10348
10349template <typename Derived>
10350StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10351 OMPTeamsDistributeSimdDirective *D) {
10352 DeclarationNameInfo DirName;
10353 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10354 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10355 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10356 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10357 return Res;
10358}
10359
10360template <typename Derived>
10361StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10362 OMPTeamsDistributeParallelForSimdDirective *D) {
10363 DeclarationNameInfo DirName;
10364 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10365 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10366 D->getBeginLoc());
10367 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10368 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10369 return Res;
10370}
10371
10372template <typename Derived>
10373StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10374 OMPTeamsDistributeParallelForDirective *D) {
10375 DeclarationNameInfo DirName;
10376 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10377 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10378 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10379 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10380 return Res;
10381}
10382
10383template <typename Derived>
10384StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10385 OMPTargetTeamsDirective *D) {
10386 DeclarationNameInfo DirName;
10387 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10388 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10389 auto Res = getDerived().TransformOMPExecutableDirective(D);
10390 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10391 return Res;
10392}
10393
10394template <typename Derived>
10395StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10396 OMPTargetTeamsDistributeDirective *D) {
10397 DeclarationNameInfo DirName;
10398 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10399 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10400 auto Res = getDerived().TransformOMPExecutableDirective(D);
10401 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10402 return Res;
10403}
10404
10405template <typename Derived>
10406StmtResult
10407TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10408 OMPTargetTeamsDistributeParallelForDirective *D) {
10409 DeclarationNameInfo DirName;
10410 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10411 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10412 D->getBeginLoc());
10413 auto Res = getDerived().TransformOMPExecutableDirective(D);
10414 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10415 return Res;
10416}
10417
10418template <typename Derived>
10419StmtResult TreeTransform<Derived>::
10420 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10421 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10422 DeclarationNameInfo DirName;
10423 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10424 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10425 D->getBeginLoc());
10426 auto Res = getDerived().TransformOMPExecutableDirective(D);
10427 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10428 return Res;
10429}
10430
10431template <typename Derived>
10432StmtResult
10433TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10434 OMPTargetTeamsDistributeSimdDirective *D) {
10435 DeclarationNameInfo DirName;
10436 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10437 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10438 auto Res = getDerived().TransformOMPExecutableDirective(D);
10439 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10440 return Res;
10441}
10442
10443template <typename Derived>
10444StmtResult
10445TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10446 DeclarationNameInfo DirName;
10447 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10448 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10449 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10450 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10451 return Res;
10452}
10453
10454template <typename Derived>
10455StmtResult
10456TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10457 DeclarationNameInfo DirName;
10458 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10459 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10460 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10461 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10462 return Res;
10463}
10464
10465template <typename Derived>
10466StmtResult
10467TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10468 DeclarationNameInfo DirName;
10469 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10470 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10471 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10472 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10473 return Res;
10474}
10475
10476template <typename Derived>
10477StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10478 OMPGenericLoopDirective *D) {
10479 DeclarationNameInfo DirName;
10480 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10481 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10482 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10483 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10484 return Res;
10485}
10486
10487template <typename Derived>
10488StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10489 OMPTeamsGenericLoopDirective *D) {
10490 DeclarationNameInfo DirName;
10491 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10492 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10493 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10494 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10495 return Res;
10496}
10497
10498template <typename Derived>
10499StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10500 OMPTargetTeamsGenericLoopDirective *D) {
10501 DeclarationNameInfo DirName;
10502 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10503 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10504 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10505 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10506 return Res;
10507}
10508
10509template <typename Derived>
10510StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10511 OMPParallelGenericLoopDirective *D) {
10512 DeclarationNameInfo DirName;
10513 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10514 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10515 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10516 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10517 return Res;
10518}
10519
10520template <typename Derived>
10521StmtResult
10522TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10523 OMPTargetParallelGenericLoopDirective *D) {
10524 DeclarationNameInfo DirName;
10525 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10526 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10527 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10528 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10529 return Res;
10530}
10531
10532//===----------------------------------------------------------------------===//
10533// OpenMP clause transformation
10534//===----------------------------------------------------------------------===//
10535template <typename Derived>
10536OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10537 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10538 if (Cond.isInvalid())
10539 return nullptr;
10540 return getDerived().RebuildOMPIfClause(
10541 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10542 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10543}
10544
10545template <typename Derived>
10546OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10547 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10548 if (Cond.isInvalid())
10549 return nullptr;
10550 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10551 C->getLParenLoc(), C->getEndLoc());
10552}
10553
10554template <typename Derived>
10555OMPClause *
10556TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10557 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10558 if (NumThreads.isInvalid())
10559 return nullptr;
10560 return getDerived().RebuildOMPNumThreadsClause(
10561 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10562 C->getModifierLoc(), C->getEndLoc());
10563}
10564
10565template <typename Derived>
10566OMPClause *
10567TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10568 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10569 if (E.isInvalid())
10570 return nullptr;
10571 return getDerived().RebuildOMPSafelenClause(
10572 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10573}
10574
10575template <typename Derived>
10576OMPClause *
10577TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10578 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10579 if (E.isInvalid())
10580 return nullptr;
10581 return getDerived().RebuildOMPAllocatorClause(
10582 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10583}
10584
10585template <typename Derived>
10586OMPClause *
10587TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10588 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10589 if (E.isInvalid())
10590 return nullptr;
10591 return getDerived().RebuildOMPSimdlenClause(
10592 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10593}
10594
10595template <typename Derived>
10596OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10597 SmallVector<Expr *, 4> TransformedSizes;
10598 TransformedSizes.reserve(N: C->getNumSizes());
10599 bool Changed = false;
10600 for (Expr *E : C->getSizesRefs()) {
10601 if (!E) {
10602 TransformedSizes.push_back(Elt: nullptr);
10603 continue;
10604 }
10605
10606 ExprResult T = getDerived().TransformExpr(E);
10607 if (T.isInvalid())
10608 return nullptr;
10609 if (E != T.get())
10610 Changed = true;
10611 TransformedSizes.push_back(Elt: T.get());
10612 }
10613
10614 if (!Changed && !getDerived().AlwaysRebuild())
10615 return C;
10616 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10617 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10618}
10619
10620template <typename Derived>
10621OMPClause *
10622TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10623 SmallVector<Expr *> TransformedArgs;
10624 TransformedArgs.reserve(N: C->getNumLoops());
10625 bool Changed = false;
10626 for (Expr *E : C->getArgsRefs()) {
10627 if (!E) {
10628 TransformedArgs.push_back(Elt: nullptr);
10629 continue;
10630 }
10631
10632 ExprResult T = getDerived().TransformExpr(E);
10633 if (T.isInvalid())
10634 return nullptr;
10635 if (E != T.get())
10636 Changed = true;
10637 TransformedArgs.push_back(Elt: T.get());
10638 }
10639
10640 if (!Changed && !getDerived().AlwaysRebuild())
10641 return C;
10642 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10643 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10644}
10645
10646template <typename Derived>
10647OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10648 if (!getDerived().AlwaysRebuild())
10649 return C;
10650 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10651}
10652
10653template <typename Derived>
10654OMPClause *
10655TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10656 ExprResult T = getDerived().TransformExpr(C->getFactor());
10657 if (T.isInvalid())
10658 return nullptr;
10659 Expr *Factor = T.get();
10660 bool Changed = Factor != C->getFactor();
10661
10662 if (!Changed && !getDerived().AlwaysRebuild())
10663 return C;
10664 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10665 EndLoc: C->getEndLoc());
10666}
10667
10668template <typename Derived>
10669OMPClause *
10670TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
10671 ExprResult F = getDerived().TransformExpr(C->getFirst());
10672 if (F.isInvalid())
10673 return nullptr;
10674
10675 ExprResult Cn = getDerived().TransformExpr(C->getCount());
10676 if (Cn.isInvalid())
10677 return nullptr;
10678
10679 Expr *First = F.get();
10680 Expr *Count = Cn.get();
10681
10682 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
10683
10684 // If no changes and AlwaysRebuild() is false, return the original clause
10685 if (!Changed && !getDerived().AlwaysRebuild())
10686 return C;
10687
10688 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
10689 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
10690 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
10691}
10692
10693template <typename Derived>
10694OMPClause *
10695TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10696 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10697 if (E.isInvalid())
10698 return nullptr;
10699 return getDerived().RebuildOMPCollapseClause(
10700 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10701}
10702
10703template <typename Derived>
10704OMPClause *
10705TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10706 return getDerived().RebuildOMPDefaultClause(
10707 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
10708 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
10709 C->getEndLoc());
10710}
10711
10712template <typename Derived>
10713OMPClause *
10714TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
10715 // No need to rebuild this clause, no template-dependent parameters.
10716 return C;
10717}
10718
10719template <typename Derived>
10720OMPClause *
10721TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
10722 Expr *Impex = C->getImpexType();
10723 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
10724
10725 if (TransformedImpex.isInvalid())
10726 return nullptr;
10727
10728 return getDerived().RebuildOMPTransparentClause(
10729 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
10730 C->getEndLoc());
10731}
10732
10733template <typename Derived>
10734OMPClause *
10735TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10736 return getDerived().RebuildOMPProcBindClause(
10737 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10738 C->getLParenLoc(), C->getEndLoc());
10739}
10740
10741template <typename Derived>
10742OMPClause *
10743TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10744 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10745 if (E.isInvalid())
10746 return nullptr;
10747 return getDerived().RebuildOMPScheduleClause(
10748 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10749 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10750 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10751 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10752}
10753
10754template <typename Derived>
10755OMPClause *
10756TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10757 ExprResult E;
10758 if (auto *Num = C->getNumForLoops()) {
10759 E = getDerived().TransformExpr(Num);
10760 if (E.isInvalid())
10761 return nullptr;
10762 }
10763 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10764 C->getLParenLoc(), E.get());
10765}
10766
10767template <typename Derived>
10768OMPClause *
10769TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10770 ExprResult E;
10771 if (Expr *Evt = C->getEventHandler()) {
10772 E = getDerived().TransformExpr(Evt);
10773 if (E.isInvalid())
10774 return nullptr;
10775 }
10776 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10777 C->getLParenLoc(), C->getEndLoc());
10778}
10779
10780template <typename Derived>
10781OMPClause *
10782TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10783 ExprResult Cond;
10784 if (auto *Condition = C->getCondition()) {
10785 Cond = getDerived().TransformExpr(Condition);
10786 if (Cond.isInvalid())
10787 return nullptr;
10788 }
10789 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
10790 C->getLParenLoc(), C->getEndLoc());
10791}
10792
10793template <typename Derived>
10794OMPClause *
10795TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10796 // No need to rebuild this clause, no template-dependent parameters.
10797 return C;
10798}
10799
10800template <typename Derived>
10801OMPClause *
10802TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10803 // No need to rebuild this clause, no template-dependent parameters.
10804 return C;
10805}
10806
10807template <typename Derived>
10808OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10809 // No need to rebuild this clause, no template-dependent parameters.
10810 return C;
10811}
10812
10813template <typename Derived>
10814OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10815 // No need to rebuild this clause, no template-dependent parameters.
10816 return C;
10817}
10818
10819template <typename Derived>
10820OMPClause *
10821TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10822 // No need to rebuild this clause, no template-dependent parameters.
10823 return C;
10824}
10825
10826template <typename Derived>
10827OMPClause *
10828TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10829 // No need to rebuild this clause, no template-dependent parameters.
10830 return C;
10831}
10832
10833template <typename Derived>
10834OMPClause *
10835TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10836 // No need to rebuild this clause, no template-dependent parameters.
10837 return C;
10838}
10839
10840template <typename Derived>
10841OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10842 // No need to rebuild this clause, no template-dependent parameters.
10843 return C;
10844}
10845
10846template <typename Derived>
10847OMPClause *
10848TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10849 return C;
10850}
10851
10852template <typename Derived>
10853OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10854 ExprResult E = getDerived().TransformExpr(C->getExpr());
10855 if (E.isInvalid())
10856 return nullptr;
10857 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10858 C->getLParenLoc(), C->getEndLoc());
10859}
10860
10861template <typename Derived>
10862OMPClause *
10863TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10864 return C;
10865}
10866
10867template <typename Derived>
10868OMPClause *
10869TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10870 return C;
10871}
10872template <typename Derived>
10873OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10874 OMPNoOpenMPRoutinesClause *C) {
10875 return C;
10876}
10877template <typename Derived>
10878OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10879 OMPNoOpenMPConstructsClause *C) {
10880 return C;
10881}
10882template <typename Derived>
10883OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10884 OMPNoParallelismClause *C) {
10885 return C;
10886}
10887
10888template <typename Derived>
10889OMPClause *
10890TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10891 // No need to rebuild this clause, no template-dependent parameters.
10892 return C;
10893}
10894
10895template <typename Derived>
10896OMPClause *
10897TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10898 // No need to rebuild this clause, no template-dependent parameters.
10899 return C;
10900}
10901
10902template <typename Derived>
10903OMPClause *
10904TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10905 // No need to rebuild this clause, no template-dependent parameters.
10906 return C;
10907}
10908
10909template <typename Derived>
10910OMPClause *
10911TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10912 // No need to rebuild this clause, no template-dependent parameters.
10913 return C;
10914}
10915
10916template <typename Derived>
10917OMPClause *
10918TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10919 // No need to rebuild this clause, no template-dependent parameters.
10920 return C;
10921}
10922
10923template <typename Derived>
10924OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10925 // No need to rebuild this clause, no template-dependent parameters.
10926 return C;
10927}
10928
10929template <typename Derived>
10930OMPClause *
10931TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10932 // No need to rebuild this clause, no template-dependent parameters.
10933 return C;
10934}
10935
10936template <typename Derived>
10937OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10938 // No need to rebuild this clause, no template-dependent parameters.
10939 return C;
10940}
10941
10942template <typename Derived>
10943OMPClause *
10944TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10945 // No need to rebuild this clause, no template-dependent parameters.
10946 return C;
10947}
10948
10949template <typename Derived>
10950OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10951 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10952 if (IVR.isInvalid())
10953 return nullptr;
10954
10955 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10956 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10957 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlist())) {
10958 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10959 if (ER.isInvalid())
10960 return nullptr;
10961 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10962 }
10963 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10964 C->getBeginLoc(), C->getLParenLoc(),
10965 C->getVarLoc(), C->getEndLoc());
10966}
10967
10968template <typename Derived>
10969OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10970 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10971 if (ER.isInvalid())
10972 return nullptr;
10973 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10974 C->getLParenLoc(), C->getVarLoc(),
10975 C->getEndLoc());
10976}
10977
10978template <typename Derived>
10979OMPClause *
10980TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10981 ExprResult ER;
10982 if (Expr *IV = C->getInteropVar()) {
10983 ER = getDerived().TransformExpr(IV);
10984 if (ER.isInvalid())
10985 return nullptr;
10986 }
10987 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10988 C->getLParenLoc(), C->getVarLoc(),
10989 C->getEndLoc());
10990}
10991
10992template <typename Derived>
10993OMPClause *
10994TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10995 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10996 if (Cond.isInvalid())
10997 return nullptr;
10998 return getDerived().RebuildOMPNovariantsClause(
10999 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11000}
11001
11002template <typename Derived>
11003OMPClause *
11004TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11005 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11006 if (Cond.isInvalid())
11007 return nullptr;
11008 return getDerived().RebuildOMPNocontextClause(
11009 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11010}
11011
11012template <typename Derived>
11013OMPClause *
11014TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11015 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11016 if (ThreadID.isInvalid())
11017 return nullptr;
11018 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11019 C->getLParenLoc(), C->getEndLoc());
11020}
11021
11022template <typename Derived>
11023OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11024 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11025 if (E.isInvalid())
11026 return nullptr;
11027 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11028 C->getLParenLoc(), C->getEndLoc());
11029}
11030
11031template <typename Derived>
11032OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11033 OMPUnifiedAddressClause *C) {
11034 llvm_unreachable("unified_address clause cannot appear in dependent context");
11035}
11036
11037template <typename Derived>
11038OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11039 OMPUnifiedSharedMemoryClause *C) {
11040 llvm_unreachable(
11041 "unified_shared_memory clause cannot appear in dependent context");
11042}
11043
11044template <typename Derived>
11045OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11046 OMPReverseOffloadClause *C) {
11047 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11048}
11049
11050template <typename Derived>
11051OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11052 OMPDynamicAllocatorsClause *C) {
11053 llvm_unreachable(
11054 "dynamic_allocators clause cannot appear in dependent context");
11055}
11056
11057template <typename Derived>
11058OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11059 OMPAtomicDefaultMemOrderClause *C) {
11060 llvm_unreachable(
11061 "atomic_default_mem_order clause cannot appear in dependent context");
11062}
11063
11064template <typename Derived>
11065OMPClause *
11066TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11067 llvm_unreachable("self_maps clause cannot appear in dependent context");
11068}
11069
11070template <typename Derived>
11071OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11072 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11073 C->getBeginLoc(), C->getLParenLoc(),
11074 C->getEndLoc());
11075}
11076
11077template <typename Derived>
11078OMPClause *
11079TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11080 return getDerived().RebuildOMPSeverityClause(
11081 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11082 C->getLParenLoc(), C->getEndLoc());
11083}
11084
11085template <typename Derived>
11086OMPClause *
11087TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11088 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11089 if (E.isInvalid())
11090 return nullptr;
11091 return getDerived().RebuildOMPMessageClause(
11092 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11093}
11094
11095template <typename Derived>
11096OMPClause *
11097TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11098 llvm::SmallVector<Expr *, 16> Vars;
11099 Vars.reserve(N: C->varlist_size());
11100 for (auto *VE : C->varlist()) {
11101 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11102 if (EVar.isInvalid())
11103 return nullptr;
11104 Vars.push_back(Elt: EVar.get());
11105 }
11106 return getDerived().RebuildOMPPrivateClause(
11107 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11108}
11109
11110template <typename Derived>
11111OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11112 OMPFirstprivateClause *C) {
11113 llvm::SmallVector<Expr *, 16> Vars;
11114 Vars.reserve(N: C->varlist_size());
11115 for (auto *VE : C->varlist()) {
11116 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11117 if (EVar.isInvalid())
11118 return nullptr;
11119 Vars.push_back(Elt: EVar.get());
11120 }
11121 return getDerived().RebuildOMPFirstprivateClause(
11122 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11123}
11124
11125template <typename Derived>
11126OMPClause *
11127TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11128 llvm::SmallVector<Expr *, 16> Vars;
11129 Vars.reserve(N: C->varlist_size());
11130 for (auto *VE : C->varlist()) {
11131 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11132 if (EVar.isInvalid())
11133 return nullptr;
11134 Vars.push_back(Elt: EVar.get());
11135 }
11136 return getDerived().RebuildOMPLastprivateClause(
11137 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11138 C->getLParenLoc(), C->getEndLoc());
11139}
11140
11141template <typename Derived>
11142OMPClause *
11143TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11144 llvm::SmallVector<Expr *, 16> Vars;
11145 Vars.reserve(N: C->varlist_size());
11146 for (auto *VE : C->varlist()) {
11147 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11148 if (EVar.isInvalid())
11149 return nullptr;
11150 Vars.push_back(Elt: EVar.get());
11151 }
11152 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11153 C->getLParenLoc(), C->getEndLoc());
11154}
11155
11156template <typename Derived>
11157OMPClause *
11158TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11159 llvm::SmallVector<Expr *, 16> Vars;
11160 Vars.reserve(N: C->varlist_size());
11161 for (auto *VE : C->varlist()) {
11162 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11163 if (EVar.isInvalid())
11164 return nullptr;
11165 Vars.push_back(Elt: EVar.get());
11166 }
11167 CXXScopeSpec ReductionIdScopeSpec;
11168 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11169
11170 DeclarationNameInfo NameInfo = C->getNameInfo();
11171 if (NameInfo.getName()) {
11172 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11173 if (!NameInfo.getName())
11174 return nullptr;
11175 }
11176 // Build a list of all UDR decls with the same names ranged by the Scopes.
11177 // The Scope boundary is a duplication of the previous decl.
11178 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11179 for (auto *E : C->reduction_ops()) {
11180 // Transform all the decls.
11181 if (E) {
11182 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11183 UnresolvedSet<8> Decls;
11184 for (auto *D : ULE->decls()) {
11185 NamedDecl *InstD =
11186 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11187 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11188 }
11189 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11190 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11191 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11192 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11193 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11194 } else
11195 UnresolvedReductions.push_back(Elt: nullptr);
11196 }
11197 return getDerived().RebuildOMPReductionClause(
11198 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11199 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11200 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11201}
11202
11203template <typename Derived>
11204OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11205 OMPTaskReductionClause *C) {
11206 llvm::SmallVector<Expr *, 16> Vars;
11207 Vars.reserve(N: C->varlist_size());
11208 for (auto *VE : C->varlist()) {
11209 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11210 if (EVar.isInvalid())
11211 return nullptr;
11212 Vars.push_back(Elt: EVar.get());
11213 }
11214 CXXScopeSpec ReductionIdScopeSpec;
11215 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11216
11217 DeclarationNameInfo NameInfo = C->getNameInfo();
11218 if (NameInfo.getName()) {
11219 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11220 if (!NameInfo.getName())
11221 return nullptr;
11222 }
11223 // Build a list of all UDR decls with the same names ranged by the Scopes.
11224 // The Scope boundary is a duplication of the previous decl.
11225 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11226 for (auto *E : C->reduction_ops()) {
11227 // Transform all the decls.
11228 if (E) {
11229 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11230 UnresolvedSet<8> Decls;
11231 for (auto *D : ULE->decls()) {
11232 NamedDecl *InstD =
11233 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11234 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11235 }
11236 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11237 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11238 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11239 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11240 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11241 } else
11242 UnresolvedReductions.push_back(Elt: nullptr);
11243 }
11244 return getDerived().RebuildOMPTaskReductionClause(
11245 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11246 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11247}
11248
11249template <typename Derived>
11250OMPClause *
11251TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11252 llvm::SmallVector<Expr *, 16> Vars;
11253 Vars.reserve(N: C->varlist_size());
11254 for (auto *VE : C->varlist()) {
11255 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11256 if (EVar.isInvalid())
11257 return nullptr;
11258 Vars.push_back(Elt: EVar.get());
11259 }
11260 CXXScopeSpec ReductionIdScopeSpec;
11261 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11262
11263 DeclarationNameInfo NameInfo = C->getNameInfo();
11264 if (NameInfo.getName()) {
11265 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11266 if (!NameInfo.getName())
11267 return nullptr;
11268 }
11269 // Build a list of all UDR decls with the same names ranged by the Scopes.
11270 // The Scope boundary is a duplication of the previous decl.
11271 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11272 for (auto *E : C->reduction_ops()) {
11273 // Transform all the decls.
11274 if (E) {
11275 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11276 UnresolvedSet<8> Decls;
11277 for (auto *D : ULE->decls()) {
11278 NamedDecl *InstD =
11279 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11280 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11281 }
11282 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11283 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11284 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11285 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11286 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11287 } else
11288 UnresolvedReductions.push_back(Elt: nullptr);
11289 }
11290 return getDerived().RebuildOMPInReductionClause(
11291 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11292 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11293}
11294
11295template <typename Derived>
11296OMPClause *
11297TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11298 llvm::SmallVector<Expr *, 16> Vars;
11299 Vars.reserve(N: C->varlist_size());
11300 for (auto *VE : C->varlist()) {
11301 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11302 if (EVar.isInvalid())
11303 return nullptr;
11304 Vars.push_back(Elt: EVar.get());
11305 }
11306 ExprResult Step = getDerived().TransformExpr(C->getStep());
11307 if (Step.isInvalid())
11308 return nullptr;
11309 return getDerived().RebuildOMPLinearClause(
11310 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11311 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11312 C->getEndLoc());
11313}
11314
11315template <typename Derived>
11316OMPClause *
11317TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11318 llvm::SmallVector<Expr *, 16> Vars;
11319 Vars.reserve(N: C->varlist_size());
11320 for (auto *VE : C->varlist()) {
11321 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11322 if (EVar.isInvalid())
11323 return nullptr;
11324 Vars.push_back(Elt: EVar.get());
11325 }
11326 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11327 if (Alignment.isInvalid())
11328 return nullptr;
11329 return getDerived().RebuildOMPAlignedClause(
11330 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11331 C->getColonLoc(), C->getEndLoc());
11332}
11333
11334template <typename Derived>
11335OMPClause *
11336TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11337 llvm::SmallVector<Expr *, 16> Vars;
11338 Vars.reserve(N: C->varlist_size());
11339 for (auto *VE : C->varlist()) {
11340 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11341 if (EVar.isInvalid())
11342 return nullptr;
11343 Vars.push_back(Elt: EVar.get());
11344 }
11345 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11346 C->getLParenLoc(), C->getEndLoc());
11347}
11348
11349template <typename Derived>
11350OMPClause *
11351TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11352 llvm::SmallVector<Expr *, 16> Vars;
11353 Vars.reserve(N: C->varlist_size());
11354 for (auto *VE : C->varlist()) {
11355 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11356 if (EVar.isInvalid())
11357 return nullptr;
11358 Vars.push_back(Elt: EVar.get());
11359 }
11360 return getDerived().RebuildOMPCopyprivateClause(
11361 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11362}
11363
11364template <typename Derived>
11365OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11366 llvm::SmallVector<Expr *, 16> Vars;
11367 Vars.reserve(N: C->varlist_size());
11368 for (auto *VE : C->varlist()) {
11369 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11370 if (EVar.isInvalid())
11371 return nullptr;
11372 Vars.push_back(Elt: EVar.get());
11373 }
11374 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11375 C->getLParenLoc(), C->getEndLoc());
11376}
11377
11378template <typename Derived>
11379OMPClause *
11380TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11381 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11382 if (E.isInvalid())
11383 return nullptr;
11384 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11385 C->getLParenLoc(), C->getEndLoc());
11386}
11387
11388template <typename Derived>
11389OMPClause *
11390TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11391 llvm::SmallVector<Expr *, 16> Vars;
11392 Expr *DepModifier = C->getModifier();
11393 if (DepModifier) {
11394 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11395 if (DepModRes.isInvalid())
11396 return nullptr;
11397 DepModifier = DepModRes.get();
11398 }
11399 Vars.reserve(N: C->varlist_size());
11400 for (auto *VE : C->varlist()) {
11401 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11402 if (EVar.isInvalid())
11403 return nullptr;
11404 Vars.push_back(Elt: EVar.get());
11405 }
11406 return getDerived().RebuildOMPDependClause(
11407 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11408 C->getOmpAllMemoryLoc()},
11409 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11410}
11411
11412template <typename Derived>
11413OMPClause *
11414TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11415 ExprResult E = getDerived().TransformExpr(C->getDevice());
11416 if (E.isInvalid())
11417 return nullptr;
11418 return getDerived().RebuildOMPDeviceClause(
11419 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11420 C->getModifierLoc(), C->getEndLoc());
11421}
11422
11423template <typename Derived, class T>
11424bool transformOMPMappableExprListClause(
11425 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11426 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11427 DeclarationNameInfo &MapperIdInfo,
11428 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11429 // Transform expressions in the list.
11430 Vars.reserve(N: C->varlist_size());
11431 for (auto *VE : C->varlist()) {
11432 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11433 if (EVar.isInvalid())
11434 return true;
11435 Vars.push_back(Elt: EVar.get());
11436 }
11437 // Transform mapper scope specifier and identifier.
11438 NestedNameSpecifierLoc QualifierLoc;
11439 if (C->getMapperQualifierLoc()) {
11440 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11441 C->getMapperQualifierLoc());
11442 if (!QualifierLoc)
11443 return true;
11444 }
11445 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11446 MapperIdInfo = C->getMapperIdInfo();
11447 if (MapperIdInfo.getName()) {
11448 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11449 if (!MapperIdInfo.getName())
11450 return true;
11451 }
11452 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11453 // the previous user-defined mapper lookup in dependent environment.
11454 for (auto *E : C->mapperlists()) {
11455 // Transform all the decls.
11456 if (E) {
11457 auto *ULE = cast<UnresolvedLookupExpr>(E);
11458 UnresolvedSet<8> Decls;
11459 for (auto *D : ULE->decls()) {
11460 NamedDecl *InstD =
11461 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11462 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11463 }
11464 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11465 TT.getSema().Context, /*NamingClass=*/nullptr,
11466 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11467 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11468 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11469 } else {
11470 UnresolvedMappers.push_back(Elt: nullptr);
11471 }
11472 }
11473 return false;
11474}
11475
11476template <typename Derived>
11477OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11478 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11479 llvm::SmallVector<Expr *, 16> Vars;
11480 Expr *IteratorModifier = C->getIteratorModifier();
11481 if (IteratorModifier) {
11482 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11483 if (MapModRes.isInvalid())
11484 return nullptr;
11485 IteratorModifier = MapModRes.get();
11486 }
11487 CXXScopeSpec MapperIdScopeSpec;
11488 DeclarationNameInfo MapperIdInfo;
11489 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11490 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11491 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11492 return nullptr;
11493 return getDerived().RebuildOMPMapClause(
11494 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11495 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11496 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11497}
11498
11499template <typename Derived>
11500OMPClause *
11501TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11502 Expr *Allocator = C->getAllocator();
11503 if (Allocator) {
11504 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11505 if (AllocatorRes.isInvalid())
11506 return nullptr;
11507 Allocator = AllocatorRes.get();
11508 }
11509 Expr *Alignment = C->getAlignment();
11510 if (Alignment) {
11511 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11512 if (AlignmentRes.isInvalid())
11513 return nullptr;
11514 Alignment = AlignmentRes.get();
11515 }
11516 llvm::SmallVector<Expr *, 16> Vars;
11517 Vars.reserve(N: C->varlist_size());
11518 for (auto *VE : C->varlist()) {
11519 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11520 if (EVar.isInvalid())
11521 return nullptr;
11522 Vars.push_back(Elt: EVar.get());
11523 }
11524 return getDerived().RebuildOMPAllocateClause(
11525 Allocator, Alignment, C->getFirstAllocateModifier(),
11526 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11527 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11528 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11529}
11530
11531template <typename Derived>
11532OMPClause *
11533TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11534 llvm::SmallVector<Expr *, 3> Vars;
11535 Vars.reserve(N: C->varlist_size());
11536 for (auto *VE : C->varlist()) {
11537 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11538 if (EVar.isInvalid())
11539 return nullptr;
11540 Vars.push_back(Elt: EVar.get());
11541 }
11542 return getDerived().RebuildOMPNumTeamsClause(
11543 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11544}
11545
11546template <typename Derived>
11547OMPClause *
11548TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11549 llvm::SmallVector<Expr *, 3> Vars;
11550 Vars.reserve(N: C->varlist_size());
11551 for (auto *VE : C->varlist()) {
11552 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11553 if (EVar.isInvalid())
11554 return nullptr;
11555 Vars.push_back(Elt: EVar.get());
11556 }
11557 return getDerived().RebuildOMPThreadLimitClause(
11558 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11559}
11560
11561template <typename Derived>
11562OMPClause *
11563TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11564 ExprResult E = getDerived().TransformExpr(C->getPriority());
11565 if (E.isInvalid())
11566 return nullptr;
11567 return getDerived().RebuildOMPPriorityClause(
11568 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11569}
11570
11571template <typename Derived>
11572OMPClause *
11573TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11574 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11575 if (E.isInvalid())
11576 return nullptr;
11577 return getDerived().RebuildOMPGrainsizeClause(
11578 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11579 C->getModifierLoc(), C->getEndLoc());
11580}
11581
11582template <typename Derived>
11583OMPClause *
11584TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11585 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11586 if (E.isInvalid())
11587 return nullptr;
11588 return getDerived().RebuildOMPNumTasksClause(
11589 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11590 C->getModifierLoc(), C->getEndLoc());
11591}
11592
11593template <typename Derived>
11594OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11595 ExprResult E = getDerived().TransformExpr(C->getHint());
11596 if (E.isInvalid())
11597 return nullptr;
11598 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11599 C->getLParenLoc(), C->getEndLoc());
11600}
11601
11602template <typename Derived>
11603OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11604 OMPDistScheduleClause *C) {
11605 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11606 if (E.isInvalid())
11607 return nullptr;
11608 return getDerived().RebuildOMPDistScheduleClause(
11609 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11610 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11611}
11612
11613template <typename Derived>
11614OMPClause *
11615TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11616 // Rebuild Defaultmap Clause since we need to invoke the checking of
11617 // defaultmap(none:variable-category) after template initialization.
11618 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11619 C->getDefaultmapKind(),
11620 C->getBeginLoc(),
11621 C->getLParenLoc(),
11622 C->getDefaultmapModifierLoc(),
11623 C->getDefaultmapKindLoc(),
11624 C->getEndLoc());
11625}
11626
11627template <typename Derived>
11628OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11629 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11630 llvm::SmallVector<Expr *, 16> Vars;
11631 Expr *IteratorModifier = C->getIteratorModifier();
11632 if (IteratorModifier) {
11633 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11634 if (MapModRes.isInvalid())
11635 return nullptr;
11636 IteratorModifier = MapModRes.get();
11637 }
11638 CXXScopeSpec MapperIdScopeSpec;
11639 DeclarationNameInfo MapperIdInfo;
11640 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11641 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11642 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11643 return nullptr;
11644 return getDerived().RebuildOMPToClause(
11645 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11646 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11647 UnresolvedMappers);
11648}
11649
11650template <typename Derived>
11651OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11652 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11653 llvm::SmallVector<Expr *, 16> Vars;
11654 Expr *IteratorModifier = C->getIteratorModifier();
11655 if (IteratorModifier) {
11656 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11657 if (MapModRes.isInvalid())
11658 return nullptr;
11659 IteratorModifier = MapModRes.get();
11660 }
11661 CXXScopeSpec MapperIdScopeSpec;
11662 DeclarationNameInfo MapperIdInfo;
11663 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11664 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11665 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11666 return nullptr;
11667 return getDerived().RebuildOMPFromClause(
11668 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11669 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11670 UnresolvedMappers);
11671}
11672
11673template <typename Derived>
11674OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11675 OMPUseDevicePtrClause *C) {
11676 llvm::SmallVector<Expr *, 16> Vars;
11677 Vars.reserve(N: C->varlist_size());
11678 for (auto *VE : C->varlist()) {
11679 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11680 if (EVar.isInvalid())
11681 return nullptr;
11682 Vars.push_back(Elt: EVar.get());
11683 }
11684 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11685 return getDerived().RebuildOMPUseDevicePtrClause(
11686 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
11687}
11688
11689template <typename Derived>
11690OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11691 OMPUseDeviceAddrClause *C) {
11692 llvm::SmallVector<Expr *, 16> Vars;
11693 Vars.reserve(N: C->varlist_size());
11694 for (auto *VE : C->varlist()) {
11695 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11696 if (EVar.isInvalid())
11697 return nullptr;
11698 Vars.push_back(Elt: EVar.get());
11699 }
11700 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11701 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11702}
11703
11704template <typename Derived>
11705OMPClause *
11706TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11707 llvm::SmallVector<Expr *, 16> Vars;
11708 Vars.reserve(N: C->varlist_size());
11709 for (auto *VE : C->varlist()) {
11710 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11711 if (EVar.isInvalid())
11712 return nullptr;
11713 Vars.push_back(Elt: EVar.get());
11714 }
11715 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11716 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11717}
11718
11719template <typename Derived>
11720OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11721 OMPHasDeviceAddrClause *C) {
11722 llvm::SmallVector<Expr *, 16> Vars;
11723 Vars.reserve(N: C->varlist_size());
11724 for (auto *VE : C->varlist()) {
11725 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11726 if (EVar.isInvalid())
11727 return nullptr;
11728 Vars.push_back(Elt: EVar.get());
11729 }
11730 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11731 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11732}
11733
11734template <typename Derived>
11735OMPClause *
11736TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11737 llvm::SmallVector<Expr *, 16> Vars;
11738 Vars.reserve(N: C->varlist_size());
11739 for (auto *VE : C->varlist()) {
11740 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11741 if (EVar.isInvalid())
11742 return nullptr;
11743 Vars.push_back(Elt: EVar.get());
11744 }
11745 return getDerived().RebuildOMPNontemporalClause(
11746 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11747}
11748
11749template <typename Derived>
11750OMPClause *
11751TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11752 llvm::SmallVector<Expr *, 16> Vars;
11753 Vars.reserve(N: C->varlist_size());
11754 for (auto *VE : C->varlist()) {
11755 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11756 if (EVar.isInvalid())
11757 return nullptr;
11758 Vars.push_back(Elt: EVar.get());
11759 }
11760 return getDerived().RebuildOMPInclusiveClause(
11761 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11762}
11763
11764template <typename Derived>
11765OMPClause *
11766TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11767 llvm::SmallVector<Expr *, 16> Vars;
11768 Vars.reserve(N: C->varlist_size());
11769 for (auto *VE : C->varlist()) {
11770 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11771 if (EVar.isInvalid())
11772 return nullptr;
11773 Vars.push_back(Elt: EVar.get());
11774 }
11775 return getDerived().RebuildOMPExclusiveClause(
11776 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11777}
11778
11779template <typename Derived>
11780OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11781 OMPUsesAllocatorsClause *C) {
11782 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11783 Data.reserve(N: C->getNumberOfAllocators());
11784 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11785 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11786 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11787 if (Allocator.isInvalid())
11788 continue;
11789 ExprResult AllocatorTraits;
11790 if (Expr *AT = D.AllocatorTraits) {
11791 AllocatorTraits = getDerived().TransformExpr(AT);
11792 if (AllocatorTraits.isInvalid())
11793 continue;
11794 }
11795 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11796 NewD.Allocator = Allocator.get();
11797 NewD.AllocatorTraits = AllocatorTraits.get();
11798 NewD.LParenLoc = D.LParenLoc;
11799 NewD.RParenLoc = D.RParenLoc;
11800 }
11801 return getDerived().RebuildOMPUsesAllocatorsClause(
11802 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11803}
11804
11805template <typename Derived>
11806OMPClause *
11807TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11808 SmallVector<Expr *, 4> Locators;
11809 Locators.reserve(N: C->varlist_size());
11810 ExprResult ModifierRes;
11811 if (Expr *Modifier = C->getModifier()) {
11812 ModifierRes = getDerived().TransformExpr(Modifier);
11813 if (ModifierRes.isInvalid())
11814 return nullptr;
11815 }
11816 for (Expr *E : C->varlist()) {
11817 ExprResult Locator = getDerived().TransformExpr(E);
11818 if (Locator.isInvalid())
11819 continue;
11820 Locators.push_back(Elt: Locator.get());
11821 }
11822 return getDerived().RebuildOMPAffinityClause(
11823 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11824 ModifierRes.get(), Locators);
11825}
11826
11827template <typename Derived>
11828OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11829 return getDerived().RebuildOMPOrderClause(
11830 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11831 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11832}
11833
11834template <typename Derived>
11835OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11836 return getDerived().RebuildOMPBindClause(
11837 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11838 C->getLParenLoc(), C->getEndLoc());
11839}
11840
11841template <typename Derived>
11842OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11843 OMPXDynCGroupMemClause *C) {
11844 ExprResult Size = getDerived().TransformExpr(C->getSize());
11845 if (Size.isInvalid())
11846 return nullptr;
11847 return getDerived().RebuildOMPXDynCGroupMemClause(
11848 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11849}
11850
11851template <typename Derived>
11852OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
11853 OMPDynGroupprivateClause *C) {
11854 ExprResult Size = getDerived().TransformExpr(C->getSize());
11855 if (Size.isInvalid())
11856 return nullptr;
11857 return getDerived().RebuildOMPDynGroupprivateClause(
11858 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
11859 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
11860 C->getDynGroupprivateModifierLoc(),
11861 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
11862}
11863
11864template <typename Derived>
11865OMPClause *
11866TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11867 llvm::SmallVector<Expr *, 16> Vars;
11868 Vars.reserve(N: C->varlist_size());
11869 for (auto *VE : C->varlist()) {
11870 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11871 if (EVar.isInvalid())
11872 return nullptr;
11873 Vars.push_back(Elt: EVar.get());
11874 }
11875 return getDerived().RebuildOMPDoacrossClause(
11876 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11877 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11878}
11879
11880template <typename Derived>
11881OMPClause *
11882TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11883 SmallVector<const Attr *> NewAttrs;
11884 for (auto *A : C->getAttrs())
11885 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11886 return getDerived().RebuildOMPXAttributeClause(
11887 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11888}
11889
11890template <typename Derived>
11891OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11892 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11893}
11894
11895//===----------------------------------------------------------------------===//
11896// OpenACC transformation
11897//===----------------------------------------------------------------------===//
11898namespace {
11899template <typename Derived>
11900class OpenACCClauseTransform final
11901 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11902 TreeTransform<Derived> &Self;
11903 ArrayRef<const OpenACCClause *> ExistingClauses;
11904 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11905 OpenACCClause *NewClause = nullptr;
11906
11907 ExprResult VisitVar(Expr *VarRef) {
11908 ExprResult Res = Self.TransformExpr(VarRef);
11909
11910 if (!Res.isUsable())
11911 return Res;
11912
11913 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11914 ParsedClause.getClauseKind(),
11915 Res.get());
11916
11917 return Res;
11918 }
11919
11920 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11921 llvm::SmallVector<Expr *> InstantiatedVarList;
11922 for (Expr *CurVar : VarList) {
11923 ExprResult VarRef = VisitVar(VarRef: CurVar);
11924
11925 if (VarRef.isUsable())
11926 InstantiatedVarList.push_back(Elt: VarRef.get());
11927 }
11928
11929 return InstantiatedVarList;
11930 }
11931
11932public:
11933 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11934 ArrayRef<const OpenACCClause *> ExistingClauses,
11935 SemaOpenACC::OpenACCParsedClause &PC)
11936 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11937
11938 OpenACCClause *CreatedClause() const { return NewClause; }
11939
11940#define VISIT_CLAUSE(CLAUSE_NAME) \
11941 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11942#include "clang/Basic/OpenACCClauses.def"
11943};
11944
11945template <typename Derived>
11946void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11947 const OpenACCDefaultClause &C) {
11948 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11949
11950 NewClause = OpenACCDefaultClause::Create(
11951 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11952 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11953 EndLoc: ParsedClause.getEndLoc());
11954}
11955
11956template <typename Derived>
11957void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11958 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11959 assert(Cond && "If constructed with invalid Condition");
11960 Sema::ConditionResult Res = Self.TransformCondition(
11961 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11962
11963 if (Res.isInvalid() || !Res.get().second)
11964 return;
11965
11966 ParsedClause.setConditionDetails(Res.get().second);
11967
11968 NewClause = OpenACCIfClause::Create(
11969 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11970 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11971 EndLoc: ParsedClause.getEndLoc());
11972}
11973
11974template <typename Derived>
11975void OpenACCClauseTransform<Derived>::VisitSelfClause(
11976 const OpenACCSelfClause &C) {
11977
11978 // If this is an 'update' 'self' clause, this is actually a var list instead.
11979 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11980 llvm::SmallVector<Expr *> InstantiatedVarList;
11981 for (Expr *CurVar : C.getVarList()) {
11982 ExprResult Res = Self.TransformExpr(CurVar);
11983
11984 if (!Res.isUsable())
11985 continue;
11986
11987 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11988 ParsedClause.getClauseKind(),
11989 Res.get());
11990
11991 if (Res.isUsable())
11992 InstantiatedVarList.push_back(Elt: Res.get());
11993 }
11994
11995 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
11996 ModKind: OpenACCModifierKind::Invalid);
11997
11998 NewClause = OpenACCSelfClause::Create(
11999 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12000 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12001 ParsedClause.getEndLoc());
12002 } else {
12003
12004 if (C.hasConditionExpr()) {
12005 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12006 Sema::ConditionResult Res =
12007 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12008 Sema::ConditionKind::Boolean);
12009
12010 if (Res.isInvalid() || !Res.get().second)
12011 return;
12012
12013 ParsedClause.setConditionDetails(Res.get().second);
12014 }
12015
12016 NewClause = OpenACCSelfClause::Create(
12017 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12018 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12019 ParsedClause.getEndLoc());
12020 }
12021}
12022
12023template <typename Derived>
12024void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12025 const OpenACCNumGangsClause &C) {
12026 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12027
12028 for (Expr *CurIntExpr : C.getIntExprs()) {
12029 ExprResult Res = Self.TransformExpr(CurIntExpr);
12030
12031 if (!Res.isUsable())
12032 return;
12033
12034 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12035 C.getClauseKind(),
12036 C.getBeginLoc(), Res.get());
12037 if (!Res.isUsable())
12038 return;
12039
12040 InstantiatedIntExprs.push_back(Elt: Res.get());
12041 }
12042
12043 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12044 NewClause = OpenACCNumGangsClause::Create(
12045 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12046 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12047 EndLoc: ParsedClause.getEndLoc());
12048}
12049
12050template <typename Derived>
12051void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12052 const OpenACCPrivateClause &C) {
12053 llvm::SmallVector<Expr *> InstantiatedVarList;
12054 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12055
12056 for (const auto [RefExpr, InitRecipe] :
12057 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12058 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12059
12060 if (VarRef.isUsable()) {
12061 InstantiatedVarList.push_back(Elt: VarRef.get());
12062
12063 // We only have to create a new one if it is dependent, and Sema won't
12064 // make one of these unless the type is non-dependent.
12065 if (InitRecipe.isSet())
12066 InitRecipes.push_back(Elt: InitRecipe);
12067 else
12068 InitRecipes.push_back(
12069 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12070 }
12071 }
12072 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12073 ModKind: OpenACCModifierKind::Invalid);
12074
12075 NewClause = OpenACCPrivateClause::Create(
12076 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12077 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12078 EndLoc: ParsedClause.getEndLoc());
12079}
12080
12081template <typename Derived>
12082void OpenACCClauseTransform<Derived>::VisitHostClause(
12083 const OpenACCHostClause &C) {
12084 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12085 OpenACCModifierKind::Invalid);
12086
12087 NewClause = OpenACCHostClause::Create(
12088 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12089 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12090 EndLoc: ParsedClause.getEndLoc());
12091}
12092
12093template <typename Derived>
12094void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12095 const OpenACCDeviceClause &C) {
12096 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12097 OpenACCModifierKind::Invalid);
12098
12099 NewClause = OpenACCDeviceClause::Create(
12100 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12101 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12102 EndLoc: ParsedClause.getEndLoc());
12103}
12104
12105template <typename Derived>
12106void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12107 const OpenACCFirstPrivateClause &C) {
12108 llvm::SmallVector<Expr *> InstantiatedVarList;
12109 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12110
12111 for (const auto [RefExpr, InitRecipe] :
12112 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12113 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12114
12115 if (VarRef.isUsable()) {
12116 InstantiatedVarList.push_back(Elt: VarRef.get());
12117
12118 // We only have to create a new one if it is dependent, and Sema won't
12119 // make one of these unless the type is non-dependent.
12120 if (InitRecipe.isSet())
12121 InitRecipes.push_back(Elt: InitRecipe);
12122 else
12123 InitRecipes.push_back(
12124 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12125 VarRef.get()));
12126 }
12127 }
12128 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12129 ModKind: OpenACCModifierKind::Invalid);
12130
12131 NewClause = OpenACCFirstPrivateClause::Create(
12132 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12133 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12134 EndLoc: ParsedClause.getEndLoc());
12135}
12136
12137template <typename Derived>
12138void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12139 const OpenACCNoCreateClause &C) {
12140 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12141 OpenACCModifierKind::Invalid);
12142
12143 NewClause = OpenACCNoCreateClause::Create(
12144 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12145 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12146 EndLoc: ParsedClause.getEndLoc());
12147}
12148
12149template <typename Derived>
12150void OpenACCClauseTransform<Derived>::VisitPresentClause(
12151 const OpenACCPresentClause &C) {
12152 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12153 OpenACCModifierKind::Invalid);
12154
12155 NewClause = OpenACCPresentClause::Create(
12156 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12157 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12158 EndLoc: ParsedClause.getEndLoc());
12159}
12160
12161template <typename Derived>
12162void OpenACCClauseTransform<Derived>::VisitCopyClause(
12163 const OpenACCCopyClause &C) {
12164 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12165 C.getModifierList());
12166
12167 NewClause = OpenACCCopyClause::Create(
12168 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12169 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12170 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12171 EndLoc: ParsedClause.getEndLoc());
12172}
12173
12174template <typename Derived>
12175void OpenACCClauseTransform<Derived>::VisitLinkClause(
12176 const OpenACCLinkClause &C) {
12177 llvm_unreachable("link clause not valid unless a decl transform");
12178}
12179
12180template <typename Derived>
12181void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12182 const OpenACCDeviceResidentClause &C) {
12183 llvm_unreachable("device_resident clause not valid unless a decl transform");
12184}
12185template <typename Derived>
12186void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12187 const OpenACCNoHostClause &C) {
12188 llvm_unreachable("nohost clause not valid unless a decl transform");
12189}
12190template <typename Derived>
12191void OpenACCClauseTransform<Derived>::VisitBindClause(
12192 const OpenACCBindClause &C) {
12193 llvm_unreachable("bind clause not valid unless a decl transform");
12194}
12195
12196template <typename Derived>
12197void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12198 const OpenACCCopyInClause &C) {
12199 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12200 C.getModifierList());
12201
12202 NewClause = OpenACCCopyInClause::Create(
12203 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12204 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12205 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12206 EndLoc: ParsedClause.getEndLoc());
12207}
12208
12209template <typename Derived>
12210void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12211 const OpenACCCopyOutClause &C) {
12212 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12213 C.getModifierList());
12214
12215 NewClause = OpenACCCopyOutClause::Create(
12216 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12217 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12218 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12219 EndLoc: ParsedClause.getEndLoc());
12220}
12221
12222template <typename Derived>
12223void OpenACCClauseTransform<Derived>::VisitCreateClause(
12224 const OpenACCCreateClause &C) {
12225 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12226 C.getModifierList());
12227
12228 NewClause = OpenACCCreateClause::Create(
12229 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12230 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12231 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12232 EndLoc: ParsedClause.getEndLoc());
12233}
12234template <typename Derived>
12235void OpenACCClauseTransform<Derived>::VisitAttachClause(
12236 const OpenACCAttachClause &C) {
12237 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12238
12239 // Ensure each var is a pointer type.
12240 llvm::erase_if(VarList, [&](Expr *E) {
12241 return Self.getSema().OpenACC().CheckVarIsPointerType(
12242 OpenACCClauseKind::Attach, E);
12243 });
12244
12245 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12246 NewClause = OpenACCAttachClause::Create(
12247 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12248 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12249 EndLoc: ParsedClause.getEndLoc());
12250}
12251
12252template <typename Derived>
12253void OpenACCClauseTransform<Derived>::VisitDetachClause(
12254 const OpenACCDetachClause &C) {
12255 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12256
12257 // Ensure each var is a pointer type.
12258 llvm::erase_if(VarList, [&](Expr *E) {
12259 return Self.getSema().OpenACC().CheckVarIsPointerType(
12260 OpenACCClauseKind::Detach, E);
12261 });
12262
12263 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12264 NewClause = OpenACCDetachClause::Create(
12265 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12266 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12267 EndLoc: ParsedClause.getEndLoc());
12268}
12269
12270template <typename Derived>
12271void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12272 const OpenACCDeleteClause &C) {
12273 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12274 OpenACCModifierKind::Invalid);
12275 NewClause = OpenACCDeleteClause::Create(
12276 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12277 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12278 EndLoc: ParsedClause.getEndLoc());
12279}
12280
12281template <typename Derived>
12282void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12283 const OpenACCUseDeviceClause &C) {
12284 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12285 OpenACCModifierKind::Invalid);
12286 NewClause = OpenACCUseDeviceClause::Create(
12287 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12288 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12289 EndLoc: ParsedClause.getEndLoc());
12290}
12291
12292template <typename Derived>
12293void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12294 const OpenACCDevicePtrClause &C) {
12295 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12296
12297 // Ensure each var is a pointer type.
12298 llvm::erase_if(VarList, [&](Expr *E) {
12299 return Self.getSema().OpenACC().CheckVarIsPointerType(
12300 OpenACCClauseKind::DevicePtr, E);
12301 });
12302
12303 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12304 NewClause = OpenACCDevicePtrClause::Create(
12305 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12306 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12307 EndLoc: ParsedClause.getEndLoc());
12308}
12309
12310template <typename Derived>
12311void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12312 const OpenACCNumWorkersClause &C) {
12313 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12314 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12315
12316 ExprResult Res = Self.TransformExpr(IntExpr);
12317 if (!Res.isUsable())
12318 return;
12319
12320 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12321 C.getClauseKind(),
12322 C.getBeginLoc(), Res.get());
12323 if (!Res.isUsable())
12324 return;
12325
12326 ParsedClause.setIntExprDetails(Res.get());
12327 NewClause = OpenACCNumWorkersClause::Create(
12328 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12329 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12330 EndLoc: ParsedClause.getEndLoc());
12331}
12332
12333template <typename Derived>
12334void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12335 const OpenACCDeviceNumClause &C) {
12336 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12337 assert(IntExpr && "device_num clause constructed with invalid int expr");
12338
12339 ExprResult Res = Self.TransformExpr(IntExpr);
12340 if (!Res.isUsable())
12341 return;
12342
12343 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12344 C.getClauseKind(),
12345 C.getBeginLoc(), Res.get());
12346 if (!Res.isUsable())
12347 return;
12348
12349 ParsedClause.setIntExprDetails(Res.get());
12350 NewClause = OpenACCDeviceNumClause::Create(
12351 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12352 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12353 EndLoc: ParsedClause.getEndLoc());
12354}
12355
12356template <typename Derived>
12357void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12358 const OpenACCDefaultAsyncClause &C) {
12359 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12360 assert(IntExpr && "default_async clause constructed with invalid int expr");
12361
12362 ExprResult Res = Self.TransformExpr(IntExpr);
12363 if (!Res.isUsable())
12364 return;
12365
12366 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12367 C.getClauseKind(),
12368 C.getBeginLoc(), Res.get());
12369 if (!Res.isUsable())
12370 return;
12371
12372 ParsedClause.setIntExprDetails(Res.get());
12373 NewClause = OpenACCDefaultAsyncClause::Create(
12374 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12375 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12376 EndLoc: ParsedClause.getEndLoc());
12377}
12378
12379template <typename Derived>
12380void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12381 const OpenACCVectorLengthClause &C) {
12382 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12383 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12384
12385 ExprResult Res = Self.TransformExpr(IntExpr);
12386 if (!Res.isUsable())
12387 return;
12388
12389 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12390 C.getClauseKind(),
12391 C.getBeginLoc(), Res.get());
12392 if (!Res.isUsable())
12393 return;
12394
12395 ParsedClause.setIntExprDetails(Res.get());
12396 NewClause = OpenACCVectorLengthClause::Create(
12397 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12398 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12399 EndLoc: ParsedClause.getEndLoc());
12400}
12401
12402template <typename Derived>
12403void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12404 const OpenACCAsyncClause &C) {
12405 if (C.hasIntExpr()) {
12406 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12407 if (!Res.isUsable())
12408 return;
12409
12410 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12411 C.getClauseKind(),
12412 C.getBeginLoc(), Res.get());
12413 if (!Res.isUsable())
12414 return;
12415 ParsedClause.setIntExprDetails(Res.get());
12416 }
12417
12418 NewClause = OpenACCAsyncClause::Create(
12419 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12420 LParenLoc: ParsedClause.getLParenLoc(),
12421 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12422 : nullptr,
12423 EndLoc: ParsedClause.getEndLoc());
12424}
12425
12426template <typename Derived>
12427void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12428 const OpenACCWorkerClause &C) {
12429 if (C.hasIntExpr()) {
12430 // restrictions on this expression are all "does it exist in certain
12431 // situations" that are not possible to be dependent, so the only check we
12432 // have is that it transforms, and is an int expression.
12433 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12434 if (!Res.isUsable())
12435 return;
12436
12437 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12438 C.getClauseKind(),
12439 C.getBeginLoc(), Res.get());
12440 if (!Res.isUsable())
12441 return;
12442 ParsedClause.setIntExprDetails(Res.get());
12443 }
12444
12445 NewClause = OpenACCWorkerClause::Create(
12446 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12447 LParenLoc: ParsedClause.getLParenLoc(),
12448 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12449 : nullptr,
12450 EndLoc: ParsedClause.getEndLoc());
12451}
12452
12453template <typename Derived>
12454void OpenACCClauseTransform<Derived>::VisitVectorClause(
12455 const OpenACCVectorClause &C) {
12456 if (C.hasIntExpr()) {
12457 // restrictions on this expression are all "does it exist in certain
12458 // situations" that are not possible to be dependent, so the only check we
12459 // have is that it transforms, and is an int expression.
12460 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12461 if (!Res.isUsable())
12462 return;
12463
12464 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12465 C.getClauseKind(),
12466 C.getBeginLoc(), Res.get());
12467 if (!Res.isUsable())
12468 return;
12469 ParsedClause.setIntExprDetails(Res.get());
12470 }
12471
12472 NewClause = OpenACCVectorClause::Create(
12473 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12474 LParenLoc: ParsedClause.getLParenLoc(),
12475 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12476 : nullptr,
12477 EndLoc: ParsedClause.getEndLoc());
12478}
12479
12480template <typename Derived>
12481void OpenACCClauseTransform<Derived>::VisitWaitClause(
12482 const OpenACCWaitClause &C) {
12483 if (C.hasExprs()) {
12484 Expr *DevNumExpr = nullptr;
12485 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12486
12487 // Instantiate devnum expr if it exists.
12488 if (C.getDevNumExpr()) {
12489 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12490 if (!Res.isUsable())
12491 return;
12492 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12493 C.getClauseKind(),
12494 C.getBeginLoc(), Res.get());
12495 if (!Res.isUsable())
12496 return;
12497
12498 DevNumExpr = Res.get();
12499 }
12500
12501 // Instantiate queue ids.
12502 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12503 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12504 if (!Res.isUsable())
12505 return;
12506 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12507 C.getClauseKind(),
12508 C.getBeginLoc(), Res.get());
12509 if (!Res.isUsable())
12510 return;
12511
12512 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12513 }
12514
12515 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12516 IntExprs: std::move(InstantiatedQueueIdExprs));
12517 }
12518
12519 NewClause = OpenACCWaitClause::Create(
12520 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12521 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12522 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12523 EndLoc: ParsedClause.getEndLoc());
12524}
12525
12526template <typename Derived>
12527void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12528 const OpenACCDeviceTypeClause &C) {
12529 // Nothing to transform here, just create a new version of 'C'.
12530 NewClause = OpenACCDeviceTypeClause::Create(
12531 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12532 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12533 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12534}
12535
12536template <typename Derived>
12537void OpenACCClauseTransform<Derived>::VisitAutoClause(
12538 const OpenACCAutoClause &C) {
12539 // Nothing to do, so just create a new node.
12540 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12541 BeginLoc: ParsedClause.getBeginLoc(),
12542 EndLoc: ParsedClause.getEndLoc());
12543}
12544
12545template <typename Derived>
12546void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12547 const OpenACCIndependentClause &C) {
12548 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12549 BeginLoc: ParsedClause.getBeginLoc(),
12550 EndLoc: ParsedClause.getEndLoc());
12551}
12552
12553template <typename Derived>
12554void OpenACCClauseTransform<Derived>::VisitSeqClause(
12555 const OpenACCSeqClause &C) {
12556 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12557 BeginLoc: ParsedClause.getBeginLoc(),
12558 EndLoc: ParsedClause.getEndLoc());
12559}
12560template <typename Derived>
12561void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12562 const OpenACCFinalizeClause &C) {
12563 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12564 BeginLoc: ParsedClause.getBeginLoc(),
12565 EndLoc: ParsedClause.getEndLoc());
12566}
12567
12568template <typename Derived>
12569void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12570 const OpenACCIfPresentClause &C) {
12571 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12572 BeginLoc: ParsedClause.getBeginLoc(),
12573 EndLoc: ParsedClause.getEndLoc());
12574}
12575
12576template <typename Derived>
12577void OpenACCClauseTransform<Derived>::VisitReductionClause(
12578 const OpenACCReductionClause &C) {
12579 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12580 SmallVector<Expr *> ValidVars;
12581 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
12582
12583 for (const auto [Var, OrigRecipe] :
12584 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
12585 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12586 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12587 if (Res.isUsable()) {
12588 ValidVars.push_back(Elt: Res.get());
12589
12590 if (OrigRecipe.isSet())
12591 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
12592 else
12593 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
12594 C.getReductionOp(), Res.get()));
12595 }
12596 }
12597
12598 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12599 ExistingClauses, ParsedClause.getDirectiveKind(),
12600 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12601 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
12602}
12603
12604template <typename Derived>
12605void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12606 const OpenACCCollapseClause &C) {
12607 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12608 assert(LoopCount && "collapse clause constructed with invalid loop count");
12609
12610 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12611
12612 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12613 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12614 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12615
12616 NewLoopCount =
12617 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12618
12619 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12620 NewClause = OpenACCCollapseClause::Create(
12621 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12622 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12623 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12624}
12625
12626template <typename Derived>
12627void OpenACCClauseTransform<Derived>::VisitTileClause(
12628 const OpenACCTileClause &C) {
12629
12630 llvm::SmallVector<Expr *> TransformedExprs;
12631
12632 for (Expr *E : C.getSizeExprs()) {
12633 ExprResult NewSizeExpr = Self.TransformExpr(E);
12634
12635 if (!NewSizeExpr.isUsable())
12636 return;
12637
12638 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12639 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12640 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12641
12642 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12643
12644 if (!NewSizeExpr.isUsable())
12645 return;
12646 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12647 }
12648
12649 ParsedClause.setIntExprDetails(TransformedExprs);
12650 NewClause = OpenACCTileClause::Create(
12651 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12652 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12653 EndLoc: ParsedClause.getEndLoc());
12654}
12655template <typename Derived>
12656void OpenACCClauseTransform<Derived>::VisitGangClause(
12657 const OpenACCGangClause &C) {
12658 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12659 llvm::SmallVector<Expr *> TransformedIntExprs;
12660
12661 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12662 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12663 if (!ER.isUsable())
12664 continue;
12665
12666 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12667 ParsedClause.getDirectiveKind(),
12668 C.getExpr(I).first, ER.get());
12669 if (!ER.isUsable())
12670 continue;
12671 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12672 TransformedIntExprs.push_back(Elt: ER.get());
12673 }
12674
12675 NewClause = Self.getSema().OpenACC().CheckGangClause(
12676 ParsedClause.getDirectiveKind(), ExistingClauses,
12677 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12678 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12679}
12680} // namespace
12681template <typename Derived>
12682OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12683 ArrayRef<const OpenACCClause *> ExistingClauses,
12684 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12685
12686 SemaOpenACC::OpenACCParsedClause ParsedClause(
12687 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12688 ParsedClause.setEndLoc(OldClause->getEndLoc());
12689
12690 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12691 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12692
12693 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12694 ParsedClause};
12695 Transform.Visit(OldClause);
12696
12697 return Transform.CreatedClause();
12698}
12699
12700template <typename Derived>
12701llvm::SmallVector<OpenACCClause *>
12702TreeTransform<Derived>::TransformOpenACCClauseList(
12703 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12704 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12705 for (const auto *Clause : OldClauses) {
12706 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12707 TransformedClauses, DirKind, Clause))
12708 TransformedClauses.push_back(Elt: TransformedClause);
12709 }
12710 return TransformedClauses;
12711}
12712
12713template <typename Derived>
12714StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12715 OpenACCComputeConstruct *C) {
12716 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12717
12718 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12719 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12720 C->clauses());
12721
12722 if (getSema().OpenACC().ActOnStartStmtDirective(
12723 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12724 return StmtError();
12725
12726 // Transform Structured Block.
12727 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12728 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12729 C->clauses(), TransformedClauses);
12730 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12731 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12732 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12733
12734 return getDerived().RebuildOpenACCComputeConstruct(
12735 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12736 C->getEndLoc(), TransformedClauses, StrBlock);
12737}
12738
12739template <typename Derived>
12740StmtResult
12741TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12742
12743 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12744
12745 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12746 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12747 C->clauses());
12748
12749 if (getSema().OpenACC().ActOnStartStmtDirective(
12750 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12751 return StmtError();
12752
12753 // Transform Loop.
12754 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12755 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12756 C->clauses(), TransformedClauses);
12757 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12758 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12759 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12760
12761 return getDerived().RebuildOpenACCLoopConstruct(
12762 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12763 TransformedClauses, Loop);
12764}
12765
12766template <typename Derived>
12767StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12768 OpenACCCombinedConstruct *C) {
12769 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12770
12771 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12772 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12773 C->clauses());
12774
12775 if (getSema().OpenACC().ActOnStartStmtDirective(
12776 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12777 return StmtError();
12778
12779 // Transform Loop.
12780 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12781 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12782 C->clauses(), TransformedClauses);
12783 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12784 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12785 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12786
12787 return getDerived().RebuildOpenACCCombinedConstruct(
12788 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12789 C->getEndLoc(), TransformedClauses, Loop);
12790}
12791
12792template <typename Derived>
12793StmtResult
12794TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12795 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12796
12797 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12798 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12799 C->clauses());
12800 if (getSema().OpenACC().ActOnStartStmtDirective(
12801 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12802 return StmtError();
12803
12804 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12805 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12806 C->clauses(), TransformedClauses);
12807 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12808 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12809 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12810
12811 return getDerived().RebuildOpenACCDataConstruct(
12812 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12813 TransformedClauses, StrBlock);
12814}
12815
12816template <typename Derived>
12817StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12818 OpenACCEnterDataConstruct *C) {
12819 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12820
12821 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12822 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12823 C->clauses());
12824 if (getSema().OpenACC().ActOnStartStmtDirective(
12825 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12826 return StmtError();
12827
12828 return getDerived().RebuildOpenACCEnterDataConstruct(
12829 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12830 TransformedClauses);
12831}
12832
12833template <typename Derived>
12834StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12835 OpenACCExitDataConstruct *C) {
12836 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12837
12838 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12839 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12840 C->clauses());
12841 if (getSema().OpenACC().ActOnStartStmtDirective(
12842 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12843 return StmtError();
12844
12845 return getDerived().RebuildOpenACCExitDataConstruct(
12846 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12847 TransformedClauses);
12848}
12849
12850template <typename Derived>
12851StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12852 OpenACCHostDataConstruct *C) {
12853 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12854
12855 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12856 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12857 C->clauses());
12858 if (getSema().OpenACC().ActOnStartStmtDirective(
12859 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12860 return StmtError();
12861
12862 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12863 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12864 C->clauses(), TransformedClauses);
12865 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12866 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12867 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12868
12869 return getDerived().RebuildOpenACCHostDataConstruct(
12870 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12871 TransformedClauses, StrBlock);
12872}
12873
12874template <typename Derived>
12875StmtResult
12876TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12877 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12878
12879 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12880 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12881 C->clauses());
12882 if (getSema().OpenACC().ActOnStartStmtDirective(
12883 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12884 return StmtError();
12885
12886 return getDerived().RebuildOpenACCInitConstruct(
12887 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12888 TransformedClauses);
12889}
12890
12891template <typename Derived>
12892StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12893 OpenACCShutdownConstruct *C) {
12894 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12895
12896 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12897 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12898 C->clauses());
12899 if (getSema().OpenACC().ActOnStartStmtDirective(
12900 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12901 return StmtError();
12902
12903 return getDerived().RebuildOpenACCShutdownConstruct(
12904 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12905 TransformedClauses);
12906}
12907template <typename Derived>
12908StmtResult
12909TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12910 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12911
12912 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12913 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12914 C->clauses());
12915 if (getSema().OpenACC().ActOnStartStmtDirective(
12916 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12917 return StmtError();
12918
12919 return getDerived().RebuildOpenACCSetConstruct(
12920 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12921 TransformedClauses);
12922}
12923
12924template <typename Derived>
12925StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12926 OpenACCUpdateConstruct *C) {
12927 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12928
12929 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12930 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12931 C->clauses());
12932 if (getSema().OpenACC().ActOnStartStmtDirective(
12933 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12934 return StmtError();
12935
12936 return getDerived().RebuildOpenACCUpdateConstruct(
12937 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12938 TransformedClauses);
12939}
12940
12941template <typename Derived>
12942StmtResult
12943TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12944 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12945
12946 ExprResult DevNumExpr;
12947 if (C->hasDevNumExpr()) {
12948 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12949
12950 if (DevNumExpr.isUsable())
12951 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12952 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12953 C->getBeginLoc(), DevNumExpr.get());
12954 }
12955
12956 llvm::SmallVector<Expr *> QueueIdExprs;
12957
12958 for (Expr *QE : C->getQueueIdExprs()) {
12959 assert(QE && "Null queue id expr?");
12960 ExprResult NewEQ = getDerived().TransformExpr(QE);
12961
12962 if (!NewEQ.isUsable())
12963 break;
12964 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12965 OpenACCClauseKind::Invalid,
12966 C->getBeginLoc(), NewEQ.get());
12967 if (NewEQ.isUsable())
12968 QueueIdExprs.push_back(Elt: NewEQ.get());
12969 }
12970
12971 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12972 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12973 C->clauses());
12974
12975 if (getSema().OpenACC().ActOnStartStmtDirective(
12976 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12977 return StmtError();
12978
12979 return getDerived().RebuildOpenACCWaitConstruct(
12980 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12981 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12982 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12983}
12984template <typename Derived>
12985StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12986 OpenACCCacheConstruct *C) {
12987 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12988
12989 llvm::SmallVector<Expr *> TransformedVarList;
12990 for (Expr *Var : C->getVarList()) {
12991 assert(Var && "Null var listexpr?");
12992
12993 ExprResult NewVar = getDerived().TransformExpr(Var);
12994
12995 if (!NewVar.isUsable())
12996 break;
12997
12998 NewVar = getSema().OpenACC().ActOnVar(
12999 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13000 if (!NewVar.isUsable())
13001 break;
13002
13003 TransformedVarList.push_back(Elt: NewVar.get());
13004 }
13005
13006 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13007 C->getBeginLoc(), {}))
13008 return StmtError();
13009
13010 return getDerived().RebuildOpenACCCacheConstruct(
13011 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13012 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13013 C->getEndLoc());
13014}
13015
13016template <typename Derived>
13017StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13018 OpenACCAtomicConstruct *C) {
13019 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13020
13021 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13022 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13023 C->clauses());
13024
13025 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13026 C->getBeginLoc(), {}))
13027 return StmtError();
13028
13029 // Transform Associated Stmt.
13030 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13031 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13032
13033 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13034 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13035 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13036 AssocStmt);
13037
13038 return getDerived().RebuildOpenACCAtomicConstruct(
13039 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13040 C->getEndLoc(), TransformedClauses, AssocStmt);
13041}
13042
13043template <typename Derived>
13044ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13045 OpenACCAsteriskSizeExpr *E) {
13046 if (getDerived().AlwaysRebuild())
13047 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13048 // Nothing can ever change, so there is never anything to transform.
13049 return E;
13050}
13051
13052//===----------------------------------------------------------------------===//
13053// Expression transformation
13054//===----------------------------------------------------------------------===//
13055template<typename Derived>
13056ExprResult
13057TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13058 return TransformExpr(E: E->getSubExpr());
13059}
13060
13061template <typename Derived>
13062ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13063 SYCLUniqueStableNameExpr *E) {
13064 if (!E->isTypeDependent())
13065 return E;
13066
13067 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13068
13069 if (!NewT)
13070 return ExprError();
13071
13072 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13073 return E;
13074
13075 return getDerived().RebuildSYCLUniqueStableNameExpr(
13076 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13077}
13078
13079template <typename Derived>
13080ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13081 // TODO(reflection): Implement its transform
13082 assert(false && "not implemented yet");
13083 return ExprError();
13084}
13085
13086template<typename Derived>
13087ExprResult
13088TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13089 if (!E->isTypeDependent())
13090 return E;
13091
13092 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13093 E->getIdentKind());
13094}
13095
13096template<typename Derived>
13097ExprResult
13098TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13099 NestedNameSpecifierLoc QualifierLoc;
13100 if (E->getQualifierLoc()) {
13101 QualifierLoc
13102 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13103 if (!QualifierLoc)
13104 return ExprError();
13105 }
13106
13107 ValueDecl *ND
13108 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13109 E->getDecl()));
13110 if (!ND || ND->isInvalidDecl())
13111 return ExprError();
13112
13113 NamedDecl *Found = ND;
13114 if (E->getFoundDecl() != E->getDecl()) {
13115 Found = cast_or_null<NamedDecl>(
13116 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13117 if (!Found)
13118 return ExprError();
13119 }
13120
13121 DeclarationNameInfo NameInfo = E->getNameInfo();
13122 if (NameInfo.getName()) {
13123 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13124 if (!NameInfo.getName())
13125 return ExprError();
13126 }
13127
13128 if (!getDerived().AlwaysRebuild() &&
13129 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13130 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13131 Found == E->getFoundDecl() &&
13132 NameInfo.getName() == E->getDecl()->getDeclName() &&
13133 !E->hasExplicitTemplateArgs()) {
13134
13135 // Mark it referenced in the new context regardless.
13136 // FIXME: this is a bit instantiation-specific.
13137 SemaRef.MarkDeclRefReferenced(E);
13138
13139 return E;
13140 }
13141
13142 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13143 if (E->hasExplicitTemplateArgs()) {
13144 TemplateArgs = &TransArgs;
13145 TransArgs.setLAngleLoc(E->getLAngleLoc());
13146 TransArgs.setRAngleLoc(E->getRAngleLoc());
13147 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13148 E->getNumTemplateArgs(),
13149 TransArgs))
13150 return ExprError();
13151 }
13152
13153 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13154 Found, TemplateArgs);
13155}
13156
13157template<typename Derived>
13158ExprResult
13159TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13160 return E;
13161}
13162
13163template <typename Derived>
13164ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13165 FixedPointLiteral *E) {
13166 return E;
13167}
13168
13169template<typename Derived>
13170ExprResult
13171TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13172 return E;
13173}
13174
13175template<typename Derived>
13176ExprResult
13177TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13178 return E;
13179}
13180
13181template<typename Derived>
13182ExprResult
13183TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13184 return E;
13185}
13186
13187template<typename Derived>
13188ExprResult
13189TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13190 return E;
13191}
13192
13193template<typename Derived>
13194ExprResult
13195TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13196 return getDerived().TransformCallExpr(E);
13197}
13198
13199template<typename Derived>
13200ExprResult
13201TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13202 ExprResult ControllingExpr;
13203 TypeSourceInfo *ControllingType = nullptr;
13204 if (E->isExprPredicate())
13205 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13206 else
13207 ControllingType = getDerived().TransformType(E->getControllingType());
13208
13209 if (ControllingExpr.isInvalid() && !ControllingType)
13210 return ExprError();
13211
13212 SmallVector<Expr *, 4> AssocExprs;
13213 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13214 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13215 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13216 if (TSI) {
13217 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13218 if (!AssocType)
13219 return ExprError();
13220 AssocTypes.push_back(Elt: AssocType);
13221 } else {
13222 AssocTypes.push_back(Elt: nullptr);
13223 }
13224
13225 ExprResult AssocExpr =
13226 getDerived().TransformExpr(Assoc.getAssociationExpr());
13227 if (AssocExpr.isInvalid())
13228 return ExprError();
13229 AssocExprs.push_back(Elt: AssocExpr.get());
13230 }
13231
13232 if (!ControllingType)
13233 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13234 E->getDefaultLoc(),
13235 E->getRParenLoc(),
13236 ControllingExpr.get(),
13237 AssocTypes,
13238 AssocExprs);
13239 return getDerived().RebuildGenericSelectionExpr(
13240 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13241 ControllingType, AssocTypes, AssocExprs);
13242}
13243
13244template<typename Derived>
13245ExprResult
13246TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13247 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13248 if (SubExpr.isInvalid())
13249 return ExprError();
13250
13251 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13252 return E;
13253
13254 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13255 E->getRParen());
13256}
13257
13258/// The operand of a unary address-of operator has special rules: it's
13259/// allowed to refer to a non-static member of a class even if there's no 'this'
13260/// object available.
13261template<typename Derived>
13262ExprResult
13263TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13264 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13265 return getDerived().TransformDependentScopeDeclRefExpr(
13266 DRE, /*IsAddressOfOperand=*/true, nullptr);
13267 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13268 return getDerived().TransformUnresolvedLookupExpr(
13269 ULE, /*IsAddressOfOperand=*/true);
13270 else
13271 return getDerived().TransformExpr(E);
13272}
13273
13274template<typename Derived>
13275ExprResult
13276TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13277 ExprResult SubExpr;
13278 if (E->getOpcode() == UO_AddrOf)
13279 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13280 else
13281 SubExpr = TransformExpr(E: E->getSubExpr());
13282 if (SubExpr.isInvalid())
13283 return ExprError();
13284
13285 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13286 return E;
13287
13288 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13289 E->getOpcode(),
13290 SubExpr.get());
13291}
13292
13293template<typename Derived>
13294ExprResult
13295TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13296 // Transform the type.
13297 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13298 if (!Type)
13299 return ExprError();
13300
13301 // Transform all of the components into components similar to what the
13302 // parser uses.
13303 // FIXME: It would be slightly more efficient in the non-dependent case to
13304 // just map FieldDecls, rather than requiring the rebuilder to look for
13305 // the fields again. However, __builtin_offsetof is rare enough in
13306 // template code that we don't care.
13307 bool ExprChanged = false;
13308 typedef Sema::OffsetOfComponent Component;
13309 SmallVector<Component, 4> Components;
13310 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13311 const OffsetOfNode &ON = E->getComponent(Idx: I);
13312 Component Comp;
13313 Comp.isBrackets = true;
13314 Comp.LocStart = ON.getSourceRange().getBegin();
13315 Comp.LocEnd = ON.getSourceRange().getEnd();
13316 switch (ON.getKind()) {
13317 case OffsetOfNode::Array: {
13318 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13319 ExprResult Index = getDerived().TransformExpr(FromIndex);
13320 if (Index.isInvalid())
13321 return ExprError();
13322
13323 ExprChanged = ExprChanged || Index.get() != FromIndex;
13324 Comp.isBrackets = true;
13325 Comp.U.E = Index.get();
13326 break;
13327 }
13328
13329 case OffsetOfNode::Field:
13330 case OffsetOfNode::Identifier:
13331 Comp.isBrackets = false;
13332 Comp.U.IdentInfo = ON.getFieldName();
13333 if (!Comp.U.IdentInfo)
13334 continue;
13335
13336 break;
13337
13338 case OffsetOfNode::Base:
13339 // Will be recomputed during the rebuild.
13340 continue;
13341 }
13342
13343 Components.push_back(Elt: Comp);
13344 }
13345
13346 // If nothing changed, retain the existing expression.
13347 if (!getDerived().AlwaysRebuild() &&
13348 Type == E->getTypeSourceInfo() &&
13349 !ExprChanged)
13350 return E;
13351
13352 // Build a new offsetof expression.
13353 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13354 Components, E->getRParenLoc());
13355}
13356
13357template<typename Derived>
13358ExprResult
13359TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13360 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13361 "opaque value expression requires transformation");
13362 return E;
13363}
13364
13365template <typename Derived>
13366ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13367 llvm::SmallVector<Expr *, 8> Children;
13368 bool Changed = false;
13369 for (Expr *C : E->subExpressions()) {
13370 ExprResult NewC = getDerived().TransformExpr(C);
13371 if (NewC.isInvalid())
13372 return ExprError();
13373 Children.push_back(Elt: NewC.get());
13374
13375 Changed |= NewC.get() != C;
13376 }
13377 if (!getDerived().AlwaysRebuild() && !Changed)
13378 return E;
13379 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13380 Children, E->getType());
13381}
13382
13383template<typename Derived>
13384ExprResult
13385TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13386 // Rebuild the syntactic form. The original syntactic form has
13387 // opaque-value expressions in it, so strip those away and rebuild
13388 // the result. This is a really awful way of doing this, but the
13389 // better solution (rebuilding the semantic expressions and
13390 // rebinding OVEs as necessary) doesn't work; we'd need
13391 // TreeTransform to not strip away implicit conversions.
13392 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13393 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13394 if (result.isInvalid()) return ExprError();
13395
13396 // If that gives us a pseudo-object result back, the pseudo-object
13397 // expression must have been an lvalue-to-rvalue conversion which we
13398 // should reapply.
13399 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13400 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13401
13402 return result;
13403}
13404
13405template<typename Derived>
13406ExprResult
13407TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13408 UnaryExprOrTypeTraitExpr *E) {
13409 if (E->isArgumentType()) {
13410 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13411
13412 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13413 if (!NewT)
13414 return ExprError();
13415
13416 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13417 return E;
13418
13419 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13420 E->getKind(),
13421 E->getSourceRange());
13422 }
13423
13424 // C++0x [expr.sizeof]p1:
13425 // The operand is either an expression, which is an unevaluated operand
13426 // [...]
13427 EnterExpressionEvaluationContext Unevaluated(
13428 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13429 Sema::ReuseLambdaContextDecl);
13430
13431 // Try to recover if we have something like sizeof(T::X) where X is a type.
13432 // Notably, there must be *exactly* one set of parens if X is a type.
13433 TypeSourceInfo *RecoveryTSI = nullptr;
13434 ExprResult SubExpr;
13435 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13436 if (auto *DRE =
13437 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13438 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13439 PE, DRE, false, &RecoveryTSI);
13440 else
13441 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13442
13443 if (RecoveryTSI) {
13444 return getDerived().RebuildUnaryExprOrTypeTrait(
13445 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13446 } else if (SubExpr.isInvalid())
13447 return ExprError();
13448
13449 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13450 return E;
13451
13452 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13453 E->getOperatorLoc(),
13454 E->getKind(),
13455 E->getSourceRange());
13456}
13457
13458template<typename Derived>
13459ExprResult
13460TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13461 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13462 if (LHS.isInvalid())
13463 return ExprError();
13464
13465 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13466 if (RHS.isInvalid())
13467 return ExprError();
13468
13469
13470 if (!getDerived().AlwaysRebuild() &&
13471 LHS.get() == E->getLHS() &&
13472 RHS.get() == E->getRHS())
13473 return E;
13474
13475 return getDerived().RebuildArraySubscriptExpr(
13476 LHS.get(),
13477 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13478}
13479
13480template <typename Derived>
13481ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13482 MatrixSingleSubscriptExpr *E) {
13483 ExprResult Base = getDerived().TransformExpr(E->getBase());
13484 if (Base.isInvalid())
13485 return ExprError();
13486
13487 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13488 if (RowIdx.isInvalid())
13489 return ExprError();
13490
13491 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13492 RowIdx.get() == E->getRowIdx())
13493 return E;
13494
13495 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
13496 E->getRBracketLoc());
13497}
13498
13499template <typename Derived>
13500ExprResult
13501TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13502 ExprResult Base = getDerived().TransformExpr(E->getBase());
13503 if (Base.isInvalid())
13504 return ExprError();
13505
13506 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13507 if (RowIdx.isInvalid())
13508 return ExprError();
13509
13510 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13511 if (ColumnIdx.isInvalid())
13512 return ExprError();
13513
13514 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13515 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13516 return E;
13517
13518 return getDerived().RebuildMatrixSubscriptExpr(
13519 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13520}
13521
13522template <typename Derived>
13523ExprResult
13524TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13525 ExprResult Base = getDerived().TransformExpr(E->getBase());
13526 if (Base.isInvalid())
13527 return ExprError();
13528
13529 ExprResult LowerBound;
13530 if (E->getLowerBound()) {
13531 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13532 if (LowerBound.isInvalid())
13533 return ExprError();
13534 }
13535
13536 ExprResult Length;
13537 if (E->getLength()) {
13538 Length = getDerived().TransformExpr(E->getLength());
13539 if (Length.isInvalid())
13540 return ExprError();
13541 }
13542
13543 ExprResult Stride;
13544 if (E->isOMPArraySection()) {
13545 if (Expr *Str = E->getStride()) {
13546 Stride = getDerived().TransformExpr(Str);
13547 if (Stride.isInvalid())
13548 return ExprError();
13549 }
13550 }
13551
13552 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13553 LowerBound.get() == E->getLowerBound() &&
13554 Length.get() == E->getLength() &&
13555 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13556 return E;
13557
13558 return getDerived().RebuildArraySectionExpr(
13559 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13560 LowerBound.get(), E->getColonLocFirst(),
13561 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13562 Length.get(), Stride.get(), E->getRBracketLoc());
13563}
13564
13565template <typename Derived>
13566ExprResult
13567TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13568 ExprResult Base = getDerived().TransformExpr(E->getBase());
13569 if (Base.isInvalid())
13570 return ExprError();
13571
13572 SmallVector<Expr *, 4> Dims;
13573 bool ErrorFound = false;
13574 for (Expr *Dim : E->getDimensions()) {
13575 ExprResult DimRes = getDerived().TransformExpr(Dim);
13576 if (DimRes.isInvalid()) {
13577 ErrorFound = true;
13578 continue;
13579 }
13580 Dims.push_back(Elt: DimRes.get());
13581 }
13582
13583 if (ErrorFound)
13584 return ExprError();
13585 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13586 E->getRParenLoc(), Dims,
13587 E->getBracketsRanges());
13588}
13589
13590template <typename Derived>
13591ExprResult
13592TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13593 unsigned NumIterators = E->numOfIterators();
13594 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13595
13596 bool ErrorFound = false;
13597 bool NeedToRebuild = getDerived().AlwaysRebuild();
13598 for (unsigned I = 0; I < NumIterators; ++I) {
13599 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13600 Data[I].DeclIdent = D->getIdentifier();
13601 Data[I].DeclIdentLoc = D->getLocation();
13602 if (D->getLocation() == D->getBeginLoc()) {
13603 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13604 "Implicit type must be int.");
13605 } else {
13606 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13607 QualType DeclTy = getDerived().TransformType(D->getType());
13608 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13609 }
13610 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13611 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13612 ExprResult End = getDerived().TransformExpr(Range.End);
13613 ExprResult Step = getDerived().TransformExpr(Range.Step);
13614 ErrorFound = ErrorFound ||
13615 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13616 !Data[I].Type.get().isNull())) ||
13617 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13618 if (ErrorFound)
13619 continue;
13620 Data[I].Range.Begin = Begin.get();
13621 Data[I].Range.End = End.get();
13622 Data[I].Range.Step = Step.get();
13623 Data[I].AssignLoc = E->getAssignLoc(I);
13624 Data[I].ColonLoc = E->getColonLoc(I);
13625 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13626 NeedToRebuild =
13627 NeedToRebuild ||
13628 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13629 D->getType().getTypePtrOrNull()) ||
13630 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13631 Range.Step != Data[I].Range.Step;
13632 }
13633 if (ErrorFound)
13634 return ExprError();
13635 if (!NeedToRebuild)
13636 return E;
13637
13638 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13639 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13640 if (!Res.isUsable())
13641 return Res;
13642 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13643 for (unsigned I = 0; I < NumIterators; ++I)
13644 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13645 IE->getIteratorDecl(I));
13646 return Res;
13647}
13648
13649template<typename Derived>
13650ExprResult
13651TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13652 // Transform the callee.
13653 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13654 if (Callee.isInvalid())
13655 return ExprError();
13656
13657 // Transform arguments.
13658 bool ArgChanged = false;
13659 SmallVector<Expr*, 8> Args;
13660 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13661 &ArgChanged))
13662 return ExprError();
13663
13664 if (!getDerived().AlwaysRebuild() &&
13665 Callee.get() == E->getCallee() &&
13666 !ArgChanged)
13667 return SemaRef.MaybeBindToTemporary(E);
13668
13669 // FIXME: Wrong source location information for the '('.
13670 SourceLocation FakeLParenLoc
13671 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13672
13673 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13674 if (E->hasStoredFPFeatures()) {
13675 FPOptionsOverride NewOverrides = E->getFPFeatures();
13676 getSema().CurFPFeatures =
13677 NewOverrides.applyOverrides(getSema().getLangOpts());
13678 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13679 }
13680
13681 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13682 Args,
13683 E->getRParenLoc());
13684}
13685
13686template<typename Derived>
13687ExprResult
13688TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13689 ExprResult Base = getDerived().TransformExpr(E->getBase());
13690 if (Base.isInvalid())
13691 return ExprError();
13692
13693 NestedNameSpecifierLoc QualifierLoc;
13694 if (E->hasQualifier()) {
13695 QualifierLoc
13696 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13697
13698 if (!QualifierLoc)
13699 return ExprError();
13700 }
13701 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13702
13703 ValueDecl *Member
13704 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13705 E->getMemberDecl()));
13706 if (!Member)
13707 return ExprError();
13708
13709 NamedDecl *FoundDecl = E->getFoundDecl();
13710 if (FoundDecl == E->getMemberDecl()) {
13711 FoundDecl = Member;
13712 } else {
13713 FoundDecl = cast_or_null<NamedDecl>(
13714 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13715 if (!FoundDecl)
13716 return ExprError();
13717 }
13718
13719 if (!getDerived().AlwaysRebuild() &&
13720 Base.get() == E->getBase() &&
13721 QualifierLoc == E->getQualifierLoc() &&
13722 Member == E->getMemberDecl() &&
13723 FoundDecl == E->getFoundDecl() &&
13724 !E->hasExplicitTemplateArgs()) {
13725
13726 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13727 // for Openmp where the field need to be privatizized in the case.
13728 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13729 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13730 cast<ValueDecl>(Val: Member)))) {
13731 // Mark it referenced in the new context regardless.
13732 // FIXME: this is a bit instantiation-specific.
13733 SemaRef.MarkMemberReferenced(E);
13734 return E;
13735 }
13736 }
13737
13738 TemplateArgumentListInfo TransArgs;
13739 if (E->hasExplicitTemplateArgs()) {
13740 TransArgs.setLAngleLoc(E->getLAngleLoc());
13741 TransArgs.setRAngleLoc(E->getRAngleLoc());
13742 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13743 E->getNumTemplateArgs(),
13744 TransArgs))
13745 return ExprError();
13746 }
13747
13748 // FIXME: Bogus source location for the operator
13749 SourceLocation FakeOperatorLoc =
13750 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13751
13752 // FIXME: to do this check properly, we will need to preserve the
13753 // first-qualifier-in-scope here, just in case we had a dependent
13754 // base (and therefore couldn't do the check) and a
13755 // nested-name-qualifier (and therefore could do the lookup).
13756 NamedDecl *FirstQualifierInScope = nullptr;
13757 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13758 if (MemberNameInfo.getName()) {
13759 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13760 if (!MemberNameInfo.getName())
13761 return ExprError();
13762 }
13763
13764 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13765 E->isArrow(),
13766 QualifierLoc,
13767 TemplateKWLoc,
13768 MemberNameInfo,
13769 Member,
13770 FoundDecl,
13771 (E->hasExplicitTemplateArgs()
13772 ? &TransArgs : nullptr),
13773 FirstQualifierInScope);
13774}
13775
13776template<typename Derived>
13777ExprResult
13778TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13779 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13780 if (LHS.isInvalid())
13781 return ExprError();
13782
13783 ExprResult RHS =
13784 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13785 if (RHS.isInvalid())
13786 return ExprError();
13787
13788 if (!getDerived().AlwaysRebuild() &&
13789 LHS.get() == E->getLHS() &&
13790 RHS.get() == E->getRHS())
13791 return E;
13792
13793 if (E->isCompoundAssignmentOp())
13794 // FPFeatures has already been established from trailing storage
13795 return getDerived().RebuildBinaryOperator(
13796 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13797 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13798 FPOptionsOverride NewOverrides(E->getFPFeatures());
13799 getSema().CurFPFeatures =
13800 NewOverrides.applyOverrides(getSema().getLangOpts());
13801 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13802 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13803 LHS.get(), RHS.get());
13804}
13805
13806template <typename Derived>
13807ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13808 CXXRewrittenBinaryOperator *E) {
13809 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13810
13811 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13812 if (LHS.isInvalid())
13813 return ExprError();
13814
13815 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13816 if (RHS.isInvalid())
13817 return ExprError();
13818
13819 // Extract the already-resolved callee declarations so that we can restrict
13820 // ourselves to using them as the unqualified lookup results when rebuilding.
13821 UnresolvedSet<2> UnqualLookups;
13822 bool ChangedAnyLookups = false;
13823 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13824 const_cast<Expr *>(Decomp.InnerBinOp)};
13825 for (Expr *PossibleBinOp : PossibleBinOps) {
13826 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13827 if (!Op)
13828 continue;
13829 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13830 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13831 continue;
13832
13833 // Transform the callee in case we built a call to a local extern
13834 // declaration.
13835 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13836 E->getOperatorLoc(), Callee->getFoundDecl()));
13837 if (!Found)
13838 return ExprError();
13839 if (Found != Callee->getFoundDecl())
13840 ChangedAnyLookups = true;
13841 UnqualLookups.addDecl(D: Found);
13842 }
13843
13844 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13845 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13846 // Mark all functions used in the rewrite as referenced. Note that when
13847 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13848 // function calls, and/or there might be a user-defined conversion sequence
13849 // applied to the operands of the <.
13850 // FIXME: this is a bit instantiation-specific.
13851 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13852 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13853 return E;
13854 }
13855
13856 return getDerived().RebuildCXXRewrittenBinaryOperator(
13857 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13858}
13859
13860template<typename Derived>
13861ExprResult
13862TreeTransform<Derived>::TransformCompoundAssignOperator(
13863 CompoundAssignOperator *E) {
13864 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13865 FPOptionsOverride NewOverrides(E->getFPFeatures());
13866 getSema().CurFPFeatures =
13867 NewOverrides.applyOverrides(getSema().getLangOpts());
13868 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13869 return getDerived().TransformBinaryOperator(E);
13870}
13871
13872template<typename Derived>
13873ExprResult TreeTransform<Derived>::
13874TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13875 // Just rebuild the common and RHS expressions and see whether we
13876 // get any changes.
13877
13878 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13879 if (commonExpr.isInvalid())
13880 return ExprError();
13881
13882 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13883 if (rhs.isInvalid())
13884 return ExprError();
13885
13886 if (!getDerived().AlwaysRebuild() &&
13887 commonExpr.get() == e->getCommon() &&
13888 rhs.get() == e->getFalseExpr())
13889 return e;
13890
13891 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13892 e->getQuestionLoc(),
13893 nullptr,
13894 e->getColonLoc(),
13895 rhs.get());
13896}
13897
13898template<typename Derived>
13899ExprResult
13900TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13901 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13902 if (Cond.isInvalid())
13903 return ExprError();
13904
13905 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13906 if (LHS.isInvalid())
13907 return ExprError();
13908
13909 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13910 if (RHS.isInvalid())
13911 return ExprError();
13912
13913 if (!getDerived().AlwaysRebuild() &&
13914 Cond.get() == E->getCond() &&
13915 LHS.get() == E->getLHS() &&
13916 RHS.get() == E->getRHS())
13917 return E;
13918
13919 return getDerived().RebuildConditionalOperator(Cond.get(),
13920 E->getQuestionLoc(),
13921 LHS.get(),
13922 E->getColonLoc(),
13923 RHS.get());
13924}
13925
13926template<typename Derived>
13927ExprResult
13928TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13929 // Implicit casts are eliminated during transformation, since they
13930 // will be recomputed by semantic analysis after transformation.
13931 return getDerived().TransformExpr(E->getSubExprAsWritten());
13932}
13933
13934template<typename Derived>
13935ExprResult
13936TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13937 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13938 if (!Type)
13939 return ExprError();
13940
13941 ExprResult SubExpr
13942 = getDerived().TransformExpr(E->getSubExprAsWritten());
13943 if (SubExpr.isInvalid())
13944 return ExprError();
13945
13946 if (!getDerived().AlwaysRebuild() &&
13947 Type == E->getTypeInfoAsWritten() &&
13948 SubExpr.get() == E->getSubExpr())
13949 return E;
13950
13951 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13952 Type,
13953 E->getRParenLoc(),
13954 SubExpr.get());
13955}
13956
13957template<typename Derived>
13958ExprResult
13959TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13960 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13961 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13962 if (!NewT)
13963 return ExprError();
13964
13965 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13966 if (Init.isInvalid())
13967 return ExprError();
13968
13969 if (!getDerived().AlwaysRebuild() &&
13970 OldT == NewT &&
13971 Init.get() == E->getInitializer())
13972 return SemaRef.MaybeBindToTemporary(E);
13973
13974 // Note: the expression type doesn't necessarily match the
13975 // type-as-written, but that's okay, because it should always be
13976 // derivable from the initializer.
13977
13978 return getDerived().RebuildCompoundLiteralExpr(
13979 E->getLParenLoc(), NewT,
13980 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13981}
13982
13983template<typename Derived>
13984ExprResult
13985TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13986 ExprResult Base = getDerived().TransformExpr(E->getBase());
13987 if (Base.isInvalid())
13988 return ExprError();
13989
13990 if (!getDerived().AlwaysRebuild() &&
13991 Base.get() == E->getBase())
13992 return E;
13993
13994 // FIXME: Bad source location
13995 SourceLocation FakeOperatorLoc =
13996 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
13997 return getDerived().RebuildExtVectorOrMatrixElementExpr(
13998 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13999 E->getAccessor());
14000}
14001
14002template <typename Derived>
14003ExprResult
14004TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14005 ExprResult Base = getDerived().TransformExpr(E->getBase());
14006 if (Base.isInvalid())
14007 return ExprError();
14008
14009 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14010 return E;
14011
14012 // FIXME: Bad source location
14013 SourceLocation FakeOperatorLoc =
14014 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14015 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14016 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14017 E->getAccessor());
14018}
14019
14020template<typename Derived>
14021ExprResult
14022TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14023 if (InitListExpr *Syntactic = E->getSyntacticForm())
14024 E = Syntactic;
14025
14026 bool InitChanged = false;
14027
14028 EnterExpressionEvaluationContext Context(
14029 getSema(), EnterExpressionEvaluationContext::InitList);
14030
14031 SmallVector<Expr*, 4> Inits;
14032 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14033 Inits, &InitChanged))
14034 return ExprError();
14035
14036 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14037 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14038 // in some cases. We can't reuse it in general, because the syntactic and
14039 // semantic forms are linked, and we can't know that semantic form will
14040 // match even if the syntactic form does.
14041 }
14042
14043 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14044 E->getRBraceLoc());
14045}
14046
14047template<typename Derived>
14048ExprResult
14049TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14050 Designation Desig;
14051
14052 // transform the initializer value
14053 ExprResult Init = getDerived().TransformExpr(E->getInit());
14054 if (Init.isInvalid())
14055 return ExprError();
14056
14057 // transform the designators.
14058 SmallVector<Expr*, 4> ArrayExprs;
14059 bool ExprChanged = false;
14060 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14061 if (D.isFieldDesignator()) {
14062 if (D.getFieldDecl()) {
14063 FieldDecl *Field = cast_or_null<FieldDecl>(
14064 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14065 if (Field != D.getFieldDecl())
14066 // Rebuild the expression when the transformed FieldDecl is
14067 // different to the already assigned FieldDecl.
14068 ExprChanged = true;
14069 if (Field->isAnonymousStructOrUnion())
14070 continue;
14071 } else {
14072 // Ensure that the designator expression is rebuilt when there isn't
14073 // a resolved FieldDecl in the designator as we don't want to assign
14074 // a FieldDecl to a pattern designator that will be instantiated again.
14075 ExprChanged = true;
14076 }
14077 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14078 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14079 continue;
14080 }
14081
14082 if (D.isArrayDesignator()) {
14083 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14084 if (Index.isInvalid())
14085 return ExprError();
14086
14087 Desig.AddDesignator(
14088 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14089
14090 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14091 ArrayExprs.push_back(Elt: Index.get());
14092 continue;
14093 }
14094
14095 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14096 ExprResult Start
14097 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14098 if (Start.isInvalid())
14099 return ExprError();
14100
14101 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14102 if (End.isInvalid())
14103 return ExprError();
14104
14105 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14106 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14107
14108 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14109 End.get() != E->getArrayRangeEnd(D);
14110
14111 ArrayExprs.push_back(Elt: Start.get());
14112 ArrayExprs.push_back(Elt: End.get());
14113 }
14114
14115 if (!getDerived().AlwaysRebuild() &&
14116 Init.get() == E->getInit() &&
14117 !ExprChanged)
14118 return E;
14119
14120 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14121 E->getEqualOrColonLoc(),
14122 E->usesGNUSyntax(), Init.get());
14123}
14124
14125// Seems that if TransformInitListExpr() only works on the syntactic form of an
14126// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14127template<typename Derived>
14128ExprResult
14129TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14130 DesignatedInitUpdateExpr *E) {
14131 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14132 "initializer");
14133 return ExprError();
14134}
14135
14136template<typename Derived>
14137ExprResult
14138TreeTransform<Derived>::TransformNoInitExpr(
14139 NoInitExpr *E) {
14140 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14141 return ExprError();
14142}
14143
14144template<typename Derived>
14145ExprResult
14146TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14147 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14148 return ExprError();
14149}
14150
14151template<typename Derived>
14152ExprResult
14153TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14154 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14155 return ExprError();
14156}
14157
14158template<typename Derived>
14159ExprResult
14160TreeTransform<Derived>::TransformImplicitValueInitExpr(
14161 ImplicitValueInitExpr *E) {
14162 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14163
14164 // FIXME: Will we ever have proper type location here? Will we actually
14165 // need to transform the type?
14166 QualType T = getDerived().TransformType(E->getType());
14167 if (T.isNull())
14168 return ExprError();
14169
14170 if (!getDerived().AlwaysRebuild() &&
14171 T == E->getType())
14172 return E;
14173
14174 return getDerived().RebuildImplicitValueInitExpr(T);
14175}
14176
14177template<typename Derived>
14178ExprResult
14179TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14180 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14181 if (!TInfo)
14182 return ExprError();
14183
14184 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14185 if (SubExpr.isInvalid())
14186 return ExprError();
14187
14188 if (!getDerived().AlwaysRebuild() &&
14189 TInfo == E->getWrittenTypeInfo() &&
14190 SubExpr.get() == E->getSubExpr())
14191 return E;
14192
14193 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14194 TInfo, E->getRParenLoc());
14195}
14196
14197template<typename Derived>
14198ExprResult
14199TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14200 bool ArgumentChanged = false;
14201 SmallVector<Expr*, 4> Inits;
14202 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14203 ArgChanged: &ArgumentChanged))
14204 return ExprError();
14205
14206 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14207 Inits,
14208 E->getRParenLoc());
14209}
14210
14211/// Transform an address-of-label expression.
14212///
14213/// By default, the transformation of an address-of-label expression always
14214/// rebuilds the expression, so that the label identifier can be resolved to
14215/// the corresponding label statement by semantic analysis.
14216template<typename Derived>
14217ExprResult
14218TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14219 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14220 E->getLabel());
14221 if (!LD)
14222 return ExprError();
14223
14224 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14225 cast<LabelDecl>(Val: LD));
14226}
14227
14228template<typename Derived>
14229ExprResult
14230TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14231 SemaRef.ActOnStartStmtExpr();
14232 StmtResult SubStmt
14233 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14234 if (SubStmt.isInvalid()) {
14235 SemaRef.ActOnStmtExprError();
14236 return ExprError();
14237 }
14238
14239 unsigned OldDepth = E->getTemplateDepth();
14240 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14241
14242 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14243 SubStmt.get() == E->getSubStmt()) {
14244 // Calling this an 'error' is unintuitive, but it does the right thing.
14245 SemaRef.ActOnStmtExprError();
14246 return SemaRef.MaybeBindToTemporary(E);
14247 }
14248
14249 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14250 E->getRParenLoc(), NewDepth);
14251}
14252
14253template<typename Derived>
14254ExprResult
14255TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14256 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14257 if (Cond.isInvalid())
14258 return ExprError();
14259
14260 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14261 if (LHS.isInvalid())
14262 return ExprError();
14263
14264 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14265 if (RHS.isInvalid())
14266 return ExprError();
14267
14268 if (!getDerived().AlwaysRebuild() &&
14269 Cond.get() == E->getCond() &&
14270 LHS.get() == E->getLHS() &&
14271 RHS.get() == E->getRHS())
14272 return E;
14273
14274 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14275 Cond.get(), LHS.get(), RHS.get(),
14276 E->getRParenLoc());
14277}
14278
14279template<typename Derived>
14280ExprResult
14281TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14282 return E;
14283}
14284
14285template<typename Derived>
14286ExprResult
14287TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14288 switch (E->getOperator()) {
14289 case OO_New:
14290 case OO_Delete:
14291 case OO_Array_New:
14292 case OO_Array_Delete:
14293 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14294
14295 case OO_Subscript:
14296 case OO_Call: {
14297 // This is a call to an object's operator().
14298 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14299
14300 // Transform the object itself.
14301 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14302 if (Object.isInvalid())
14303 return ExprError();
14304
14305 // FIXME: Poor location information. Also, if the location for the end of
14306 // the token is within a macro expansion, getLocForEndOfToken() will return
14307 // an invalid source location. If that happens and we have an otherwise
14308 // valid end location, use the valid one instead of the invalid one.
14309 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14310 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14311 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14312 FakeLParenLoc = EndLoc;
14313
14314 // Transform the call arguments.
14315 SmallVector<Expr*, 8> Args;
14316 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14317 Args))
14318 return ExprError();
14319
14320 if (E->getOperator() == OO_Subscript)
14321 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14322 Args, E->getEndLoc());
14323
14324 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14325 E->getEndLoc());
14326 }
14327
14328#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14329 case OO_##Name: \
14330 break;
14331
14332#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14333#include "clang/Basic/OperatorKinds.def"
14334
14335 case OO_Conditional:
14336 llvm_unreachable("conditional operator is not actually overloadable");
14337
14338 case OO_None:
14339 case NUM_OVERLOADED_OPERATORS:
14340 llvm_unreachable("not an overloaded operator?");
14341 }
14342
14343 ExprResult First;
14344 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14345 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14346 else
14347 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14348 if (First.isInvalid())
14349 return ExprError();
14350
14351 ExprResult Second;
14352 if (E->getNumArgs() == 2) {
14353 Second =
14354 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14355 if (Second.isInvalid())
14356 return ExprError();
14357 }
14358
14359 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14360 FPOptionsOverride NewOverrides(E->getFPFeatures());
14361 getSema().CurFPFeatures =
14362 NewOverrides.applyOverrides(getSema().getLangOpts());
14363 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14364
14365 Expr *Callee = E->getCallee();
14366 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14367 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14368 Sema::LookupOrdinaryName);
14369 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14370 return ExprError();
14371
14372 return getDerived().RebuildCXXOperatorCallExpr(
14373 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14374 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14375 }
14376
14377 UnresolvedSet<1> Functions;
14378 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14379 Callee = ICE->getSubExprAsWritten();
14380 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14381 ValueDecl *VD = cast_or_null<ValueDecl>(
14382 getDerived().TransformDecl(DR->getLocation(), DR));
14383 if (!VD)
14384 return ExprError();
14385
14386 if (!isa<CXXMethodDecl>(Val: VD))
14387 Functions.addDecl(D: VD);
14388
14389 return getDerived().RebuildCXXOperatorCallExpr(
14390 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14391 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14392}
14393
14394template<typename Derived>
14395ExprResult
14396TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14397 return getDerived().TransformCallExpr(E);
14398}
14399
14400template <typename Derived>
14401ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14402 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14403 getSema().CurContext != E->getParentContext();
14404
14405 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14406 return E;
14407
14408 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14409 E->getBeginLoc(), E->getEndLoc(),
14410 getSema().CurContext);
14411}
14412
14413template <typename Derived>
14414ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14415 return E;
14416}
14417
14418template<typename Derived>
14419ExprResult
14420TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14421 // Transform the callee.
14422 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14423 if (Callee.isInvalid())
14424 return ExprError();
14425
14426 // Transform exec config.
14427 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14428 if (EC.isInvalid())
14429 return ExprError();
14430
14431 // Transform arguments.
14432 bool ArgChanged = false;
14433 SmallVector<Expr*, 8> Args;
14434 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14435 &ArgChanged))
14436 return ExprError();
14437
14438 if (!getDerived().AlwaysRebuild() &&
14439 Callee.get() == E->getCallee() &&
14440 !ArgChanged)
14441 return SemaRef.MaybeBindToTemporary(E);
14442
14443 // FIXME: Wrong source location information for the '('.
14444 SourceLocation FakeLParenLoc
14445 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14446 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14447 Args,
14448 E->getRParenLoc(), EC.get());
14449}
14450
14451template<typename Derived>
14452ExprResult
14453TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *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 return getDerived().RebuildCXXNamedCastExpr(
14468 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14469 Type, E->getAngleBrackets().getEnd(),
14470 // FIXME. this should be '(' location
14471 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14472}
14473
14474template<typename Derived>
14475ExprResult
14476TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14477 TypeSourceInfo *TSI =
14478 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14479 if (!TSI)
14480 return ExprError();
14481
14482 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14483 if (Sub.isInvalid())
14484 return ExprError();
14485
14486 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14487 Sub.get(), BCE->getEndLoc());
14488}
14489
14490template<typename Derived>
14491ExprResult
14492TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14493 return getDerived().TransformCXXNamedCastExpr(E);
14494}
14495
14496template<typename Derived>
14497ExprResult
14498TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14499 return getDerived().TransformCXXNamedCastExpr(E);
14500}
14501
14502template<typename Derived>
14503ExprResult
14504TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14505 CXXReinterpretCastExpr *E) {
14506 return getDerived().TransformCXXNamedCastExpr(E);
14507}
14508
14509template<typename Derived>
14510ExprResult
14511TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14512 return getDerived().TransformCXXNamedCastExpr(E);
14513}
14514
14515template<typename Derived>
14516ExprResult
14517TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14518 return getDerived().TransformCXXNamedCastExpr(E);
14519}
14520
14521template<typename Derived>
14522ExprResult
14523TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14524 CXXFunctionalCastExpr *E) {
14525 TypeSourceInfo *Type =
14526 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14527 if (!Type)
14528 return ExprError();
14529
14530 ExprResult SubExpr
14531 = getDerived().TransformExpr(E->getSubExprAsWritten());
14532 if (SubExpr.isInvalid())
14533 return ExprError();
14534
14535 if (!getDerived().AlwaysRebuild() &&
14536 Type == E->getTypeInfoAsWritten() &&
14537 SubExpr.get() == E->getSubExpr())
14538 return E;
14539
14540 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14541 E->getLParenLoc(),
14542 SubExpr.get(),
14543 E->getRParenLoc(),
14544 E->isListInitialization());
14545}
14546
14547template<typename Derived>
14548ExprResult
14549TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14550 if (E->isTypeOperand()) {
14551 TypeSourceInfo *TInfo
14552 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14553 if (!TInfo)
14554 return ExprError();
14555
14556 if (!getDerived().AlwaysRebuild() &&
14557 TInfo == E->getTypeOperandSourceInfo())
14558 return E;
14559
14560 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14561 TInfo, E->getEndLoc());
14562 }
14563
14564 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14565 // type. We must not unilaterally enter unevaluated context here, as then
14566 // semantic processing can re-transform an already transformed operand.
14567 Expr *Op = E->getExprOperand();
14568 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14569 if (E->isGLValue())
14570 if (auto *RD = Op->getType()->getAsCXXRecordDecl();
14571 RD && RD->isPolymorphic())
14572 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14573
14574 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14575 Sema::ReuseLambdaContextDecl);
14576
14577 ExprResult SubExpr = getDerived().TransformExpr(Op);
14578 if (SubExpr.isInvalid())
14579 return ExprError();
14580
14581 if (!getDerived().AlwaysRebuild() &&
14582 SubExpr.get() == E->getExprOperand())
14583 return E;
14584
14585 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14586 SubExpr.get(), E->getEndLoc());
14587}
14588
14589template<typename Derived>
14590ExprResult
14591TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14592 if (E->isTypeOperand()) {
14593 TypeSourceInfo *TInfo
14594 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14595 if (!TInfo)
14596 return ExprError();
14597
14598 if (!getDerived().AlwaysRebuild() &&
14599 TInfo == E->getTypeOperandSourceInfo())
14600 return E;
14601
14602 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14603 TInfo, E->getEndLoc());
14604 }
14605
14606 EnterExpressionEvaluationContext Unevaluated(
14607 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14608
14609 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14610 if (SubExpr.isInvalid())
14611 return ExprError();
14612
14613 if (!getDerived().AlwaysRebuild() &&
14614 SubExpr.get() == E->getExprOperand())
14615 return E;
14616
14617 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14618 SubExpr.get(), E->getEndLoc());
14619}
14620
14621template<typename Derived>
14622ExprResult
14623TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14624 return E;
14625}
14626
14627template<typename Derived>
14628ExprResult
14629TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14630 CXXNullPtrLiteralExpr *E) {
14631 return E;
14632}
14633
14634template<typename Derived>
14635ExprResult
14636TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14637
14638 // In lambdas, the qualifiers of the type depends of where in
14639 // the call operator `this` appear, and we do not have a good way to
14640 // rebuild this information, so we transform the type.
14641 //
14642 // In other contexts, the type of `this` may be overrided
14643 // for type deduction, so we need to recompute it.
14644 //
14645 // Always recompute the type if we're in the body of a lambda, and
14646 // 'this' is dependent on a lambda's explicit object parameter; we
14647 // also need to always rebuild the expression in this case to clear
14648 // the flag.
14649 QualType T = [&]() {
14650 auto &S = getSema();
14651 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14652 return S.getCurrentThisType();
14653 if (S.getCurLambda())
14654 return getDerived().TransformType(E->getType());
14655 return S.getCurrentThisType();
14656 }();
14657
14658 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
14659 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
14660 // Mark it referenced in the new context regardless.
14661 // FIXME: this is a bit instantiation-specific.
14662 getSema().MarkThisReferenced(E);
14663 return E;
14664 }
14665
14666 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14667}
14668
14669template<typename Derived>
14670ExprResult
14671TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14672 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14673 if (SubExpr.isInvalid())
14674 return ExprError();
14675
14676 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14677
14678 if (!getDerived().AlwaysRebuild() &&
14679 SubExpr.get() == E->getSubExpr())
14680 return E;
14681
14682 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14683 E->isThrownVariableInScope());
14684}
14685
14686template<typename Derived>
14687ExprResult
14688TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14689 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14690 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14691 if (!Param)
14692 return ExprError();
14693
14694 ExprResult InitRes;
14695 if (E->hasRewrittenInit()) {
14696 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14697 if (InitRes.isInvalid())
14698 return ExprError();
14699 }
14700
14701 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14702 E->getUsedContext() == SemaRef.CurContext &&
14703 InitRes.get() == E->getRewrittenExpr())
14704 return E;
14705
14706 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14707 InitRes.get());
14708}
14709
14710template<typename Derived>
14711ExprResult
14712TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14713 FieldDecl *Field = cast_or_null<FieldDecl>(
14714 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14715 if (!Field)
14716 return ExprError();
14717
14718 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14719 E->getUsedContext() == SemaRef.CurContext)
14720 return E;
14721
14722 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14723}
14724
14725template<typename Derived>
14726ExprResult
14727TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14728 CXXScalarValueInitExpr *E) {
14729 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14730 if (!T)
14731 return ExprError();
14732
14733 if (!getDerived().AlwaysRebuild() &&
14734 T == E->getTypeSourceInfo())
14735 return E;
14736
14737 return getDerived().RebuildCXXScalarValueInitExpr(T,
14738 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14739 E->getRParenLoc());
14740}
14741
14742template<typename Derived>
14743ExprResult
14744TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14745 // Transform the type that we're allocating
14746 TypeSourceInfo *AllocTypeInfo =
14747 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14748 if (!AllocTypeInfo)
14749 return ExprError();
14750
14751 // Transform the size of the array we're allocating (if any).
14752 std::optional<Expr *> ArraySize;
14753 if (E->isArray()) {
14754 ExprResult NewArraySize;
14755 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14756 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14757 if (NewArraySize.isInvalid())
14758 return ExprError();
14759 }
14760 ArraySize = NewArraySize.get();
14761 }
14762
14763 // Transform the placement arguments (if any).
14764 bool ArgumentChanged = false;
14765 SmallVector<Expr*, 8> PlacementArgs;
14766 if (getDerived().TransformExprs(E->getPlacementArgs(),
14767 E->getNumPlacementArgs(), true,
14768 PlacementArgs, &ArgumentChanged))
14769 return ExprError();
14770
14771 // Transform the initializer (if any).
14772 Expr *OldInit = E->getInitializer();
14773 ExprResult NewInit;
14774 if (OldInit)
14775 NewInit = getDerived().TransformInitializer(OldInit, true);
14776 if (NewInit.isInvalid())
14777 return ExprError();
14778
14779 // Transform new operator and delete operator.
14780 FunctionDecl *OperatorNew = nullptr;
14781 if (E->getOperatorNew()) {
14782 OperatorNew = cast_or_null<FunctionDecl>(
14783 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14784 if (!OperatorNew)
14785 return ExprError();
14786 }
14787
14788 FunctionDecl *OperatorDelete = nullptr;
14789 if (E->getOperatorDelete()) {
14790 OperatorDelete = cast_or_null<FunctionDecl>(
14791 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14792 if (!OperatorDelete)
14793 return ExprError();
14794 }
14795
14796 if (!getDerived().AlwaysRebuild() &&
14797 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14798 ArraySize == E->getArraySize() &&
14799 NewInit.get() == OldInit &&
14800 OperatorNew == E->getOperatorNew() &&
14801 OperatorDelete == E->getOperatorDelete() &&
14802 !ArgumentChanged) {
14803 // Mark any declarations we need as referenced.
14804 // FIXME: instantiation-specific.
14805 if (OperatorNew)
14806 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14807 if (OperatorDelete)
14808 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14809
14810 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14811 QualType ElementType
14812 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14813 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
14814 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
14815 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14816 }
14817 }
14818
14819 return E;
14820 }
14821
14822 QualType AllocType = AllocTypeInfo->getType();
14823 if (!ArraySize) {
14824 // If no array size was specified, but the new expression was
14825 // instantiated with an array type (e.g., "new T" where T is
14826 // instantiated with "int[4]"), extract the outer bound from the
14827 // array type as our array size. We do this with constant and
14828 // dependently-sized array types.
14829 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14830 if (!ArrayT) {
14831 // Do nothing
14832 } else if (const ConstantArrayType *ConsArrayT
14833 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14834 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14835 type: SemaRef.Context.getSizeType(),
14836 /*FIXME:*/ l: E->getBeginLoc());
14837 AllocType = ConsArrayT->getElementType();
14838 } else if (const DependentSizedArrayType *DepArrayT
14839 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14840 if (DepArrayT->getSizeExpr()) {
14841 ArraySize = DepArrayT->getSizeExpr();
14842 AllocType = DepArrayT->getElementType();
14843 }
14844 }
14845 }
14846
14847 return getDerived().RebuildCXXNewExpr(
14848 E->getBeginLoc(), E->isGlobalNew(),
14849 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14850 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14851 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14852}
14853
14854template<typename Derived>
14855ExprResult
14856TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14857 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14858 if (Operand.isInvalid())
14859 return ExprError();
14860
14861 // Transform the delete operator, if known.
14862 FunctionDecl *OperatorDelete = nullptr;
14863 if (E->getOperatorDelete()) {
14864 OperatorDelete = cast_or_null<FunctionDecl>(
14865 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14866 if (!OperatorDelete)
14867 return ExprError();
14868 }
14869
14870 if (!getDerived().AlwaysRebuild() &&
14871 Operand.get() == E->getArgument() &&
14872 OperatorDelete == E->getOperatorDelete()) {
14873 // Mark any declarations we need as referenced.
14874 // FIXME: instantiation-specific.
14875 if (OperatorDelete)
14876 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14877
14878 if (!E->getArgument()->isTypeDependent()) {
14879 QualType Destroyed = SemaRef.Context.getBaseElementType(
14880 QT: E->getDestroyedType());
14881 if (auto *Record = Destroyed->getAsCXXRecordDecl())
14882 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14883 Func: SemaRef.LookupDestructor(Class: Record));
14884 }
14885
14886 return E;
14887 }
14888
14889 return getDerived().RebuildCXXDeleteExpr(
14890 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14891}
14892
14893template<typename Derived>
14894ExprResult
14895TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14896 CXXPseudoDestructorExpr *E) {
14897 ExprResult Base = getDerived().TransformExpr(E->getBase());
14898 if (Base.isInvalid())
14899 return ExprError();
14900
14901 ParsedType ObjectTypePtr;
14902 bool MayBePseudoDestructor = false;
14903 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14904 OpLoc: E->getOperatorLoc(),
14905 OpKind: E->isArrow()? tok::arrow : tok::period,
14906 ObjectType&: ObjectTypePtr,
14907 MayBePseudoDestructor);
14908 if (Base.isInvalid())
14909 return ExprError();
14910
14911 QualType ObjectType = ObjectTypePtr.get();
14912 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14913 if (QualifierLoc) {
14914 QualifierLoc
14915 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14916 if (!QualifierLoc)
14917 return ExprError();
14918 }
14919 CXXScopeSpec SS;
14920 SS.Adopt(Other: QualifierLoc);
14921
14922 PseudoDestructorTypeStorage Destroyed;
14923 if (E->getDestroyedTypeInfo()) {
14924 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
14925 E->getDestroyedTypeInfo(), ObjectType,
14926 /*FirstQualifierInScope=*/nullptr);
14927 if (!DestroyedTypeInfo)
14928 return ExprError();
14929 Destroyed = DestroyedTypeInfo;
14930 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14931 // We aren't likely to be able to resolve the identifier down to a type
14932 // now anyway, so just retain the identifier.
14933 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14934 E->getDestroyedTypeLoc());
14935 } else {
14936 // Look for a destructor known with the given name.
14937 ParsedType T = SemaRef.getDestructorName(
14938 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14939 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14940 if (!T)
14941 return ExprError();
14942
14943 Destroyed
14944 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14945 Loc: E->getDestroyedTypeLoc());
14946 }
14947
14948 TypeSourceInfo *ScopeTypeInfo = nullptr;
14949 if (E->getScopeTypeInfo()) {
14950 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14951 E->getScopeTypeInfo(), ObjectType, nullptr);
14952 if (!ScopeTypeInfo)
14953 return ExprError();
14954 }
14955
14956 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14957 E->getOperatorLoc(),
14958 E->isArrow(),
14959 SS,
14960 ScopeTypeInfo,
14961 E->getColonColonLoc(),
14962 E->getTildeLoc(),
14963 Destroyed);
14964}
14965
14966template <typename Derived>
14967bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14968 bool RequiresADL,
14969 LookupResult &R) {
14970 // Transform all the decls.
14971 bool AllEmptyPacks = true;
14972 for (auto *OldD : Old->decls()) {
14973 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14974 if (!InstD) {
14975 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14976 // This can happen because of dependent hiding.
14977 if (isa<UsingShadowDecl>(Val: OldD))
14978 continue;
14979 else {
14980 R.clear();
14981 return true;
14982 }
14983 }
14984
14985 // Expand using pack declarations.
14986 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
14987 ArrayRef<NamedDecl*> Decls = SingleDecl;
14988 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
14989 Decls = UPD->expansions();
14990
14991 // Expand using declarations.
14992 for (auto *D : Decls) {
14993 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
14994 for (auto *SD : UD->shadows())
14995 R.addDecl(D: SD);
14996 } else {
14997 R.addDecl(D);
14998 }
14999 }
15000
15001 AllEmptyPacks &= Decls.empty();
15002 }
15003
15004 // C++ [temp.res]/8.4.2:
15005 // The program is ill-formed, no diagnostic required, if [...] lookup for
15006 // a name in the template definition found a using-declaration, but the
15007 // lookup in the corresponding scope in the instantiation odoes not find
15008 // any declarations because the using-declaration was a pack expansion and
15009 // the corresponding pack is empty
15010 if (AllEmptyPacks && !RequiresADL) {
15011 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15012 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15013 return true;
15014 }
15015
15016 // Resolve a kind, but don't do any further analysis. If it's
15017 // ambiguous, the callee needs to deal with it.
15018 R.resolveKind();
15019
15020 if (Old->hasTemplateKeyword() && !R.empty()) {
15021 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15022 getSema().FilterAcceptableTemplateNames(R,
15023 /*AllowFunctionTemplates=*/true,
15024 /*AllowDependent=*/true);
15025 if (R.empty()) {
15026 // If a 'template' keyword was used, a lookup that finds only non-template
15027 // names is an error.
15028 getSema().Diag(R.getNameLoc(),
15029 diag::err_template_kw_refers_to_non_template)
15030 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15031 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15032 getSema().Diag(FoundDecl->getLocation(),
15033 diag::note_template_kw_refers_to_non_template)
15034 << R.getLookupName();
15035 return true;
15036 }
15037 }
15038
15039 return false;
15040}
15041
15042template <typename Derived>
15043ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15044 UnresolvedLookupExpr *Old) {
15045 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15046}
15047
15048template <typename Derived>
15049ExprResult
15050TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15051 bool IsAddressOfOperand) {
15052 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15053 Sema::LookupOrdinaryName);
15054
15055 // Transform the declaration set.
15056 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15057 return ExprError();
15058
15059 // Rebuild the nested-name qualifier, if present.
15060 CXXScopeSpec SS;
15061 if (Old->getQualifierLoc()) {
15062 NestedNameSpecifierLoc QualifierLoc
15063 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15064 if (!QualifierLoc)
15065 return ExprError();
15066
15067 SS.Adopt(Other: QualifierLoc);
15068 }
15069
15070 if (Old->getNamingClass()) {
15071 CXXRecordDecl *NamingClass
15072 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15073 Old->getNameLoc(),
15074 Old->getNamingClass()));
15075 if (!NamingClass) {
15076 R.clear();
15077 return ExprError();
15078 }
15079
15080 R.setNamingClass(NamingClass);
15081 }
15082
15083 // Rebuild the template arguments, if any.
15084 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15085 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15086 if (Old->hasExplicitTemplateArgs() &&
15087 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15088 Old->getNumTemplateArgs(),
15089 TransArgs)) {
15090 R.clear();
15091 return ExprError();
15092 }
15093
15094 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15095 // a non-static data member is named in an unevaluated operand, or when
15096 // a member is named in a dependent class scope function template explicit
15097 // specialization that is neither declared static nor with an explicit object
15098 // parameter.
15099 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15100 return SemaRef.BuildPossibleImplicitMemberExpr(
15101 SS, TemplateKWLoc, R,
15102 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15103 /*S=*/S: nullptr);
15104
15105 // If we have neither explicit template arguments, nor the template keyword,
15106 // it's a normal declaration name or member reference.
15107 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15108 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15109
15110 // If we have template arguments, then rebuild the template-id expression.
15111 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15112 Old->requiresADL(), &TransArgs);
15113}
15114
15115template<typename Derived>
15116ExprResult
15117TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15118 bool ArgChanged = false;
15119 SmallVector<TypeSourceInfo *, 4> Args;
15120 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15121 TypeSourceInfo *From = E->getArg(I);
15122 TypeLoc FromTL = From->getTypeLoc();
15123 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15124 TypeLocBuilder TLB;
15125 TLB.reserve(Requested: FromTL.getFullDataSize());
15126 QualType To = getDerived().TransformType(TLB, FromTL);
15127 if (To.isNull())
15128 return ExprError();
15129
15130 if (To == From->getType())
15131 Args.push_back(Elt: From);
15132 else {
15133 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15134 ArgChanged = true;
15135 }
15136 continue;
15137 }
15138
15139 ArgChanged = true;
15140
15141 // We have a pack expansion. Instantiate it.
15142 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15143 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15144 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15145 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15146
15147 // Determine whether the set of unexpanded parameter packs can and should
15148 // be expanded.
15149 bool Expand = true;
15150 bool RetainExpansion = false;
15151 UnsignedOrNone OrigNumExpansions =
15152 ExpansionTL.getTypePtr()->getNumExpansions();
15153 UnsignedOrNone NumExpansions = OrigNumExpansions;
15154 if (getDerived().TryExpandParameterPacks(
15155 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15156 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15157 RetainExpansion, NumExpansions))
15158 return ExprError();
15159
15160 if (!Expand) {
15161 // The transform has determined that we should perform a simple
15162 // transformation on the pack expansion, producing another pack
15163 // expansion.
15164 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15165
15166 TypeLocBuilder TLB;
15167 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15168
15169 QualType To = getDerived().TransformType(TLB, PatternTL);
15170 if (To.isNull())
15171 return ExprError();
15172
15173 To = getDerived().RebuildPackExpansionType(To,
15174 PatternTL.getSourceRange(),
15175 ExpansionTL.getEllipsisLoc(),
15176 NumExpansions);
15177 if (To.isNull())
15178 return ExprError();
15179
15180 PackExpansionTypeLoc ToExpansionTL
15181 = TLB.push<PackExpansionTypeLoc>(T: To);
15182 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15183 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15184 continue;
15185 }
15186
15187 // Expand the pack expansion by substituting for each argument in the
15188 // pack(s).
15189 for (unsigned I = 0; I != *NumExpansions; ++I) {
15190 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15191 TypeLocBuilder TLB;
15192 TLB.reserve(Requested: PatternTL.getFullDataSize());
15193 QualType To = getDerived().TransformType(TLB, PatternTL);
15194 if (To.isNull())
15195 return ExprError();
15196
15197 if (To->containsUnexpandedParameterPack()) {
15198 To = getDerived().RebuildPackExpansionType(To,
15199 PatternTL.getSourceRange(),
15200 ExpansionTL.getEllipsisLoc(),
15201 NumExpansions);
15202 if (To.isNull())
15203 return ExprError();
15204
15205 PackExpansionTypeLoc ToExpansionTL
15206 = TLB.push<PackExpansionTypeLoc>(T: To);
15207 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15208 }
15209
15210 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15211 }
15212
15213 if (!RetainExpansion)
15214 continue;
15215
15216 // If we're supposed to retain a pack expansion, do so by temporarily
15217 // forgetting the partially-substituted parameter pack.
15218 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15219
15220 TypeLocBuilder TLB;
15221 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15222
15223 QualType To = getDerived().TransformType(TLB, PatternTL);
15224 if (To.isNull())
15225 return ExprError();
15226
15227 To = getDerived().RebuildPackExpansionType(To,
15228 PatternTL.getSourceRange(),
15229 ExpansionTL.getEllipsisLoc(),
15230 NumExpansions);
15231 if (To.isNull())
15232 return ExprError();
15233
15234 PackExpansionTypeLoc ToExpansionTL
15235 = TLB.push<PackExpansionTypeLoc>(T: To);
15236 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15237 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15238 }
15239
15240 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15241 return E;
15242
15243 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15244 E->getEndLoc());
15245}
15246
15247template<typename Derived>
15248ExprResult
15249TreeTransform<Derived>::TransformConceptSpecializationExpr(
15250 ConceptSpecializationExpr *E) {
15251 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15252 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15253 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15254 Old->NumTemplateArgs, TransArgs))
15255 return ExprError();
15256
15257 return getDerived().RebuildConceptSpecializationExpr(
15258 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15259 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
15260 &TransArgs);
15261}
15262
15263template<typename Derived>
15264ExprResult
15265TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15266 SmallVector<ParmVarDecl*, 4> TransParams;
15267 SmallVector<QualType, 4> TransParamTypes;
15268 Sema::ExtParameterInfoBuilder ExtParamInfos;
15269
15270 // C++2a [expr.prim.req]p2
15271 // Expressions appearing within a requirement-body are unevaluated operands.
15272 EnterExpressionEvaluationContext Ctx(
15273 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15274 Sema::ReuseLambdaContextDecl);
15275
15276 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15277 C&: getSema().Context, DC: getSema().CurContext,
15278 StartLoc: E->getBody()->getBeginLoc());
15279
15280 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15281
15282 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15283 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15284 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15285
15286 for (ParmVarDecl *Param : TransParams)
15287 if (Param)
15288 Param->setDeclContext(Body);
15289
15290 // On failure to transform, TransformRequiresTypeParams returns an expression
15291 // in the event that the transformation of the type params failed in some way.
15292 // It is expected that this will result in a 'not satisfied' Requires clause
15293 // when instantiating.
15294 if (!TypeParamResult.isUnset())
15295 return TypeParamResult;
15296
15297 SmallVector<concepts::Requirement *, 4> TransReqs;
15298 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15299 TransReqs))
15300 return ExprError();
15301
15302 for (concepts::Requirement *Req : TransReqs) {
15303 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15304 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15305 ER->getReturnTypeRequirement()
15306 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15307 ->setDeclContext(Body);
15308 }
15309 }
15310 }
15311
15312 return getDerived().RebuildRequiresExpr(
15313 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15314 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15315}
15316
15317template<typename Derived>
15318bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15319 ArrayRef<concepts::Requirement *> Reqs,
15320 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15321 for (concepts::Requirement *Req : Reqs) {
15322 concepts::Requirement *TransReq = nullptr;
15323 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15324 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15325 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15326 TransReq = getDerived().TransformExprRequirement(ExprReq);
15327 else
15328 TransReq = getDerived().TransformNestedRequirement(
15329 cast<concepts::NestedRequirement>(Val: Req));
15330 if (!TransReq)
15331 return true;
15332 Transformed.push_back(Elt: TransReq);
15333 }
15334 return false;
15335}
15336
15337template<typename Derived>
15338concepts::TypeRequirement *
15339TreeTransform<Derived>::TransformTypeRequirement(
15340 concepts::TypeRequirement *Req) {
15341 if (Req->isSubstitutionFailure()) {
15342 if (getDerived().AlwaysRebuild())
15343 return getDerived().RebuildTypeRequirement(
15344 Req->getSubstitutionDiagnostic());
15345 return Req;
15346 }
15347 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15348 if (!TransType)
15349 return nullptr;
15350 return getDerived().RebuildTypeRequirement(TransType);
15351}
15352
15353template<typename Derived>
15354concepts::ExprRequirement *
15355TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15356 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15357 if (Req->isExprSubstitutionFailure())
15358 TransExpr = Req->getExprSubstitutionDiagnostic();
15359 else {
15360 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15361 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15362 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15363 if (TransExprRes.isInvalid())
15364 return nullptr;
15365 TransExpr = TransExprRes.get();
15366 }
15367
15368 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15369 const auto &RetReq = Req->getReturnTypeRequirement();
15370 if (RetReq.isEmpty())
15371 TransRetReq.emplace();
15372 else if (RetReq.isSubstitutionFailure())
15373 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15374 else if (RetReq.isTypeConstraint()) {
15375 TemplateParameterList *OrigTPL =
15376 RetReq.getTypeConstraintTemplateParameterList();
15377 TemplateParameterList *TPL =
15378 getDerived().TransformTemplateParameterList(OrigTPL);
15379 if (!TPL)
15380 return nullptr;
15381 TransRetReq.emplace(args&: TPL);
15382 }
15383 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15384 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15385 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15386 Req->getNoexceptLoc(),
15387 std::move(*TransRetReq));
15388 return getDerived().RebuildExprRequirement(
15389 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15390 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15391}
15392
15393template<typename Derived>
15394concepts::NestedRequirement *
15395TreeTransform<Derived>::TransformNestedRequirement(
15396 concepts::NestedRequirement *Req) {
15397 if (Req->hasInvalidConstraint()) {
15398 if (getDerived().AlwaysRebuild())
15399 return getDerived().RebuildNestedRequirement(
15400 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15401 return Req;
15402 }
15403 ExprResult TransConstraint =
15404 getDerived().TransformExpr(Req->getConstraintExpr());
15405 if (TransConstraint.isInvalid())
15406 return nullptr;
15407 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15408}
15409
15410template<typename Derived>
15411ExprResult
15412TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15413 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15414 if (!T)
15415 return ExprError();
15416
15417 if (!getDerived().AlwaysRebuild() &&
15418 T == E->getQueriedTypeSourceInfo())
15419 return E;
15420
15421 ExprResult SubExpr;
15422 {
15423 EnterExpressionEvaluationContext Unevaluated(
15424 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15425 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15426 if (SubExpr.isInvalid())
15427 return ExprError();
15428 }
15429
15430 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15431 SubExpr.get(), E->getEndLoc());
15432}
15433
15434template<typename Derived>
15435ExprResult
15436TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15437 ExprResult SubExpr;
15438 {
15439 EnterExpressionEvaluationContext Unevaluated(
15440 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15441 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15442 if (SubExpr.isInvalid())
15443 return ExprError();
15444
15445 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15446 return E;
15447 }
15448
15449 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15450 SubExpr.get(), E->getEndLoc());
15451}
15452
15453template <typename Derived>
15454ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15455 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15456 TypeSourceInfo **RecoveryTSI) {
15457 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15458 DRE, AddrTaken, RecoveryTSI);
15459
15460 // Propagate both errors and recovered types, which return ExprEmpty.
15461 if (!NewDRE.isUsable())
15462 return NewDRE;
15463
15464 // We got an expr, wrap it up in parens.
15465 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15466 return PE;
15467 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15468 PE->getRParen());
15469}
15470
15471template <typename Derived>
15472ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15473 DependentScopeDeclRefExpr *E) {
15474 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15475 nullptr);
15476}
15477
15478template <typename Derived>
15479ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15480 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15481 TypeSourceInfo **RecoveryTSI) {
15482 assert(E->getQualifierLoc());
15483 NestedNameSpecifierLoc QualifierLoc =
15484 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15485 if (!QualifierLoc)
15486 return ExprError();
15487 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15488
15489 // TODO: If this is a conversion-function-id, verify that the
15490 // destination type name (if present) resolves the same way after
15491 // instantiation as it did in the local scope.
15492
15493 DeclarationNameInfo NameInfo =
15494 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15495 if (!NameInfo.getName())
15496 return ExprError();
15497
15498 if (!E->hasExplicitTemplateArgs()) {
15499 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15500 // Note: it is sufficient to compare the Name component of NameInfo:
15501 // if name has not changed, DNLoc has not changed either.
15502 NameInfo.getName() == E->getDeclName())
15503 return E;
15504
15505 return getDerived().RebuildDependentScopeDeclRefExpr(
15506 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15507 IsAddressOfOperand, RecoveryTSI);
15508 }
15509
15510 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15511 if (getDerived().TransformTemplateArguments(
15512 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15513 return ExprError();
15514
15515 return getDerived().RebuildDependentScopeDeclRefExpr(
15516 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15517 RecoveryTSI);
15518}
15519
15520template<typename Derived>
15521ExprResult
15522TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15523 // CXXConstructExprs other than for list-initialization and
15524 // CXXTemporaryObjectExpr are always implicit, so when we have
15525 // a 1-argument construction we just transform that argument.
15526 if (getDerived().AllowSkippingCXXConstructExpr() &&
15527 ((E->getNumArgs() == 1 ||
15528 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15529 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15530 !E->isListInitialization()))
15531 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15532 /*DirectInit*/ false);
15533
15534 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15535
15536 QualType T = getDerived().TransformType(E->getType());
15537 if (T.isNull())
15538 return ExprError();
15539
15540 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15541 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15542 if (!Constructor)
15543 return ExprError();
15544
15545 bool ArgumentChanged = false;
15546 SmallVector<Expr*, 8> Args;
15547 {
15548 EnterExpressionEvaluationContext Context(
15549 getSema(), EnterExpressionEvaluationContext::InitList,
15550 E->isListInitialization());
15551 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15552 &ArgumentChanged))
15553 return ExprError();
15554 }
15555
15556 if (!getDerived().AlwaysRebuild() &&
15557 T == E->getType() &&
15558 Constructor == E->getConstructor() &&
15559 !ArgumentChanged) {
15560 // Mark the constructor as referenced.
15561 // FIXME: Instantiation-specific
15562 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15563 return E;
15564 }
15565
15566 return getDerived().RebuildCXXConstructExpr(
15567 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15568 E->hadMultipleCandidates(), E->isListInitialization(),
15569 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15570 E->getConstructionKind(), E->getParenOrBraceRange());
15571}
15572
15573template<typename Derived>
15574ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15575 CXXInheritedCtorInitExpr *E) {
15576 QualType T = getDerived().TransformType(E->getType());
15577 if (T.isNull())
15578 return ExprError();
15579
15580 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15581 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15582 if (!Constructor)
15583 return ExprError();
15584
15585 if (!getDerived().AlwaysRebuild() &&
15586 T == E->getType() &&
15587 Constructor == E->getConstructor()) {
15588 // Mark the constructor as referenced.
15589 // FIXME: Instantiation-specific
15590 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15591 return E;
15592 }
15593
15594 return getDerived().RebuildCXXInheritedCtorInitExpr(
15595 T, E->getLocation(), Constructor,
15596 E->constructsVBase(), E->inheritedFromVBase());
15597}
15598
15599/// Transform a C++ temporary-binding expression.
15600///
15601/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15602/// transform the subexpression and return that.
15603template<typename Derived>
15604ExprResult
15605TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15606 if (auto *Dtor = E->getTemporary()->getDestructor())
15607 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15608 Func: const_cast<CXXDestructorDecl *>(Dtor));
15609 return getDerived().TransformExpr(E->getSubExpr());
15610}
15611
15612/// Transform a C++ expression that contains cleanups that should
15613/// be run after the expression is evaluated.
15614///
15615/// Since ExprWithCleanups nodes are implicitly generated, we
15616/// just transform the subexpression and return that.
15617template<typename Derived>
15618ExprResult
15619TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15620 return getDerived().TransformExpr(E->getSubExpr());
15621}
15622
15623template<typename Derived>
15624ExprResult
15625TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15626 CXXTemporaryObjectExpr *E) {
15627 TypeSourceInfo *T =
15628 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15629 if (!T)
15630 return ExprError();
15631
15632 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15633 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15634 if (!Constructor)
15635 return ExprError();
15636
15637 bool ArgumentChanged = false;
15638 SmallVector<Expr*, 8> Args;
15639 Args.reserve(N: E->getNumArgs());
15640 {
15641 EnterExpressionEvaluationContext Context(
15642 getSema(), EnterExpressionEvaluationContext::InitList,
15643 E->isListInitialization());
15644 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15645 ArgChanged: &ArgumentChanged))
15646 return ExprError();
15647
15648 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15649 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15650 if (Res.isInvalid())
15651 return ExprError();
15652 Args = {Res.get()};
15653 }
15654 }
15655
15656 if (!getDerived().AlwaysRebuild() &&
15657 T == E->getTypeSourceInfo() &&
15658 Constructor == E->getConstructor() &&
15659 !ArgumentChanged) {
15660 // FIXME: Instantiation-specific
15661 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15662 return SemaRef.MaybeBindToTemporary(E);
15663 }
15664
15665 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15666 return getDerived().RebuildCXXTemporaryObjectExpr(
15667 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15668}
15669
15670template<typename Derived>
15671ExprResult
15672TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15673 // Transform any init-capture expressions before entering the scope of the
15674 // lambda body, because they are not semantically within that scope.
15675 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15676 struct TransformedInitCapture {
15677 // The location of the ... if the result is retaining a pack expansion.
15678 SourceLocation EllipsisLoc;
15679 // Zero or more expansions of the init-capture.
15680 SmallVector<InitCaptureInfoTy, 4> Expansions;
15681 };
15682 SmallVector<TransformedInitCapture, 4> InitCaptures;
15683 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15684 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15685 CEnd = E->capture_end();
15686 C != CEnd; ++C) {
15687 if (!E->isInitCapture(Capture: C))
15688 continue;
15689
15690 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15691 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15692
15693 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15694 UnsignedOrNone NumExpansions) {
15695 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15696 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15697
15698 if (NewExprInitResult.isInvalid()) {
15699 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15700 return;
15701 }
15702 Expr *NewExprInit = NewExprInitResult.get();
15703
15704 QualType NewInitCaptureType =
15705 getSema().buildLambdaInitCaptureInitialization(
15706 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15707 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15708 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15709 VarDecl::CInit,
15710 NewExprInit);
15711 Result.Expansions.push_back(
15712 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15713 };
15714
15715 // If this is an init-capture pack, consider expanding the pack now.
15716 if (OldVD->isParameterPack()) {
15717 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15718 ->getTypeLoc()
15719 .castAs<PackExpansionTypeLoc>();
15720 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15721 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15722
15723 // Determine whether the set of unexpanded parameter packs can and should
15724 // be expanded.
15725 bool Expand = true;
15726 bool RetainExpansion = false;
15727 UnsignedOrNone OrigNumExpansions =
15728 ExpansionTL.getTypePtr()->getNumExpansions();
15729 UnsignedOrNone NumExpansions = OrigNumExpansions;
15730 if (getDerived().TryExpandParameterPacks(
15731 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
15732 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15733 RetainExpansion, NumExpansions))
15734 return ExprError();
15735 assert(!RetainExpansion && "Should not need to retain expansion after a "
15736 "capture since it cannot be extended");
15737 if (Expand) {
15738 for (unsigned I = 0; I != *NumExpansions; ++I) {
15739 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15740 SubstInitCapture(SourceLocation(), std::nullopt);
15741 }
15742 } else {
15743 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15744 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15745 }
15746 } else {
15747 SubstInitCapture(SourceLocation(), std::nullopt);
15748 }
15749 }
15750
15751 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15752 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15753
15754 // Create the local class that will describe the lambda.
15755
15756 // FIXME: DependencyKind below is wrong when substituting inside a templated
15757 // context that isn't a DeclContext (such as a variable template), or when
15758 // substituting an unevaluated lambda inside of a function's parameter's type
15759 // - as parameter types are not instantiated from within a function's DC. We
15760 // use evaluation contexts to distinguish the function parameter case.
15761 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15762 CXXRecordDecl::LDK_Unknown;
15763 DeclContext *DC = getSema().CurContext;
15764 // A RequiresExprBodyDecl is not interesting for dependencies.
15765 // For the following case,
15766 //
15767 // template <typename>
15768 // concept C = requires { [] {}; };
15769 //
15770 // template <class F>
15771 // struct Widget;
15772 //
15773 // template <C F>
15774 // struct Widget<F> {};
15775 //
15776 // While we are substituting Widget<F>, the parent of DC would be
15777 // the template specialization itself. Thus, the lambda expression
15778 // will be deemed as dependent even if there are no dependent template
15779 // arguments.
15780 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15781 while (DC->isRequiresExprBody())
15782 DC = DC->getParent();
15783 if ((getSema().isUnevaluatedContext() ||
15784 getSema().isConstantEvaluatedContext()) &&
15785 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
15786 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
15787 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15788 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15789
15790 CXXRecordDecl *OldClass = E->getLambdaClass();
15791 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15792 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15793 E->getCaptureDefault());
15794 getDerived().transformedLocalDecl(OldClass, {Class});
15795
15796 CXXMethodDecl *NewCallOperator =
15797 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15798
15799 // Enter the scope of the lambda.
15800 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15801 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15802 E->hasExplicitParameters(), E->isMutable());
15803
15804 // Introduce the context of the call operator.
15805 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15806 /*NewThisContext*/false);
15807
15808 bool Invalid = false;
15809
15810 // Transform captures.
15811 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15812 CEnd = E->capture_end();
15813 C != CEnd; ++C) {
15814 // When we hit the first implicit capture, tell Sema that we've finished
15815 // the list of explicit captures.
15816 if (C->isImplicit())
15817 break;
15818
15819 // Capturing 'this' is trivial.
15820 if (C->capturesThis()) {
15821 // If this is a lambda that is part of a default member initialiser
15822 // and which we're instantiating outside the class that 'this' is
15823 // supposed to refer to, adjust the type of 'this' accordingly.
15824 //
15825 // Otherwise, leave the type of 'this' as-is.
15826 Sema::CXXThisScopeRAII ThisScope(
15827 getSema(),
15828 dyn_cast_if_present<CXXRecordDecl>(
15829 getSema().getFunctionLevelDeclContext()),
15830 Qualifiers());
15831 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15832 /*BuildAndDiagnose*/ true, nullptr,
15833 C->getCaptureKind() == LCK_StarThis);
15834 continue;
15835 }
15836 // Captured expression will be recaptured during captured variables
15837 // rebuilding.
15838 if (C->capturesVLAType())
15839 continue;
15840
15841 // Rebuild init-captures, including the implied field declaration.
15842 if (E->isInitCapture(Capture: C)) {
15843 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15844
15845 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15846 llvm::SmallVector<Decl*, 4> NewVDs;
15847
15848 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15849 ExprResult Init = Info.first;
15850 QualType InitQualType = Info.second;
15851 if (Init.isInvalid() || InitQualType.isNull()) {
15852 Invalid = true;
15853 break;
15854 }
15855 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15856 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15857 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15858 getSema().CurContext);
15859 if (!NewVD) {
15860 Invalid = true;
15861 break;
15862 }
15863 NewVDs.push_back(Elt: NewVD);
15864 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15865 // Cases we want to tackle:
15866 // ([C(Pack)] {}, ...)
15867 // But rule out cases e.g.
15868 // [...C = Pack()] {}
15869 if (NewC.EllipsisLoc.isInvalid())
15870 LSI->ContainsUnexpandedParameterPack |=
15871 Init.get()->containsUnexpandedParameterPack();
15872 }
15873
15874 if (Invalid)
15875 break;
15876
15877 getDerived().transformedLocalDecl(OldVD, NewVDs);
15878 continue;
15879 }
15880
15881 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15882
15883 // Determine the capture kind for Sema.
15884 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15885 : C->getCaptureKind() == LCK_ByCopy
15886 ? TryCaptureKind::ExplicitByVal
15887 : TryCaptureKind::ExplicitByRef;
15888 SourceLocation EllipsisLoc;
15889 if (C->isPackExpansion()) {
15890 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15891 bool ShouldExpand = false;
15892 bool RetainExpansion = false;
15893 UnsignedOrNone NumExpansions = std::nullopt;
15894 if (getDerived().TryExpandParameterPacks(
15895 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
15896 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
15897 RetainExpansion, NumExpansions)) {
15898 Invalid = true;
15899 continue;
15900 }
15901
15902 if (ShouldExpand) {
15903 // The transform has determined that we should perform an expansion;
15904 // transform and capture each of the arguments.
15905 // expansion of the pattern. Do so.
15906 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
15907 for (unsigned I = 0; I != *NumExpansions; ++I) {
15908 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15909 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15910 getDerived().TransformDecl(C->getLocation(), Pack));
15911 if (!CapturedVar) {
15912 Invalid = true;
15913 continue;
15914 }
15915
15916 // Capture the transformed variable.
15917 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15918 }
15919
15920 // FIXME: Retain a pack expansion if RetainExpansion is true.
15921
15922 continue;
15923 }
15924
15925 EllipsisLoc = C->getEllipsisLoc();
15926 }
15927
15928 // Transform the captured variable.
15929 auto *CapturedVar = cast_or_null<ValueDecl>(
15930 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15931 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15932 Invalid = true;
15933 continue;
15934 }
15935
15936 // This is not an init-capture; however it contains an unexpanded pack e.g.
15937 // ([Pack] {}(), ...)
15938 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15939 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15940
15941 // Capture the transformed variable.
15942 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15943 EllipsisLoc);
15944 }
15945 getSema().finishLambdaExplicitCaptures(LSI);
15946
15947 // Transform the template parameters, and add them to the current
15948 // instantiation scope. The null case is handled correctly.
15949 auto TPL = getDerived().TransformTemplateParameterList(
15950 E->getTemplateParameterList());
15951 LSI->GLTemplateParameterList = TPL;
15952 if (TPL) {
15953 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15954 TPL);
15955 LSI->ContainsUnexpandedParameterPack |=
15956 TPL->containsUnexpandedParameterPack();
15957 }
15958
15959 TypeLocBuilder NewCallOpTLBuilder;
15960 TypeLoc OldCallOpTypeLoc =
15961 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15962 QualType NewCallOpType =
15963 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15964 if (NewCallOpType.isNull())
15965 return ExprError();
15966 LSI->ContainsUnexpandedParameterPack |=
15967 NewCallOpType->containsUnexpandedParameterPack();
15968 TypeSourceInfo *NewCallOpTSI =
15969 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
15970
15971 // The type may be an AttributedType or some other kind of sugar;
15972 // get the actual underlying FunctionProtoType.
15973 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15974 assert(FPTL && "Not a FunctionProtoType?");
15975
15976 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15977 if (!TRC.ArgPackSubstIndex)
15978 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15979
15980 getSema().CompleteLambdaCallOperator(
15981 NewCallOperator, E->getCallOperator()->getLocation(),
15982 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15983 E->getCallOperator()->getConstexprKind(),
15984 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15985 E->hasExplicitResultType());
15986
15987 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15988 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15989
15990 {
15991 // Number the lambda for linkage purposes if necessary.
15992 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15993
15994 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15995 if (getDerived().ReplacingOriginal()) {
15996 Numbering = OldClass->getLambdaNumbering();
15997 }
15998
15999 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16000 }
16001
16002 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16003 // evaluation context even if we're not transforming the function body.
16004 getSema().PushExpressionEvaluationContextForFunction(
16005 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16006 E->getCallOperator());
16007
16008 StmtResult Body;
16009 {
16010 Sema::NonSFINAEContext _(getSema());
16011 Sema::CodeSynthesisContext C;
16012 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16013 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16014 getSema().pushCodeSynthesisContext(C);
16015
16016 // Instantiate the body of the lambda expression.
16017 Body = Invalid ? StmtError()
16018 : getDerived().TransformLambdaBody(E, E->getBody());
16019
16020 getSema().popCodeSynthesisContext();
16021 }
16022
16023 // ActOnLambda* will pop the function scope for us.
16024 FuncScopeCleanup.disable();
16025
16026 if (Body.isInvalid()) {
16027 SavedContext.pop();
16028 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16029 /*IsInstantiation=*/true);
16030 return ExprError();
16031 }
16032
16033 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16034 /*IsInstantiation=*/true,
16035 /*RetainFunctionScopeInfo=*/true);
16036 SavedContext.pop();
16037
16038 // Recompute the dependency of the lambda so that we can defer the lambda call
16039 // construction until after we have all the necessary template arguments. For
16040 // example, given
16041 //
16042 // template <class> struct S {
16043 // template <class U>
16044 // using Type = decltype([](U){}(42.0));
16045 // };
16046 // void foo() {
16047 // using T = S<int>::Type<float>;
16048 // ^~~~~~
16049 // }
16050 //
16051 // We would end up here from instantiating S<int> when ensuring its
16052 // completeness. That would transform the lambda call expression regardless of
16053 // the absence of the corresponding argument for U.
16054 //
16055 // Going ahead with unsubstituted type U makes things worse: we would soon
16056 // compare the argument type (which is float) against the parameter U
16057 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16058 // error suggesting unmatched types 'U' and 'float'!
16059 //
16060 // That said, everything will be fine if we defer that semantic checking.
16061 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16062 // dependent. Since the CallExpr's dependency boils down to the lambda's
16063 // dependency in this case, we can harness that by recomputing the dependency
16064 // from the instantiation arguments.
16065 //
16066 // FIXME: Creating the type of a lambda requires us to have a dependency
16067 // value, which happens before its substitution. We update its dependency
16068 // *after* the substitution in case we can't decide the dependency
16069 // so early, e.g. because we want to see if any of the *substituted*
16070 // parameters are dependent.
16071 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16072 Class->setLambdaDependencyKind(DependencyKind);
16073
16074 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16075 Body.get()->getEndLoc(), LSI);
16076}
16077
16078template<typename Derived>
16079StmtResult
16080TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16081 return TransformStmt(S);
16082}
16083
16084template<typename Derived>
16085StmtResult
16086TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16087 // Transform captures.
16088 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16089 CEnd = E->capture_end();
16090 C != CEnd; ++C) {
16091 // When we hit the first implicit capture, tell Sema that we've finished
16092 // the list of explicit captures.
16093 if (!C->isImplicit())
16094 continue;
16095
16096 // Capturing 'this' is trivial.
16097 if (C->capturesThis()) {
16098 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16099 /*BuildAndDiagnose*/ true, nullptr,
16100 C->getCaptureKind() == LCK_StarThis);
16101 continue;
16102 }
16103 // Captured expression will be recaptured during captured variables
16104 // rebuilding.
16105 if (C->capturesVLAType())
16106 continue;
16107
16108 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16109 assert(!E->isInitCapture(C) && "implicit init-capture?");
16110
16111 // Transform the captured variable.
16112 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16113 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16114 if (!CapturedVar || CapturedVar->isInvalidDecl())
16115 return StmtError();
16116
16117 // Capture the transformed variable.
16118 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16119 }
16120
16121 return S;
16122}
16123
16124template<typename Derived>
16125ExprResult
16126TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16127 CXXUnresolvedConstructExpr *E) {
16128 TypeSourceInfo *T =
16129 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16130 if (!T)
16131 return ExprError();
16132
16133 bool ArgumentChanged = false;
16134 SmallVector<Expr*, 8> Args;
16135 Args.reserve(N: E->getNumArgs());
16136 {
16137 EnterExpressionEvaluationContext Context(
16138 getSema(), EnterExpressionEvaluationContext::InitList,
16139 E->isListInitialization());
16140 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16141 &ArgumentChanged))
16142 return ExprError();
16143 }
16144
16145 if (!getDerived().AlwaysRebuild() &&
16146 T == E->getTypeSourceInfo() &&
16147 !ArgumentChanged)
16148 return E;
16149
16150 // FIXME: we're faking the locations of the commas
16151 return getDerived().RebuildCXXUnresolvedConstructExpr(
16152 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16153}
16154
16155template<typename Derived>
16156ExprResult
16157TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16158 CXXDependentScopeMemberExpr *E) {
16159 // Transform the base of the expression.
16160 ExprResult Base((Expr*) nullptr);
16161 Expr *OldBase;
16162 QualType BaseType;
16163 QualType ObjectType;
16164 if (!E->isImplicitAccess()) {
16165 OldBase = E->getBase();
16166 Base = getDerived().TransformExpr(OldBase);
16167 if (Base.isInvalid())
16168 return ExprError();
16169
16170 // Start the member reference and compute the object's type.
16171 ParsedType ObjectTy;
16172 bool MayBePseudoDestructor = false;
16173 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16174 OpLoc: E->getOperatorLoc(),
16175 OpKind: E->isArrow()? tok::arrow : tok::period,
16176 ObjectType&: ObjectTy,
16177 MayBePseudoDestructor);
16178 if (Base.isInvalid())
16179 return ExprError();
16180
16181 ObjectType = ObjectTy.get();
16182 BaseType = ((Expr*) Base.get())->getType();
16183 } else {
16184 OldBase = nullptr;
16185 BaseType = getDerived().TransformType(E->getBaseType());
16186 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16187 }
16188
16189 // Transform the first part of the nested-name-specifier that qualifies
16190 // the member name.
16191 NamedDecl *FirstQualifierInScope
16192 = getDerived().TransformFirstQualifierInScope(
16193 E->getFirstQualifierFoundInScope(),
16194 E->getQualifierLoc().getBeginLoc());
16195
16196 NestedNameSpecifierLoc QualifierLoc;
16197 if (E->getQualifier()) {
16198 QualifierLoc
16199 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16200 ObjectType,
16201 FirstQualifierInScope);
16202 if (!QualifierLoc)
16203 return ExprError();
16204 }
16205
16206 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16207
16208 // TODO: If this is a conversion-function-id, verify that the
16209 // destination type name (if present) resolves the same way after
16210 // instantiation as it did in the local scope.
16211
16212 DeclarationNameInfo NameInfo
16213 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16214 if (!NameInfo.getName())
16215 return ExprError();
16216
16217 if (!E->hasExplicitTemplateArgs()) {
16218 // This is a reference to a member without an explicitly-specified
16219 // template argument list. Optimize for this common case.
16220 if (!getDerived().AlwaysRebuild() &&
16221 Base.get() == OldBase &&
16222 BaseType == E->getBaseType() &&
16223 QualifierLoc == E->getQualifierLoc() &&
16224 NameInfo.getName() == E->getMember() &&
16225 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16226 return E;
16227
16228 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16229 BaseType,
16230 E->isArrow(),
16231 E->getOperatorLoc(),
16232 QualifierLoc,
16233 TemplateKWLoc,
16234 FirstQualifierInScope,
16235 NameInfo,
16236 /*TemplateArgs*/nullptr);
16237 }
16238
16239 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16240 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16241 E->getNumTemplateArgs(),
16242 TransArgs))
16243 return ExprError();
16244
16245 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16246 BaseType,
16247 E->isArrow(),
16248 E->getOperatorLoc(),
16249 QualifierLoc,
16250 TemplateKWLoc,
16251 FirstQualifierInScope,
16252 NameInfo,
16253 &TransArgs);
16254}
16255
16256template <typename Derived>
16257ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16258 UnresolvedMemberExpr *Old) {
16259 // Transform the base of the expression.
16260 ExprResult Base((Expr *)nullptr);
16261 QualType BaseType;
16262 if (!Old->isImplicitAccess()) {
16263 Base = getDerived().TransformExpr(Old->getBase());
16264 if (Base.isInvalid())
16265 return ExprError();
16266 Base =
16267 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16268 if (Base.isInvalid())
16269 return ExprError();
16270 BaseType = Base.get()->getType();
16271 } else {
16272 BaseType = getDerived().TransformType(Old->getBaseType());
16273 }
16274
16275 NestedNameSpecifierLoc QualifierLoc;
16276 if (Old->getQualifierLoc()) {
16277 QualifierLoc =
16278 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16279 if (!QualifierLoc)
16280 return ExprError();
16281 }
16282
16283 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16284
16285 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16286
16287 // Transform the declaration set.
16288 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16289 return ExprError();
16290
16291 // Determine the naming class.
16292 if (Old->getNamingClass()) {
16293 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16294 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16295 if (!NamingClass)
16296 return ExprError();
16297
16298 R.setNamingClass(NamingClass);
16299 }
16300
16301 TemplateArgumentListInfo TransArgs;
16302 if (Old->hasExplicitTemplateArgs()) {
16303 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16304 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16305 if (getDerived().TransformTemplateArguments(
16306 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16307 return ExprError();
16308 }
16309
16310 // FIXME: to do this check properly, we will need to preserve the
16311 // first-qualifier-in-scope here, just in case we had a dependent
16312 // base (and therefore couldn't do the check) and a
16313 // nested-name-qualifier (and therefore could do the lookup).
16314 NamedDecl *FirstQualifierInScope = nullptr;
16315
16316 return getDerived().RebuildUnresolvedMemberExpr(
16317 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16318 TemplateKWLoc, FirstQualifierInScope, R,
16319 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16320}
16321
16322template<typename Derived>
16323ExprResult
16324TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16325 EnterExpressionEvaluationContext Unevaluated(
16326 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16327 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16328 if (SubExpr.isInvalid())
16329 return ExprError();
16330
16331 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16332 return E;
16333
16334 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16335}
16336
16337template<typename Derived>
16338ExprResult
16339TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16340 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16341 if (Pattern.isInvalid())
16342 return ExprError();
16343
16344 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16345 return E;
16346
16347 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16348 E->getNumExpansions());
16349}
16350
16351template <typename Derived>
16352UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16353 ArrayRef<TemplateArgument> PackArgs) {
16354 UnsignedOrNone Result = 0u;
16355 for (const TemplateArgument &Arg : PackArgs) {
16356 if (!Arg.isPackExpansion()) {
16357 Result = *Result + 1;
16358 continue;
16359 }
16360
16361 TemplateArgumentLoc ArgLoc;
16362 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16363
16364 // Find the pattern of the pack expansion.
16365 SourceLocation Ellipsis;
16366 UnsignedOrNone OrigNumExpansions = std::nullopt;
16367 TemplateArgumentLoc Pattern =
16368 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16369 OrigNumExpansions);
16370
16371 // Substitute under the pack expansion. Do not expand the pack (yet).
16372 TemplateArgumentLoc OutPattern;
16373 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16374 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16375 /*Uneval*/ true))
16376 return 1u;
16377
16378 // See if we can determine the number of arguments from the result.
16379 UnsignedOrNone NumExpansions =
16380 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16381 if (!NumExpansions) {
16382 // No: we must be in an alias template expansion, and we're going to
16383 // need to actually expand the packs.
16384 Result = std::nullopt;
16385 break;
16386 }
16387
16388 Result = *Result + *NumExpansions;
16389 }
16390 return Result;
16391}
16392
16393template<typename Derived>
16394ExprResult
16395TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16396 // If E is not value-dependent, then nothing will change when we transform it.
16397 // Note: This is an instantiation-centric view.
16398 if (!E->isValueDependent())
16399 return E;
16400
16401 EnterExpressionEvaluationContext Unevaluated(
16402 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16403
16404 ArrayRef<TemplateArgument> PackArgs;
16405 TemplateArgument ArgStorage;
16406
16407 // Find the argument list to transform.
16408 if (E->isPartiallySubstituted()) {
16409 PackArgs = E->getPartialArguments();
16410 } else if (E->isValueDependent()) {
16411 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16412 bool ShouldExpand = false;
16413 bool RetainExpansion = false;
16414 UnsignedOrNone NumExpansions = std::nullopt;
16415 if (getDerived().TryExpandParameterPacks(
16416 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16417 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16418 RetainExpansion, NumExpansions))
16419 return ExprError();
16420
16421 // If we need to expand the pack, build a template argument from it and
16422 // expand that.
16423 if (ShouldExpand) {
16424 auto *Pack = E->getPack();
16425 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16426 ArgStorage = getSema().Context.getPackExpansionType(
16427 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16428 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16429 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16430 } else {
16431 auto *VD = cast<ValueDecl>(Val: Pack);
16432 ExprResult DRE = getSema().BuildDeclRefExpr(
16433 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16434 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16435 E->getPackLoc());
16436 if (DRE.isInvalid())
16437 return ExprError();
16438 ArgStorage = TemplateArgument(
16439 new (getSema().Context)
16440 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16441 /*IsCanonical=*/false);
16442 }
16443 PackArgs = ArgStorage;
16444 }
16445 }
16446
16447 // If we're not expanding the pack, just transform the decl.
16448 if (!PackArgs.size()) {
16449 auto *Pack = cast_or_null<NamedDecl>(
16450 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16451 if (!Pack)
16452 return ExprError();
16453 return getDerived().RebuildSizeOfPackExpr(
16454 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16455 std::nullopt, {});
16456 }
16457
16458 // Try to compute the result without performing a partial substitution.
16459 UnsignedOrNone Result =
16460 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16461
16462 // Common case: we could determine the number of expansions without
16463 // substituting.
16464 if (Result)
16465 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16466 E->getPackLoc(),
16467 E->getRParenLoc(), *Result, {});
16468
16469 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16470 E->getPackLoc());
16471 {
16472 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16473 typedef TemplateArgumentLocInventIterator<
16474 Derived, const TemplateArgument*> PackLocIterator;
16475 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16476 PackLocIterator(*this, PackArgs.end()),
16477 TransformedPackArgs, /*Uneval*/true))
16478 return ExprError();
16479 }
16480
16481 // Check whether we managed to fully-expand the pack.
16482 // FIXME: Is it possible for us to do so and not hit the early exit path?
16483 SmallVector<TemplateArgument, 8> Args;
16484 bool PartialSubstitution = false;
16485 for (auto &Loc : TransformedPackArgs.arguments()) {
16486 Args.push_back(Elt: Loc.getArgument());
16487 if (Loc.getArgument().isPackExpansion())
16488 PartialSubstitution = true;
16489 }
16490
16491 if (PartialSubstitution)
16492 return getDerived().RebuildSizeOfPackExpr(
16493 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16494 std::nullopt, Args);
16495
16496 return getDerived().RebuildSizeOfPackExpr(
16497 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16498 /*Length=*/static_cast<unsigned>(Args.size()),
16499 /*PartialArgs=*/{});
16500}
16501
16502template <typename Derived>
16503ExprResult
16504TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16505 if (!E->isValueDependent())
16506 return E;
16507
16508 // Transform the index
16509 ExprResult IndexExpr;
16510 {
16511 EnterExpressionEvaluationContext ConstantContext(
16512 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16513 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16514 if (IndexExpr.isInvalid())
16515 return ExprError();
16516 }
16517
16518 SmallVector<Expr *, 5> ExpandedExprs;
16519 bool FullySubstituted = true;
16520 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16521 Expr *Pattern = E->getPackIdExpression();
16522 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16523 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16524 Unexpanded);
16525 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16526
16527 // Determine whether the set of unexpanded parameter packs can and should
16528 // be expanded.
16529 bool ShouldExpand = true;
16530 bool RetainExpansion = false;
16531 UnsignedOrNone OrigNumExpansions = std::nullopt,
16532 NumExpansions = std::nullopt;
16533 if (getDerived().TryExpandParameterPacks(
16534 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16535 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16536 RetainExpansion, NumExpansions))
16537 return true;
16538 if (!ShouldExpand) {
16539 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16540 ExprResult Pack = getDerived().TransformExpr(Pattern);
16541 if (Pack.isInvalid())
16542 return ExprError();
16543 return getDerived().RebuildPackIndexingExpr(
16544 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16545 {}, /*FullySubstituted=*/false);
16546 }
16547 for (unsigned I = 0; I != *NumExpansions; ++I) {
16548 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16549 ExprResult Out = getDerived().TransformExpr(Pattern);
16550 if (Out.isInvalid())
16551 return true;
16552 if (Out.get()->containsUnexpandedParameterPack()) {
16553 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16554 OrigNumExpansions);
16555 if (Out.isInvalid())
16556 return true;
16557 FullySubstituted = false;
16558 }
16559 ExpandedExprs.push_back(Elt: Out.get());
16560 }
16561 // If we're supposed to retain a pack expansion, do so by temporarily
16562 // forgetting the partially-substituted parameter pack.
16563 if (RetainExpansion) {
16564 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16565
16566 ExprResult Out = getDerived().TransformExpr(Pattern);
16567 if (Out.isInvalid())
16568 return true;
16569
16570 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16571 OrigNumExpansions);
16572 if (Out.isInvalid())
16573 return true;
16574 FullySubstituted = false;
16575 ExpandedExprs.push_back(Elt: Out.get());
16576 }
16577 } else if (!E->expandsToEmptyPack()) {
16578 if (getDerived().TransformExprs(E->getExpressions().data(),
16579 E->getExpressions().size(), false,
16580 ExpandedExprs))
16581 return ExprError();
16582 }
16583
16584 return getDerived().RebuildPackIndexingExpr(
16585 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16586 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16587}
16588
16589template <typename Derived>
16590ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16591 SubstNonTypeTemplateParmPackExpr *E) {
16592 if (!getSema().ArgPackSubstIndex)
16593 // We aren't expanding the parameter pack, so just return ourselves.
16594 return E;
16595
16596 TemplateArgument Pack = E->getArgumentPack();
16597 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
16598 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16599 E->getAssociatedDecl(), E->getParameterPack(),
16600 E->getParameterPackLocation(), Arg, SemaRef.getPackIndex(Pack),
16601 E->getFinal());
16602}
16603
16604template <typename Derived>
16605ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16606 SubstNonTypeTemplateParmExpr *E) {
16607 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
16608 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
16609 if (Replacement.isInvalid())
16610 return true;
16611
16612 Decl *AssociatedDecl =
16613 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
16614 if (!AssociatedDecl)
16615 return true;
16616
16617 if (Replacement.get() == OrigReplacement &&
16618 AssociatedDecl == E->getAssociatedDecl())
16619 return E;
16620
16621 auto getParamAndType = [E](Decl *AssociatedDecl)
16622 -> std::tuple<NonTypeTemplateParmDecl *, QualType> {
16623 auto [PDecl, Arg] =
16624 getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex());
16625 auto *Param = cast<NonTypeTemplateParmDecl>(Val: PDecl);
16626 if (Arg.isNull())
16627 return {Param, Param->getType()};
16628 if (UnsignedOrNone PackIndex = E->getPackIndex())
16629 Arg = Arg.getPackAsArray()[*PackIndex];
16630 return {Param, Arg.getNonTypeTemplateArgumentType()};
16631 };
16632
16633 // If the replacement expression did not change, and the parameter type
16634 // did not change, we can skip the semantic action because it would
16635 // produce the same result anyway.
16636 if (auto [Param, ParamType] = getParamAndType(AssociatedDecl);
16637 !SemaRef.Context.hasSameType(
16638 ParamType, std::get<1>(getParamAndType(E->getAssociatedDecl()))) ||
16639 Replacement.get() != OrigReplacement) {
16640 // When transforming the replacement expression previously, all Sema
16641 // specific annotations, such as implicit casts, are discarded. Calling the
16642 // corresponding sema action is necessary to recover those. Otherwise,
16643 // equivalency of the result would be lost.
16644 TemplateArgument SugaredConverted, CanonicalConverted;
16645 Replacement = SemaRef.CheckTemplateArgument(
16646 Param, ParamType, Replacement.get(), SugaredConverted,
16647 CanonicalConverted,
16648 /*StrictCheck=*/false, Sema::CTAK_Specified);
16649 if (Replacement.isInvalid())
16650 return true;
16651 } else {
16652 // Otherwise, the same expression would have been produced.
16653 Replacement = E->getReplacement();
16654 }
16655
16656 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16657 AssociatedDecl, E->getParameter(), E->getNameLoc(),
16658 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
16659 E->getPackIndex(), E->getFinal());
16660}
16661
16662template<typename Derived>
16663ExprResult
16664TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16665 // Default behavior is to do nothing with this transformation.
16666 return E;
16667}
16668
16669template<typename Derived>
16670ExprResult
16671TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16672 MaterializeTemporaryExpr *E) {
16673 return getDerived().TransformExpr(E->getSubExpr());
16674}
16675
16676template<typename Derived>
16677ExprResult
16678TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16679 UnresolvedLookupExpr *Callee = nullptr;
16680 if (Expr *OldCallee = E->getCallee()) {
16681 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16682 if (CalleeResult.isInvalid())
16683 return ExprError();
16684 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16685 }
16686
16687 Expr *Pattern = E->getPattern();
16688
16689 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16690 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16691 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16692
16693 // Determine whether the set of unexpanded parameter packs can and should
16694 // be expanded.
16695 bool Expand = true;
16696 bool RetainExpansion = false;
16697 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16698 NumExpansions = OrigNumExpansions;
16699 if (getDerived().TryExpandParameterPacks(
16700 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16701 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16702 NumExpansions))
16703 return true;
16704
16705 if (!Expand) {
16706 // Do not expand any packs here, just transform and rebuild a fold
16707 // expression.
16708 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16709
16710 ExprResult LHS =
16711 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16712 if (LHS.isInvalid())
16713 return true;
16714
16715 ExprResult RHS =
16716 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16717 if (RHS.isInvalid())
16718 return true;
16719
16720 if (!getDerived().AlwaysRebuild() &&
16721 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16722 return E;
16723
16724 return getDerived().RebuildCXXFoldExpr(
16725 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16726 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16727 }
16728
16729 // Formally a fold expression expands to nested parenthesized expressions.
16730 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16731 // them.
16732 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16733 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16734 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16735 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16736 << E->getSourceRange();
16737 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16738 return ExprError();
16739 }
16740
16741 // The transform has determined that we should perform an elementwise
16742 // expansion of the pattern. Do so.
16743 ExprResult Result = getDerived().TransformExpr(E->getInit());
16744 if (Result.isInvalid())
16745 return true;
16746 bool LeftFold = E->isLeftFold();
16747
16748 // If we're retaining an expansion for a right fold, it is the innermost
16749 // component and takes the init (if any).
16750 if (!LeftFold && RetainExpansion) {
16751 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16752
16753 ExprResult Out = getDerived().TransformExpr(Pattern);
16754 if (Out.isInvalid())
16755 return true;
16756
16757 Result = getDerived().RebuildCXXFoldExpr(
16758 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16759 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16760 if (Result.isInvalid())
16761 return true;
16762 }
16763
16764 bool WarnedOnComparison = false;
16765 for (unsigned I = 0; I != *NumExpansions; ++I) {
16766 Sema::ArgPackSubstIndexRAII SubstIndex(
16767 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16768 ExprResult Out = getDerived().TransformExpr(Pattern);
16769 if (Out.isInvalid())
16770 return true;
16771
16772 if (Out.get()->containsUnexpandedParameterPack()) {
16773 // We still have a pack; retain a pack expansion for this slice.
16774 Result = getDerived().RebuildCXXFoldExpr(
16775 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16776 E->getOperator(), E->getEllipsisLoc(),
16777 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16778 OrigNumExpansions);
16779 } else if (Result.isUsable()) {
16780 // We've got down to a single element; build a binary operator.
16781 Expr *LHS = LeftFold ? Result.get() : Out.get();
16782 Expr *RHS = LeftFold ? Out.get() : Result.get();
16783 if (Callee) {
16784 UnresolvedSet<16> Functions;
16785 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16786 Result = getDerived().RebuildCXXOperatorCallExpr(
16787 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16788 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16789 Functions, LHS, RHS);
16790 } else {
16791 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16792 E->getOperator(), LHS, RHS,
16793 /*ForFoldExpresion=*/true);
16794 if (!WarnedOnComparison && Result.isUsable()) {
16795 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16796 BO && BO->isComparisonOp()) {
16797 WarnedOnComparison = true;
16798 SemaRef.Diag(Loc: BO->getBeginLoc(),
16799 DiagID: diag::warn_comparison_in_fold_expression)
16800 << BO->getOpcodeStr();
16801 }
16802 }
16803 }
16804 } else
16805 Result = Out;
16806
16807 if (Result.isInvalid())
16808 return true;
16809 }
16810
16811 // If we're retaining an expansion for a left fold, it is the outermost
16812 // component and takes the complete expansion so far as its init (if any).
16813 if (LeftFold && RetainExpansion) {
16814 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16815
16816 ExprResult Out = getDerived().TransformExpr(Pattern);
16817 if (Out.isInvalid())
16818 return true;
16819
16820 Result = getDerived().RebuildCXXFoldExpr(
16821 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16822 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16823 if (Result.isInvalid())
16824 return true;
16825 }
16826
16827 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16828 PE->setIsProducedByFoldExpansion();
16829
16830 // If we had no init and an empty pack, and we're not retaining an expansion,
16831 // then produce a fallback value or error.
16832 if (Result.isUnset())
16833 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16834 E->getOperator());
16835 return Result;
16836}
16837
16838template <typename Derived>
16839ExprResult
16840TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16841 SmallVector<Expr *, 4> TransformedInits;
16842 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16843
16844 QualType T = getDerived().TransformType(E->getType());
16845
16846 bool ArgChanged = false;
16847
16848 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16849 TransformedInits, &ArgChanged))
16850 return ExprError();
16851
16852 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16853 return E;
16854
16855 return getDerived().RebuildCXXParenListInitExpr(
16856 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16857 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16858}
16859
16860template<typename Derived>
16861ExprResult
16862TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16863 CXXStdInitializerListExpr *E) {
16864 return getDerived().TransformExpr(E->getSubExpr());
16865}
16866
16867template<typename Derived>
16868ExprResult
16869TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16870 return SemaRef.MaybeBindToTemporary(E);
16871}
16872
16873template<typename Derived>
16874ExprResult
16875TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16876 return E;
16877}
16878
16879template<typename Derived>
16880ExprResult
16881TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16882 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16883 if (SubExpr.isInvalid())
16884 return ExprError();
16885
16886 if (!getDerived().AlwaysRebuild() &&
16887 SubExpr.get() == E->getSubExpr())
16888 return E;
16889
16890 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16891}
16892
16893template<typename Derived>
16894ExprResult
16895TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16896 // Transform each of the elements.
16897 SmallVector<Expr *, 8> Elements;
16898 bool ArgChanged = false;
16899 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16900 /*IsCall=*/false, Elements, &ArgChanged))
16901 return ExprError();
16902
16903 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16904 return SemaRef.MaybeBindToTemporary(E);
16905
16906 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16907 Elements.data(),
16908 Elements.size());
16909}
16910
16911template<typename Derived>
16912ExprResult
16913TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16914 ObjCDictionaryLiteral *E) {
16915 // Transform each of the elements.
16916 SmallVector<ObjCDictionaryElement, 8> Elements;
16917 bool ArgChanged = false;
16918 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16919 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
16920
16921 if (OrigElement.isPackExpansion()) {
16922 // This key/value element is a pack expansion.
16923 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16924 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16925 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16926 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16927
16928 // Determine whether the set of unexpanded parameter packs can
16929 // and should be expanded.
16930 bool Expand = true;
16931 bool RetainExpansion = false;
16932 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16933 UnsignedOrNone NumExpansions = OrigNumExpansions;
16934 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16935 OrigElement.Value->getEndLoc());
16936 if (getDerived().TryExpandParameterPacks(
16937 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
16938 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16939 NumExpansions))
16940 return ExprError();
16941
16942 if (!Expand) {
16943 // The transform has determined that we should perform a simple
16944 // transformation on the pack expansion, producing another pack
16945 // expansion.
16946 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16947 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16948 if (Key.isInvalid())
16949 return ExprError();
16950
16951 if (Key.get() != OrigElement.Key)
16952 ArgChanged = true;
16953
16954 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16955 if (Value.isInvalid())
16956 return ExprError();
16957
16958 if (Value.get() != OrigElement.Value)
16959 ArgChanged = true;
16960
16961 ObjCDictionaryElement Expansion = {
16962 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
16963 };
16964 Elements.push_back(Elt: Expansion);
16965 continue;
16966 }
16967
16968 // Record right away that the argument was changed. This needs
16969 // to happen even if the array expands to nothing.
16970 ArgChanged = true;
16971
16972 // The transform has determined that we should perform an elementwise
16973 // expansion of the pattern. Do so.
16974 for (unsigned I = 0; I != *NumExpansions; ++I) {
16975 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16976 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16977 if (Key.isInvalid())
16978 return ExprError();
16979
16980 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16981 if (Value.isInvalid())
16982 return ExprError();
16983
16984 ObjCDictionaryElement Element = {
16985 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
16986 };
16987
16988 // If any unexpanded parameter packs remain, we still have a
16989 // pack expansion.
16990 // FIXME: Can this really happen?
16991 if (Key.get()->containsUnexpandedParameterPack() ||
16992 Value.get()->containsUnexpandedParameterPack())
16993 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16994
16995 Elements.push_back(Elt: Element);
16996 }
16997
16998 // FIXME: Retain a pack expansion if RetainExpansion is true.
16999
17000 // We've finished with this pack expansion.
17001 continue;
17002 }
17003
17004 // Transform and check key.
17005 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17006 if (Key.isInvalid())
17007 return ExprError();
17008
17009 if (Key.get() != OrigElement.Key)
17010 ArgChanged = true;
17011
17012 // Transform and check value.
17013 ExprResult Value
17014 = getDerived().TransformExpr(OrigElement.Value);
17015 if (Value.isInvalid())
17016 return ExprError();
17017
17018 if (Value.get() != OrigElement.Value)
17019 ArgChanged = true;
17020
17021 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17022 .NumExpansions: std::nullopt};
17023 Elements.push_back(Elt: Element);
17024 }
17025
17026 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17027 return SemaRef.MaybeBindToTemporary(E);
17028
17029 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17030 Elements);
17031}
17032
17033template<typename Derived>
17034ExprResult
17035TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17036 TypeSourceInfo *EncodedTypeInfo
17037 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17038 if (!EncodedTypeInfo)
17039 return ExprError();
17040
17041 if (!getDerived().AlwaysRebuild() &&
17042 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17043 return E;
17044
17045 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17046 EncodedTypeInfo,
17047 E->getRParenLoc());
17048}
17049
17050template<typename Derived>
17051ExprResult TreeTransform<Derived>::
17052TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17053 // This is a kind of implicit conversion, and it needs to get dropped
17054 // and recomputed for the same general reasons that ImplicitCastExprs
17055 // do, as well a more specific one: this expression is only valid when
17056 // it appears *immediately* as an argument expression.
17057 return getDerived().TransformExpr(E->getSubExpr());
17058}
17059
17060template<typename Derived>
17061ExprResult TreeTransform<Derived>::
17062TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17063 TypeSourceInfo *TSInfo
17064 = getDerived().TransformType(E->getTypeInfoAsWritten());
17065 if (!TSInfo)
17066 return ExprError();
17067
17068 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17069 if (Result.isInvalid())
17070 return ExprError();
17071
17072 if (!getDerived().AlwaysRebuild() &&
17073 TSInfo == E->getTypeInfoAsWritten() &&
17074 Result.get() == E->getSubExpr())
17075 return E;
17076
17077 return SemaRef.ObjC().BuildObjCBridgedCast(
17078 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17079 SubExpr: Result.get());
17080}
17081
17082template <typename Derived>
17083ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17084 ObjCAvailabilityCheckExpr *E) {
17085 return E;
17086}
17087
17088template<typename Derived>
17089ExprResult
17090TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17091 // Transform arguments.
17092 bool ArgChanged = false;
17093 SmallVector<Expr*, 8> Args;
17094 Args.reserve(N: E->getNumArgs());
17095 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17096 &ArgChanged))
17097 return ExprError();
17098
17099 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17100 // Class message: transform the receiver type.
17101 TypeSourceInfo *ReceiverTypeInfo
17102 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17103 if (!ReceiverTypeInfo)
17104 return ExprError();
17105
17106 // If nothing changed, just retain the existing message send.
17107 if (!getDerived().AlwaysRebuild() &&
17108 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17109 return SemaRef.MaybeBindToTemporary(E);
17110
17111 // Build a new class message send.
17112 SmallVector<SourceLocation, 16> SelLocs;
17113 E->getSelectorLocs(SelLocs);
17114 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17115 E->getSelector(),
17116 SelLocs,
17117 E->getMethodDecl(),
17118 E->getLeftLoc(),
17119 Args,
17120 E->getRightLoc());
17121 }
17122 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17123 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17124 if (!E->getMethodDecl())
17125 return ExprError();
17126
17127 // Build a new class message send to 'super'.
17128 SmallVector<SourceLocation, 16> SelLocs;
17129 E->getSelectorLocs(SelLocs);
17130 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17131 E->getSelector(),
17132 SelLocs,
17133 E->getReceiverType(),
17134 E->getMethodDecl(),
17135 E->getLeftLoc(),
17136 Args,
17137 E->getRightLoc());
17138 }
17139
17140 // Instance message: transform the receiver
17141 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17142 "Only class and instance messages may be instantiated");
17143 ExprResult Receiver
17144 = getDerived().TransformExpr(E->getInstanceReceiver());
17145 if (Receiver.isInvalid())
17146 return ExprError();
17147
17148 // If nothing changed, just retain the existing message send.
17149 if (!getDerived().AlwaysRebuild() &&
17150 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17151 return SemaRef.MaybeBindToTemporary(E);
17152
17153 // Build a new instance message send.
17154 SmallVector<SourceLocation, 16> SelLocs;
17155 E->getSelectorLocs(SelLocs);
17156 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17157 E->getSelector(),
17158 SelLocs,
17159 E->getMethodDecl(),
17160 E->getLeftLoc(),
17161 Args,
17162 E->getRightLoc());
17163}
17164
17165template<typename Derived>
17166ExprResult
17167TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17168 return E;
17169}
17170
17171template<typename Derived>
17172ExprResult
17173TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17174 return E;
17175}
17176
17177template<typename Derived>
17178ExprResult
17179TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17180 // Transform the base expression.
17181 ExprResult Base = getDerived().TransformExpr(E->getBase());
17182 if (Base.isInvalid())
17183 return ExprError();
17184
17185 // We don't need to transform the ivar; it will never change.
17186
17187 // If nothing changed, just retain the existing expression.
17188 if (!getDerived().AlwaysRebuild() &&
17189 Base.get() == E->getBase())
17190 return E;
17191
17192 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17193 E->getLocation(),
17194 E->isArrow(), E->isFreeIvar());
17195}
17196
17197template<typename Derived>
17198ExprResult
17199TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17200 // 'super' and types never change. Property never changes. Just
17201 // retain the existing expression.
17202 if (!E->isObjectReceiver())
17203 return E;
17204
17205 // Transform the base expression.
17206 ExprResult Base = getDerived().TransformExpr(E->getBase());
17207 if (Base.isInvalid())
17208 return ExprError();
17209
17210 // We don't need to transform the property; it will never change.
17211
17212 // If nothing changed, just retain the existing expression.
17213 if (!getDerived().AlwaysRebuild() &&
17214 Base.get() == E->getBase())
17215 return E;
17216
17217 if (E->isExplicitProperty())
17218 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17219 E->getExplicitProperty(),
17220 E->getLocation());
17221
17222 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17223 SemaRef.Context.PseudoObjectTy,
17224 E->getImplicitPropertyGetter(),
17225 E->getImplicitPropertySetter(),
17226 E->getLocation());
17227}
17228
17229template<typename Derived>
17230ExprResult
17231TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17232 // Transform the base expression.
17233 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17234 if (Base.isInvalid())
17235 return ExprError();
17236
17237 // Transform the key expression.
17238 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17239 if (Key.isInvalid())
17240 return ExprError();
17241
17242 // If nothing changed, just retain the existing expression.
17243 if (!getDerived().AlwaysRebuild() &&
17244 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17245 return E;
17246
17247 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17248 Base.get(), Key.get(),
17249 E->getAtIndexMethodDecl(),
17250 E->setAtIndexMethodDecl());
17251}
17252
17253template<typename Derived>
17254ExprResult
17255TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17256 // Transform the base expression.
17257 ExprResult Base = getDerived().TransformExpr(E->getBase());
17258 if (Base.isInvalid())
17259 return ExprError();
17260
17261 // If nothing changed, just retain the existing expression.
17262 if (!getDerived().AlwaysRebuild() &&
17263 Base.get() == E->getBase())
17264 return E;
17265
17266 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17267 E->getOpLoc(),
17268 E->isArrow());
17269}
17270
17271template<typename Derived>
17272ExprResult
17273TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17274 bool ArgumentChanged = false;
17275 SmallVector<Expr*, 8> SubExprs;
17276 SubExprs.reserve(N: E->getNumSubExprs());
17277 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17278 SubExprs, &ArgumentChanged))
17279 return ExprError();
17280
17281 if (!getDerived().AlwaysRebuild() &&
17282 !ArgumentChanged)
17283 return E;
17284
17285 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17286 SubExprs,
17287 E->getRParenLoc());
17288}
17289
17290template<typename Derived>
17291ExprResult
17292TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17293 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17294 if (SrcExpr.isInvalid())
17295 return ExprError();
17296
17297 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17298 if (!Type)
17299 return ExprError();
17300
17301 if (!getDerived().AlwaysRebuild() &&
17302 Type == E->getTypeSourceInfo() &&
17303 SrcExpr.get() == E->getSrcExpr())
17304 return E;
17305
17306 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17307 SrcExpr.get(), Type,
17308 E->getRParenLoc());
17309}
17310
17311template<typename Derived>
17312ExprResult
17313TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17314 BlockDecl *oldBlock = E->getBlockDecl();
17315
17316 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17317 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17318
17319 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17320 blockScope->TheDecl->setBlockMissingReturnType(
17321 oldBlock->blockMissingReturnType());
17322
17323 SmallVector<ParmVarDecl*, 4> params;
17324 SmallVector<QualType, 4> paramTypes;
17325
17326 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17327
17328 // Parameter substitution.
17329 Sema::ExtParameterInfoBuilder extParamInfos;
17330 if (getDerived().TransformFunctionTypeParams(
17331 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17332 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17333 extParamInfos)) {
17334 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17335 return ExprError();
17336 }
17337
17338 QualType exprResultType =
17339 getDerived().TransformType(exprFunctionType->getReturnType());
17340
17341 auto epi = exprFunctionType->getExtProtoInfo();
17342 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17343
17344 QualType functionType =
17345 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17346 blockScope->FunctionType = functionType;
17347
17348 // Set the parameters on the block decl.
17349 if (!params.empty())
17350 blockScope->TheDecl->setParams(params);
17351
17352 if (!oldBlock->blockMissingReturnType()) {
17353 blockScope->HasImplicitReturnType = false;
17354 blockScope->ReturnType = exprResultType;
17355 }
17356
17357 // Transform the body
17358 StmtResult body = getDerived().TransformStmt(E->getBody());
17359 if (body.isInvalid()) {
17360 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17361 return ExprError();
17362 }
17363
17364#ifndef NDEBUG
17365 // In builds with assertions, make sure that we captured everything we
17366 // captured before.
17367 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17368 for (const auto &I : oldBlock->captures()) {
17369 VarDecl *oldCapture = I.getVariable();
17370
17371 // Ignore parameter packs.
17372 if (oldCapture->isParameterPack())
17373 continue;
17374
17375 VarDecl *newCapture =
17376 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17377 oldCapture));
17378 assert(blockScope->CaptureMap.count(newCapture));
17379 }
17380
17381 // The this pointer may not be captured by the instantiated block, even when
17382 // it's captured by the original block, if the expression causing the
17383 // capture is in the discarded branch of a constexpr if statement.
17384 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17385 "this pointer isn't captured in the old block");
17386 }
17387#endif
17388
17389 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17390 /*Scope=*/CurScope: nullptr);
17391}
17392
17393template<typename Derived>
17394ExprResult
17395TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17396 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17397 if (SrcExpr.isInvalid())
17398 return ExprError();
17399
17400 QualType Type = getDerived().TransformType(E->getType());
17401
17402 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17403 RParenLoc: E->getRParenLoc());
17404}
17405
17406template<typename Derived>
17407ExprResult
17408TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17409 bool ArgumentChanged = false;
17410 SmallVector<Expr*, 8> SubExprs;
17411 SubExprs.reserve(N: E->getNumSubExprs());
17412 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17413 SubExprs, &ArgumentChanged))
17414 return ExprError();
17415
17416 if (!getDerived().AlwaysRebuild() &&
17417 !ArgumentChanged)
17418 return E;
17419
17420 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17421 E->getOp(), E->getRParenLoc());
17422}
17423
17424//===----------------------------------------------------------------------===//
17425// Type reconstruction
17426//===----------------------------------------------------------------------===//
17427
17428template<typename Derived>
17429QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17430 SourceLocation Star) {
17431 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17432 Entity: getDerived().getBaseEntity());
17433}
17434
17435template<typename Derived>
17436QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17437 SourceLocation Star) {
17438 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17439 Entity: getDerived().getBaseEntity());
17440}
17441
17442template<typename Derived>
17443QualType
17444TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17445 bool WrittenAsLValue,
17446 SourceLocation Sigil) {
17447 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17448 Loc: Sigil, Entity: getDerived().getBaseEntity());
17449}
17450
17451template <typename Derived>
17452QualType TreeTransform<Derived>::RebuildMemberPointerType(
17453 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17454 SourceLocation Sigil) {
17455 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17456 Entity: getDerived().getBaseEntity());
17457}
17458
17459template<typename Derived>
17460QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17461 const ObjCTypeParamDecl *Decl,
17462 SourceLocation ProtocolLAngleLoc,
17463 ArrayRef<ObjCProtocolDecl *> Protocols,
17464 ArrayRef<SourceLocation> ProtocolLocs,
17465 SourceLocation ProtocolRAngleLoc) {
17466 return SemaRef.ObjC().BuildObjCTypeParamType(
17467 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17468 /*FailOnError=*/FailOnError: true);
17469}
17470
17471template<typename Derived>
17472QualType TreeTransform<Derived>::RebuildObjCObjectType(
17473 QualType BaseType,
17474 SourceLocation Loc,
17475 SourceLocation TypeArgsLAngleLoc,
17476 ArrayRef<TypeSourceInfo *> TypeArgs,
17477 SourceLocation TypeArgsRAngleLoc,
17478 SourceLocation ProtocolLAngleLoc,
17479 ArrayRef<ObjCProtocolDecl *> Protocols,
17480 ArrayRef<SourceLocation> ProtocolLocs,
17481 SourceLocation ProtocolRAngleLoc) {
17482 return SemaRef.ObjC().BuildObjCObjectType(
17483 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17484 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17485 /*FailOnError=*/FailOnError: true,
17486 /*Rebuilding=*/Rebuilding: true);
17487}
17488
17489template<typename Derived>
17490QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17491 QualType PointeeType,
17492 SourceLocation Star) {
17493 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17494}
17495
17496template <typename Derived>
17497QualType TreeTransform<Derived>::RebuildArrayType(
17498 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17499 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17500 if (SizeExpr || !Size)
17501 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17502 Quals: IndexTypeQuals, Brackets: BracketsRange,
17503 Entity: getDerived().getBaseEntity());
17504
17505 QualType Types[] = {
17506 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17507 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17508 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17509 };
17510 QualType SizeType;
17511 for (const auto &T : Types)
17512 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17513 SizeType = T;
17514 break;
17515 }
17516
17517 // Note that we can return a VariableArrayType here in the case where
17518 // the element type was a dependent VariableArrayType.
17519 IntegerLiteral *ArraySize
17520 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17521 /*FIXME*/l: BracketsRange.getBegin());
17522 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17523 Quals: IndexTypeQuals, Brackets: BracketsRange,
17524 Entity: getDerived().getBaseEntity());
17525}
17526
17527template <typename Derived>
17528QualType TreeTransform<Derived>::RebuildConstantArrayType(
17529 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17530 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17531 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17532 IndexTypeQuals, BracketsRange);
17533}
17534
17535template <typename Derived>
17536QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17537 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17538 SourceRange BracketsRange) {
17539 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17540 IndexTypeQuals, BracketsRange);
17541}
17542
17543template <typename Derived>
17544QualType TreeTransform<Derived>::RebuildVariableArrayType(
17545 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17546 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17547 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17548 SizeExpr,
17549 IndexTypeQuals, BracketsRange);
17550}
17551
17552template <typename Derived>
17553QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17554 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17555 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17556 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17557 SizeExpr,
17558 IndexTypeQuals, BracketsRange);
17559}
17560
17561template <typename Derived>
17562QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17563 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17564 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17565 AttrLoc: AttributeLoc);
17566}
17567
17568template <typename Derived>
17569QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17570 unsigned NumElements,
17571 VectorKind VecKind) {
17572 // FIXME: semantic checking!
17573 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17574}
17575
17576template <typename Derived>
17577QualType TreeTransform<Derived>::RebuildDependentVectorType(
17578 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17579 VectorKind VecKind) {
17580 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17581}
17582
17583template<typename Derived>
17584QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17585 unsigned NumElements,
17586 SourceLocation AttributeLoc) {
17587 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17588 NumElements, true);
17589 IntegerLiteral *VectorSize
17590 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17591 l: AttributeLoc);
17592 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17593}
17594
17595template<typename Derived>
17596QualType
17597TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17598 Expr *SizeExpr,
17599 SourceLocation AttributeLoc) {
17600 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17601}
17602
17603template <typename Derived>
17604QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17605 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17606 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17607 NumColumns);
17608}
17609
17610template <typename Derived>
17611QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17612 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17613 SourceLocation AttributeLoc) {
17614 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17615 AttrLoc: AttributeLoc);
17616}
17617
17618template <typename Derived>
17619QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17620 QualType T, MutableArrayRef<QualType> ParamTypes,
17621 const FunctionProtoType::ExtProtoInfo &EPI) {
17622 return SemaRef.BuildFunctionType(T, ParamTypes,
17623 Loc: getDerived().getBaseLocation(),
17624 Entity: getDerived().getBaseEntity(),
17625 EPI);
17626}
17627
17628template<typename Derived>
17629QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17630 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17631}
17632
17633template <typename Derived>
17634QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
17635 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
17636 SourceLocation NameLoc, Decl *D) {
17637 assert(D && "no decl found");
17638 if (D->isInvalidDecl()) return QualType();
17639
17640 // FIXME: Doesn't account for ObjCInterfaceDecl!
17641 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17642 // A valid resolved using typename pack expansion decl can have multiple
17643 // UsingDecls, but they must each have exactly one type, and it must be
17644 // the same type in every case. But we must have at least one expansion!
17645 if (UPD->expansions().empty()) {
17646 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
17647 << UPD->isCXXClassMember() << UPD;
17648 return QualType();
17649 }
17650
17651 // We might still have some unresolved types. Try to pick a resolved type
17652 // if we can. The final instantiation will check that the remaining
17653 // unresolved types instantiate to the type we pick.
17654 QualType FallbackT;
17655 QualType T;
17656 for (auto *E : UPD->expansions()) {
17657 QualType ThisT =
17658 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
17659 if (ThisT.isNull())
17660 continue;
17661 if (ThisT->getAs<UnresolvedUsingType>())
17662 FallbackT = ThisT;
17663 else if (T.isNull())
17664 T = ThisT;
17665 else
17666 assert(getSema().Context.hasSameType(ThisT, T) &&
17667 "mismatched resolved types in using pack expansion");
17668 }
17669 return T.isNull() ? FallbackT : T;
17670 }
17671 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17672 assert(Using->hasTypename() &&
17673 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17674
17675 // A valid resolved using typename decl points to exactly one type decl.
17676 assert(++Using->shadow_begin() == Using->shadow_end());
17677
17678 UsingShadowDecl *Shadow = *Using->shadow_begin();
17679 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
17680 return QualType();
17681 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
17682 }
17683 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17684 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17685 return SemaRef.Context.getUnresolvedUsingType(
17686 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
17687}
17688
17689template <typename Derived>
17690QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17691 TypeOfKind Kind) {
17692 return SemaRef.BuildTypeofExprType(E, Kind);
17693}
17694
17695template<typename Derived>
17696QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17697 TypeOfKind Kind) {
17698 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17699}
17700
17701template <typename Derived>
17702QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17703 return SemaRef.BuildDecltypeType(E);
17704}
17705
17706template <typename Derived>
17707QualType TreeTransform<Derived>::RebuildPackIndexingType(
17708 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17709 SourceLocation EllipsisLoc, bool FullySubstituted,
17710 ArrayRef<QualType> Expansions) {
17711 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17712 FullySubstituted, Expansions);
17713}
17714
17715template<typename Derived>
17716QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17717 UnaryTransformType::UTTKind UKind,
17718 SourceLocation Loc) {
17719 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17720}
17721
17722template <typename Derived>
17723QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17724 ElaboratedTypeKeyword Keyword, TemplateName Template,
17725 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
17726 return SemaRef.CheckTemplateIdType(
17727 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
17728 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
17729}
17730
17731template<typename Derived>
17732QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17733 SourceLocation KWLoc) {
17734 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17735}
17736
17737template<typename Derived>
17738QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17739 SourceLocation KWLoc,
17740 bool isReadPipe) {
17741 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17742 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17743}
17744
17745template <typename Derived>
17746QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17747 unsigned NumBits,
17748 SourceLocation Loc) {
17749 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17750 NumBits, true);
17751 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17752 type: SemaRef.Context.IntTy, l: Loc);
17753 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17754}
17755
17756template <typename Derived>
17757QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17758 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17759 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17760}
17761
17762template <typename Derived>
17763TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17764 bool TemplateKW,
17765 TemplateName Name) {
17766 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17767 Template: Name);
17768}
17769
17770template <typename Derived>
17771TemplateName TreeTransform<Derived>::RebuildTemplateName(
17772 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
17773 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
17774 UnqualifiedId TemplateName;
17775 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17776 Sema::TemplateTy Template;
17777 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17778 TemplateName, ParsedType::make(P: ObjectType),
17779 /*EnteringContext=*/false, Template,
17780 AllowInjectedClassName);
17781 return Template.get();
17782}
17783
17784template<typename Derived>
17785TemplateName
17786TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17787 SourceLocation TemplateKWLoc,
17788 OverloadedOperatorKind Operator,
17789 SourceLocation NameLoc,
17790 QualType ObjectType,
17791 bool AllowInjectedClassName) {
17792 UnqualifiedId Name;
17793 // FIXME: Bogus location information.
17794 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17795 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17796 Sema::TemplateTy Template;
17797 getSema().ActOnTemplateName(
17798 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17799 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17800 return Template.get();
17801}
17802
17803template <typename Derived>
17804ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17805 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17806 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17807 Expr *Second) {
17808 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17809
17810 if (First->getObjectKind() == OK_ObjCProperty) {
17811 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17812 if (BinaryOperator::isAssignmentOp(Opc))
17813 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17814 Opcode: Opc, LHS: First, RHS: Second);
17815 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17816 if (Result.isInvalid())
17817 return ExprError();
17818 First = Result.get();
17819 }
17820
17821 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17822 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17823 if (Result.isInvalid())
17824 return ExprError();
17825 Second = Result.get();
17826 }
17827
17828 // Determine whether this should be a builtin operation.
17829 if (Op == OO_Subscript) {
17830 if (!First->getType()->isOverloadableType() &&
17831 !Second->getType()->isOverloadableType())
17832 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17833 OpLoc);
17834 } else if (Op == OO_Arrow) {
17835 // It is possible that the type refers to a RecoveryExpr created earlier
17836 // in the tree transformation.
17837 if (First->getType()->isDependentType())
17838 return ExprError();
17839 // -> is never a builtin operation.
17840 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17841 } else if (Second == nullptr || isPostIncDec) {
17842 if (!First->getType()->isOverloadableType() ||
17843 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17844 // The argument is not of overloadable type, or this is an expression
17845 // of the form &Class::member, so try to create a built-in unary
17846 // operation.
17847 UnaryOperatorKind Opc
17848 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17849
17850 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17851 }
17852 } else {
17853 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17854 !First->getType()->isOverloadableType() &&
17855 !Second->getType()->isOverloadableType()) {
17856 // Neither of the arguments is type-dependent or has an overloadable
17857 // type, so try to create a built-in binary operation.
17858 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17859 ExprResult Result
17860 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17861 if (Result.isInvalid())
17862 return ExprError();
17863
17864 return Result;
17865 }
17866 }
17867
17868 // Create the overloaded operator invocation for unary operators.
17869 if (!Second || isPostIncDec) {
17870 UnaryOperatorKind Opc
17871 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17872 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
17873 RequiresADL);
17874 }
17875
17876 // Create the overloaded operator invocation for binary operators.
17877 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17878 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
17879 LHS: First, RHS: Second, RequiresADL);
17880 if (Result.isInvalid())
17881 return ExprError();
17882
17883 return Result;
17884}
17885
17886template<typename Derived>
17887ExprResult
17888TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17889 SourceLocation OperatorLoc,
17890 bool isArrow,
17891 CXXScopeSpec &SS,
17892 TypeSourceInfo *ScopeType,
17893 SourceLocation CCLoc,
17894 SourceLocation TildeLoc,
17895 PseudoDestructorTypeStorage Destroyed) {
17896 QualType CanonicalBaseType = Base->getType().getCanonicalType();
17897 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17898 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
17899 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
17900 !cast<PointerType>(Val&: CanonicalBaseType)
17901 ->getPointeeType()
17902 ->getAsCanonical<RecordType>())) {
17903 // This pseudo-destructor expression is still a pseudo-destructor.
17904 return SemaRef.BuildPseudoDestructorExpr(
17905 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
17906 CCLoc, TildeLoc, DestroyedType: Destroyed);
17907 }
17908
17909 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17910 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17911 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
17912 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17913 NameInfo.setNamedTypeInfo(DestroyedType);
17914
17915 // The scope type is now known to be a valid nested name specifier
17916 // component. Tack it on to the nested name specifier.
17917 if (ScopeType) {
17918 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
17919 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17920 diag::err_expected_class_or_namespace)
17921 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17922 return ExprError();
17923 }
17924 SS.clear();
17925 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
17926 }
17927
17928 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17929 return getSema().BuildMemberReferenceExpr(
17930 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
17931 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
17932 /*TemplateArgs*/ nullptr,
17933 /*S*/ nullptr);
17934}
17935
17936template<typename Derived>
17937StmtResult
17938TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17939 SourceLocation Loc = S->getBeginLoc();
17940 CapturedDecl *CD = S->getCapturedDecl();
17941 unsigned NumParams = CD->getNumParams();
17942 unsigned ContextParamPos = CD->getContextParamPosition();
17943 SmallVector<Sema::CapturedParamNameType, 4> Params;
17944 for (unsigned I = 0; I < NumParams; ++I) {
17945 if (I != ContextParamPos) {
17946 Params.push_back(
17947 Elt: std::make_pair(
17948 CD->getParam(i: I)->getName(),
17949 getDerived().TransformType(CD->getParam(i: I)->getType())));
17950 } else {
17951 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
17952 }
17953 }
17954 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17955 S->getCapturedRegionKind(), Params);
17956 StmtResult Body;
17957 {
17958 Sema::CompoundScopeRAII CompoundScope(getSema());
17959 Body = getDerived().TransformStmt(S->getCapturedStmt());
17960 }
17961
17962 if (Body.isInvalid()) {
17963 getSema().ActOnCapturedRegionError();
17964 return StmtError();
17965 }
17966
17967 return getSema().ActOnCapturedRegionEnd(Body.get());
17968}
17969
17970template <typename Derived>
17971StmtResult
17972TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17973 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17974 // function definition or instantiation of a function template specialization
17975 // and will therefore never appear in a dependent context.
17976 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17977 "context");
17978}
17979
17980template <typename Derived>
17981ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17982 // We can transform the base expression and allow argument resolution to fill
17983 // in the rest.
17984 return getDerived().TransformExpr(E->getArgLValue());
17985}
17986
17987} // end namespace clang
17988
17989#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
17990