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 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 RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3106 bool IsArrow,
3107 SourceLocation AccessorLoc,
3108 IdentifierInfo &Accessor) {
3109
3110 CXXScopeSpec SS;
3111 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3112 return getSema().BuildMemberReferenceExpr(
3113 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3114 /*FirstQualifierInScope*/ nullptr, NameInfo,
3115 /* TemplateArgs */ nullptr,
3116 /*S*/ nullptr);
3117 }
3118
3119 /// Build a new initializer list expression.
3120 ///
3121 /// By default, performs semantic analysis to build the new expression.
3122 /// Subclasses may override this routine to provide different behavior.
3123 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3124 MultiExprArg Inits,
3125 SourceLocation RBraceLoc) {
3126 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3127 }
3128
3129 /// Build a new designated initializer expression.
3130 ///
3131 /// By default, performs semantic analysis to build the new expression.
3132 /// Subclasses may override this routine to provide different behavior.
3133 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3134 MultiExprArg ArrayExprs,
3135 SourceLocation EqualOrColonLoc,
3136 bool GNUSyntax,
3137 Expr *Init) {
3138 ExprResult Result
3139 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3140 Init);
3141 if (Result.isInvalid())
3142 return ExprError();
3143
3144 return Result;
3145 }
3146
3147 /// Build a new value-initialized expression.
3148 ///
3149 /// By default, builds the implicit value initialization without performing
3150 /// any semantic analysis. Subclasses may override this routine to provide
3151 /// different behavior.
3152 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3153 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3154 }
3155
3156 /// Build a new \c va_arg expression.
3157 ///
3158 /// By default, performs semantic analysis to build the new expression.
3159 /// Subclasses may override this routine to provide different behavior.
3160 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3161 Expr *SubExpr, TypeSourceInfo *TInfo,
3162 SourceLocation RParenLoc) {
3163 return getSema().BuildVAArgExpr(BuiltinLoc,
3164 SubExpr, TInfo,
3165 RParenLoc);
3166 }
3167
3168 /// Build a new expression list in parentheses.
3169 ///
3170 /// By default, performs semantic analysis to build the new expression.
3171 /// Subclasses may override this routine to provide different behavior.
3172 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3173 MultiExprArg SubExprs,
3174 SourceLocation RParenLoc) {
3175 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3176 }
3177
3178 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3179 unsigned NumUserSpecifiedExprs,
3180 SourceLocation InitLoc,
3181 SourceLocation LParenLoc,
3182 SourceLocation RParenLoc) {
3183 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3184 InitLoc, LParenLoc, RParenLoc);
3185 }
3186
3187 /// Build a new address-of-label expression.
3188 ///
3189 /// By default, performs semantic analysis, using the name of the label
3190 /// rather than attempting to map the label statement itself.
3191 /// Subclasses may override this routine to provide different behavior.
3192 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3193 SourceLocation LabelLoc, LabelDecl *Label) {
3194 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3195 }
3196
3197 /// Build a new GNU statement expression.
3198 ///
3199 /// By default, performs semantic analysis to build the new expression.
3200 /// Subclasses may override this routine to provide different behavior.
3201 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3202 SourceLocation RParenLoc, unsigned TemplateDepth) {
3203 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3204 TemplateDepth);
3205 }
3206
3207 /// Build a new __builtin_choose_expr expression.
3208 ///
3209 /// By default, performs semantic analysis to build the new expression.
3210 /// Subclasses may override this routine to provide different behavior.
3211 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3212 Expr *Cond, Expr *LHS, Expr *RHS,
3213 SourceLocation RParenLoc) {
3214 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3215 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3216 RPLoc: RParenLoc);
3217 }
3218
3219 /// Build a new generic selection expression with an expression predicate.
3220 ///
3221 /// By default, performs semantic analysis to build the new expression.
3222 /// Subclasses may override this routine to provide different behavior.
3223 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3224 SourceLocation DefaultLoc,
3225 SourceLocation RParenLoc,
3226 Expr *ControllingExpr,
3227 ArrayRef<TypeSourceInfo *> Types,
3228 ArrayRef<Expr *> Exprs) {
3229 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3230 /*PredicateIsExpr=*/true,
3231 ControllingExpr, Types, Exprs);
3232 }
3233
3234 /// Build a new generic selection expression with a type predicate.
3235 ///
3236 /// By default, performs semantic analysis to build the new expression.
3237 /// Subclasses may override this routine to provide different behavior.
3238 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3239 SourceLocation DefaultLoc,
3240 SourceLocation RParenLoc,
3241 TypeSourceInfo *ControllingType,
3242 ArrayRef<TypeSourceInfo *> Types,
3243 ArrayRef<Expr *> Exprs) {
3244 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3245 /*PredicateIsExpr=*/false,
3246 ControllingType, Types, Exprs);
3247 }
3248
3249 /// Build a new overloaded operator call expression.
3250 ///
3251 /// By default, performs semantic analysis to build the new expression.
3252 /// The semantic analysis provides the behavior of template instantiation,
3253 /// copying with transformations that turn what looks like an overloaded
3254 /// operator call into a use of a builtin operator, performing
3255 /// argument-dependent lookup, etc. Subclasses may override this routine to
3256 /// provide different behavior.
3257 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3258 SourceLocation OpLoc,
3259 SourceLocation CalleeLoc,
3260 bool RequiresADL,
3261 const UnresolvedSetImpl &Functions,
3262 Expr *First, Expr *Second);
3263
3264 /// Build a new C++ "named" cast expression, such as static_cast or
3265 /// reinterpret_cast.
3266 ///
3267 /// By default, this routine dispatches to one of the more-specific routines
3268 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3269 /// Subclasses may override this routine to provide different behavior.
3270 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3271 Stmt::StmtClass Class,
3272 SourceLocation LAngleLoc,
3273 TypeSourceInfo *TInfo,
3274 SourceLocation RAngleLoc,
3275 SourceLocation LParenLoc,
3276 Expr *SubExpr,
3277 SourceLocation RParenLoc) {
3278 switch (Class) {
3279 case Stmt::CXXStaticCastExprClass:
3280 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3281 RAngleLoc, LParenLoc,
3282 SubExpr, RParenLoc);
3283
3284 case Stmt::CXXDynamicCastExprClass:
3285 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3286 RAngleLoc, LParenLoc,
3287 SubExpr, RParenLoc);
3288
3289 case Stmt::CXXReinterpretCastExprClass:
3290 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3291 RAngleLoc, LParenLoc,
3292 SubExpr,
3293 RParenLoc);
3294
3295 case Stmt::CXXConstCastExprClass:
3296 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3297 RAngleLoc, LParenLoc,
3298 SubExpr, RParenLoc);
3299
3300 case Stmt::CXXAddrspaceCastExprClass:
3301 return getDerived().RebuildCXXAddrspaceCastExpr(
3302 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3303
3304 default:
3305 llvm_unreachable("Invalid C++ named cast");
3306 }
3307 }
3308
3309 /// Build a new C++ static_cast expression.
3310 ///
3311 /// By default, performs semantic analysis to build the new expression.
3312 /// Subclasses may override this routine to provide different behavior.
3313 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3314 SourceLocation LAngleLoc,
3315 TypeSourceInfo *TInfo,
3316 SourceLocation RAngleLoc,
3317 SourceLocation LParenLoc,
3318 Expr *SubExpr,
3319 SourceLocation RParenLoc) {
3320 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3321 TInfo, SubExpr,
3322 SourceRange(LAngleLoc, RAngleLoc),
3323 SourceRange(LParenLoc, RParenLoc));
3324 }
3325
3326 /// Build a new C++ dynamic_cast expression.
3327 ///
3328 /// By default, performs semantic analysis to build the new expression.
3329 /// Subclasses may override this routine to provide different behavior.
3330 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3331 SourceLocation LAngleLoc,
3332 TypeSourceInfo *TInfo,
3333 SourceLocation RAngleLoc,
3334 SourceLocation LParenLoc,
3335 Expr *SubExpr,
3336 SourceLocation RParenLoc) {
3337 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3338 TInfo, SubExpr,
3339 SourceRange(LAngleLoc, RAngleLoc),
3340 SourceRange(LParenLoc, RParenLoc));
3341 }
3342
3343 /// Build a new C++ reinterpret_cast expression.
3344 ///
3345 /// By default, performs semantic analysis to build the new expression.
3346 /// Subclasses may override this routine to provide different behavior.
3347 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3348 SourceLocation LAngleLoc,
3349 TypeSourceInfo *TInfo,
3350 SourceLocation RAngleLoc,
3351 SourceLocation LParenLoc,
3352 Expr *SubExpr,
3353 SourceLocation RParenLoc) {
3354 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3355 TInfo, SubExpr,
3356 SourceRange(LAngleLoc, RAngleLoc),
3357 SourceRange(LParenLoc, RParenLoc));
3358 }
3359
3360 /// Build a new C++ const_cast expression.
3361 ///
3362 /// By default, performs semantic analysis to build the new expression.
3363 /// Subclasses may override this routine to provide different behavior.
3364 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3365 SourceLocation LAngleLoc,
3366 TypeSourceInfo *TInfo,
3367 SourceLocation RAngleLoc,
3368 SourceLocation LParenLoc,
3369 Expr *SubExpr,
3370 SourceLocation RParenLoc) {
3371 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3372 TInfo, SubExpr,
3373 SourceRange(LAngleLoc, RAngleLoc),
3374 SourceRange(LParenLoc, RParenLoc));
3375 }
3376
3377 ExprResult
3378 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3379 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3380 SourceLocation LParenLoc, Expr *SubExpr,
3381 SourceLocation RParenLoc) {
3382 return getSema().BuildCXXNamedCast(
3383 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3384 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3385 }
3386
3387 /// Build a new C++ functional-style cast expression.
3388 ///
3389 /// By default, performs semantic analysis to build the new expression.
3390 /// Subclasses may override this routine to provide different behavior.
3391 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3392 SourceLocation LParenLoc,
3393 Expr *Sub,
3394 SourceLocation RParenLoc,
3395 bool ListInitialization) {
3396 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3397 // CXXParenListInitExpr. Pass its expanded arguments so that the
3398 // CXXParenListInitExpr can be rebuilt.
3399 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3400 return getSema().BuildCXXTypeConstructExpr(
3401 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3402 RParenLoc, ListInitialization);
3403
3404 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3405 return getSema().BuildCXXTypeConstructExpr(
3406 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3407
3408 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3409 MultiExprArg(&Sub, 1), RParenLoc,
3410 ListInitialization);
3411 }
3412
3413 /// Build a new C++ __builtin_bit_cast expression.
3414 ///
3415 /// By default, performs semantic analysis to build the new expression.
3416 /// Subclasses may override this routine to provide different behavior.
3417 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3418 TypeSourceInfo *TSI, Expr *Sub,
3419 SourceLocation RParenLoc) {
3420 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3421 }
3422
3423 /// Build a new C++ typeid(type) expression.
3424 ///
3425 /// By default, performs semantic analysis to build the new expression.
3426 /// Subclasses may override this routine to provide different behavior.
3427 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3428 SourceLocation TypeidLoc,
3429 TypeSourceInfo *Operand,
3430 SourceLocation RParenLoc) {
3431 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3432 RParenLoc);
3433 }
3434
3435
3436 /// Build a new C++ typeid(expr) expression.
3437 ///
3438 /// By default, performs semantic analysis to build the new expression.
3439 /// Subclasses may override this routine to provide different behavior.
3440 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3441 SourceLocation TypeidLoc,
3442 Expr *Operand,
3443 SourceLocation RParenLoc) {
3444 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3445 RParenLoc);
3446 }
3447
3448 /// Build a new C++ __uuidof(type) expression.
3449 ///
3450 /// By default, performs semantic analysis to build the new expression.
3451 /// Subclasses may override this routine to provide different behavior.
3452 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3453 TypeSourceInfo *Operand,
3454 SourceLocation RParenLoc) {
3455 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3456 }
3457
3458 /// Build a new C++ __uuidof(expr) expression.
3459 ///
3460 /// By default, performs semantic analysis to build the new expression.
3461 /// Subclasses may override this routine to provide different behavior.
3462 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3463 Expr *Operand, SourceLocation RParenLoc) {
3464 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3465 }
3466
3467 /// Build a new C++ "this" expression.
3468 ///
3469 /// By default, performs semantic analysis to build a new "this" expression.
3470 /// Subclasses may override this routine to provide different behavior.
3471 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3472 QualType ThisType,
3473 bool isImplicit) {
3474 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3475 return ExprError();
3476 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3477 }
3478
3479 /// Build a new C++ throw expression.
3480 ///
3481 /// By default, performs semantic analysis to build the new expression.
3482 /// Subclasses may override this routine to provide different behavior.
3483 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3484 bool IsThrownVariableInScope) {
3485 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3486 }
3487
3488 /// Build a new C++ default-argument expression.
3489 ///
3490 /// By default, builds a new default-argument expression, which does not
3491 /// require any semantic analysis. Subclasses may override this routine to
3492 /// provide different behavior.
3493 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3494 Expr *RewrittenExpr) {
3495 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3496 RewrittenExpr, UsedContext: getSema().CurContext);
3497 }
3498
3499 /// Build a new C++11 default-initialization expression.
3500 ///
3501 /// By default, builds a new default field initialization expression, which
3502 /// does not require any semantic analysis. Subclasses may override this
3503 /// routine to provide different behavior.
3504 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3505 FieldDecl *Field) {
3506 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3507 }
3508
3509 /// Build a new C++ zero-initialization expression.
3510 ///
3511 /// By default, performs semantic analysis to build the new expression.
3512 /// Subclasses may override this routine to provide different behavior.
3513 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3514 SourceLocation LParenLoc,
3515 SourceLocation RParenLoc) {
3516 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3517 /*ListInitialization=*/false);
3518 }
3519
3520 /// Build a new C++ "new" expression.
3521 ///
3522 /// By default, performs semantic analysis to build the new expression.
3523 /// Subclasses may override this routine to provide different behavior.
3524 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3525 SourceLocation PlacementLParen,
3526 MultiExprArg PlacementArgs,
3527 SourceLocation PlacementRParen,
3528 SourceRange TypeIdParens, QualType AllocatedType,
3529 TypeSourceInfo *AllocatedTypeInfo,
3530 std::optional<Expr *> ArraySize,
3531 SourceRange DirectInitRange, Expr *Initializer) {
3532 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3533 PlacementLParen,
3534 PlacementArgs,
3535 PlacementRParen,
3536 TypeIdParens,
3537 AllocatedType,
3538 AllocatedTypeInfo,
3539 ArraySize,
3540 DirectInitRange,
3541 Initializer);
3542 }
3543
3544 /// Build a new C++ "delete" expression.
3545 ///
3546 /// By default, performs semantic analysis to build the new expression.
3547 /// Subclasses may override this routine to provide different behavior.
3548 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3549 bool IsGlobalDelete,
3550 bool IsArrayForm,
3551 Expr *Operand) {
3552 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3553 Operand);
3554 }
3555
3556 /// Build a new type trait expression.
3557 ///
3558 /// By default, performs semantic analysis to build the new expression.
3559 /// Subclasses may override this routine to provide different behavior.
3560 ExprResult RebuildTypeTrait(TypeTrait Trait,
3561 SourceLocation StartLoc,
3562 ArrayRef<TypeSourceInfo *> Args,
3563 SourceLocation RParenLoc) {
3564 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3565 }
3566
3567 /// Build a new array type trait expression.
3568 ///
3569 /// By default, performs semantic analysis to build the new expression.
3570 /// Subclasses may override this routine to provide different behavior.
3571 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3572 SourceLocation StartLoc,
3573 TypeSourceInfo *TSInfo,
3574 Expr *DimExpr,
3575 SourceLocation RParenLoc) {
3576 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3577 }
3578
3579 /// Build a new expression trait expression.
3580 ///
3581 /// By default, performs semantic analysis to build the new expression.
3582 /// Subclasses may override this routine to provide different behavior.
3583 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3584 SourceLocation StartLoc,
3585 Expr *Queried,
3586 SourceLocation RParenLoc) {
3587 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3588 }
3589
3590 /// Build a new (previously unresolved) declaration reference
3591 /// expression.
3592 ///
3593 /// By default, performs semantic analysis to build the new expression.
3594 /// Subclasses may override this routine to provide different behavior.
3595 ExprResult RebuildDependentScopeDeclRefExpr(
3596 NestedNameSpecifierLoc QualifierLoc,
3597 SourceLocation TemplateKWLoc,
3598 const DeclarationNameInfo &NameInfo,
3599 const TemplateArgumentListInfo *TemplateArgs,
3600 bool IsAddressOfOperand,
3601 TypeSourceInfo **RecoveryTSI) {
3602 CXXScopeSpec SS;
3603 SS.Adopt(Other: QualifierLoc);
3604
3605 if (TemplateArgs || TemplateKWLoc.isValid())
3606 return getSema().BuildQualifiedTemplateIdExpr(
3607 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3608
3609 return getSema().BuildQualifiedDeclarationNameExpr(
3610 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3611 }
3612
3613 /// Build a new template-id expression.
3614 ///
3615 /// By default, performs semantic analysis to build the new expression.
3616 /// Subclasses may override this routine to provide different behavior.
3617 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3618 SourceLocation TemplateKWLoc,
3619 LookupResult &R,
3620 bool RequiresADL,
3621 const TemplateArgumentListInfo *TemplateArgs) {
3622 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3623 TemplateArgs);
3624 }
3625
3626 /// Build a new object-construction expression.
3627 ///
3628 /// By default, performs semantic analysis to build the new expression.
3629 /// Subclasses may override this routine to provide different behavior.
3630 ExprResult RebuildCXXConstructExpr(
3631 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3632 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3633 bool ListInitialization, bool StdInitListInitialization,
3634 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3635 SourceRange ParenRange) {
3636 // Reconstruct the constructor we originally found, which might be
3637 // different if this is a call to an inherited constructor.
3638 CXXConstructorDecl *FoundCtor = Constructor;
3639 if (Constructor->isInheritingConstructor())
3640 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3641
3642 SmallVector<Expr *, 8> ConvertedArgs;
3643 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3644 ConvertedArgs))
3645 return ExprError();
3646
3647 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3648 IsElidable,
3649 ConvertedArgs,
3650 HadMultipleCandidates,
3651 ListInitialization,
3652 StdInitListInitialization,
3653 RequiresZeroInit, ConstructKind,
3654 ParenRange);
3655 }
3656
3657 /// Build a new implicit construction via inherited constructor
3658 /// expression.
3659 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3660 CXXConstructorDecl *Constructor,
3661 bool ConstructsVBase,
3662 bool InheritedFromVBase) {
3663 return new (getSema().Context) CXXInheritedCtorInitExpr(
3664 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3665 }
3666
3667 /// Build a new object-construction expression.
3668 ///
3669 /// By default, performs semantic analysis to build the new expression.
3670 /// Subclasses may override this routine to provide different behavior.
3671 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3672 SourceLocation LParenOrBraceLoc,
3673 MultiExprArg Args,
3674 SourceLocation RParenOrBraceLoc,
3675 bool ListInitialization) {
3676 return getSema().BuildCXXTypeConstructExpr(
3677 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3678 }
3679
3680 /// Build a new object-construction expression.
3681 ///
3682 /// By default, performs semantic analysis to build the new expression.
3683 /// Subclasses may override this routine to provide different behavior.
3684 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3685 SourceLocation LParenLoc,
3686 MultiExprArg Args,
3687 SourceLocation RParenLoc,
3688 bool ListInitialization) {
3689 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3690 RParenLoc, ListInitialization);
3691 }
3692
3693 /// Build a new member reference expression.
3694 ///
3695 /// By default, performs semantic analysis to build the new expression.
3696 /// Subclasses may override this routine to provide different behavior.
3697 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3698 QualType BaseType,
3699 bool IsArrow,
3700 SourceLocation OperatorLoc,
3701 NestedNameSpecifierLoc QualifierLoc,
3702 SourceLocation TemplateKWLoc,
3703 NamedDecl *FirstQualifierInScope,
3704 const DeclarationNameInfo &MemberNameInfo,
3705 const TemplateArgumentListInfo *TemplateArgs) {
3706 CXXScopeSpec SS;
3707 SS.Adopt(Other: QualifierLoc);
3708
3709 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3710 OpLoc: OperatorLoc, IsArrow,
3711 SS, TemplateKWLoc,
3712 FirstQualifierInScope,
3713 NameInfo: MemberNameInfo,
3714 TemplateArgs, /*S*/S: nullptr);
3715 }
3716
3717 /// Build a new member reference expression.
3718 ///
3719 /// By default, performs semantic analysis to build the new expression.
3720 /// Subclasses may override this routine to provide different behavior.
3721 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3722 SourceLocation OperatorLoc,
3723 bool IsArrow,
3724 NestedNameSpecifierLoc QualifierLoc,
3725 SourceLocation TemplateKWLoc,
3726 NamedDecl *FirstQualifierInScope,
3727 LookupResult &R,
3728 const TemplateArgumentListInfo *TemplateArgs) {
3729 CXXScopeSpec SS;
3730 SS.Adopt(Other: QualifierLoc);
3731
3732 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3733 OpLoc: OperatorLoc, IsArrow,
3734 SS, TemplateKWLoc,
3735 FirstQualifierInScope,
3736 R, TemplateArgs, /*S*/S: nullptr);
3737 }
3738
3739 /// Build a new noexcept expression.
3740 ///
3741 /// By default, performs semantic analysis to build the new expression.
3742 /// Subclasses may override this routine to provide different behavior.
3743 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3744 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3745 }
3746
3747 UnsignedOrNone
3748 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3749
3750 /// Build a new expression to compute the length of a parameter pack.
3751 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3752 SourceLocation PackLoc,
3753 SourceLocation RParenLoc,
3754 UnsignedOrNone Length,
3755 ArrayRef<TemplateArgument> PartialArgs) {
3756 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3757 RParenLoc, Length, PartialArgs);
3758 }
3759
3760 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3761 SourceLocation RSquareLoc,
3762 Expr *PackIdExpression, Expr *IndexExpr,
3763 ArrayRef<Expr *> ExpandedExprs,
3764 bool FullySubstituted = false) {
3765 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3766 IndexExpr, RSquareLoc, ExpandedExprs,
3767 FullySubstituted);
3768 }
3769
3770 /// Build a new expression representing a call to a source location
3771 /// builtin.
3772 ///
3773 /// By default, performs semantic analysis to build the new expression.
3774 /// Subclasses may override this routine to provide different behavior.
3775 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3776 SourceLocation BuiltinLoc,
3777 SourceLocation RPLoc,
3778 DeclContext *ParentContext) {
3779 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3780 ParentContext);
3781 }
3782
3783 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3784 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3785 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3786 TemplateArgumentListInfo *TALI) {
3787 CXXScopeSpec SS;
3788 SS.Adopt(Other: NNS);
3789 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3790 ConceptNameInfo,
3791 FoundDecl,
3792 NamedConcept, TALI);
3793 if (Result.isInvalid())
3794 return ExprError();
3795 return Result;
3796 }
3797
3798 /// \brief Build a new requires expression.
3799 ///
3800 /// By default, performs semantic analysis to build the new expression.
3801 /// Subclasses may override this routine to provide different behavior.
3802 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3803 RequiresExprBodyDecl *Body,
3804 SourceLocation LParenLoc,
3805 ArrayRef<ParmVarDecl *> LocalParameters,
3806 SourceLocation RParenLoc,
3807 ArrayRef<concepts::Requirement *> Requirements,
3808 SourceLocation ClosingBraceLoc) {
3809 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3810 LocalParameters, RParenLoc, Requirements,
3811 RBraceLoc: ClosingBraceLoc);
3812 }
3813
3814 concepts::TypeRequirement *
3815 RebuildTypeRequirement(
3816 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3817 return SemaRef.BuildTypeRequirement(SubstDiag);
3818 }
3819
3820 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3821 return SemaRef.BuildTypeRequirement(Type: T);
3822 }
3823
3824 concepts::ExprRequirement *
3825 RebuildExprRequirement(
3826 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3827 SourceLocation NoexceptLoc,
3828 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3829 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3830 ReturnTypeRequirement: std::move(Ret));
3831 }
3832
3833 concepts::ExprRequirement *
3834 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3835 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3836 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3837 ReturnTypeRequirement: std::move(Ret));
3838 }
3839
3840 concepts::NestedRequirement *
3841 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3842 const ASTConstraintSatisfaction &Satisfaction) {
3843 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3844 Satisfaction);
3845 }
3846
3847 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3848 return SemaRef.BuildNestedRequirement(E: Constraint);
3849 }
3850
3851 /// \brief Build a new Objective-C boxed expression.
3852 ///
3853 /// By default, performs semantic analysis to build the new expression.
3854 /// Subclasses may override this routine to provide different behavior.
3855 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3856 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3857 }
3858
3859 /// Build a new Objective-C array literal.
3860 ///
3861 /// By default, performs semantic analysis to build the new expression.
3862 /// Subclasses may override this routine to provide different behavior.
3863 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3864 Expr **Elements, unsigned NumElements) {
3865 return getSema().ObjC().BuildObjCArrayLiteral(
3866 Range, MultiExprArg(Elements, NumElements));
3867 }
3868
3869 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3870 Expr *Base, Expr *Key,
3871 ObjCMethodDecl *getterMethod,
3872 ObjCMethodDecl *setterMethod) {
3873 return getSema().ObjC().BuildObjCSubscriptExpression(
3874 RB, Base, Key, getterMethod, setterMethod);
3875 }
3876
3877 /// Build a new Objective-C dictionary literal.
3878 ///
3879 /// By default, performs semantic analysis to build the new expression.
3880 /// Subclasses may override this routine to provide different behavior.
3881 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3882 MutableArrayRef<ObjCDictionaryElement> Elements) {
3883 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3884 }
3885
3886 /// Build a new Objective-C \@encode expression.
3887 ///
3888 /// By default, performs semantic analysis to build the new expression.
3889 /// Subclasses may override this routine to provide different behavior.
3890 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3891 TypeSourceInfo *EncodeTypeInfo,
3892 SourceLocation RParenLoc) {
3893 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3894 RParenLoc);
3895 }
3896
3897 /// Build a new Objective-C class message.
3898 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3899 Selector Sel,
3900 ArrayRef<SourceLocation> SelectorLocs,
3901 ObjCMethodDecl *Method,
3902 SourceLocation LBracLoc,
3903 MultiExprArg Args,
3904 SourceLocation RBracLoc) {
3905 return SemaRef.ObjC().BuildClassMessage(
3906 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3907 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3908 RBracLoc, Args);
3909 }
3910
3911 /// Build a new Objective-C instance message.
3912 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3913 Selector Sel,
3914 ArrayRef<SourceLocation> SelectorLocs,
3915 ObjCMethodDecl *Method,
3916 SourceLocation LBracLoc,
3917 MultiExprArg Args,
3918 SourceLocation RBracLoc) {
3919 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3920 /*SuperLoc=*/SuperLoc: SourceLocation(),
3921 Sel, Method, LBracLoc,
3922 SelectorLocs, RBracLoc, Args);
3923 }
3924
3925 /// Build a new Objective-C instance/class message to 'super'.
3926 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3927 Selector Sel,
3928 ArrayRef<SourceLocation> SelectorLocs,
3929 QualType SuperType,
3930 ObjCMethodDecl *Method,
3931 SourceLocation LBracLoc,
3932 MultiExprArg Args,
3933 SourceLocation RBracLoc) {
3934 return Method->isInstanceMethod()
3935 ? SemaRef.ObjC().BuildInstanceMessage(
3936 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3937 SelectorLocs, RBracLoc, Args)
3938 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3939 Sel, Method, LBracLoc,
3940 SelectorLocs, RBracLoc, Args);
3941 }
3942
3943 /// Build a new Objective-C ivar reference expression.
3944 ///
3945 /// By default, performs semantic analysis to build the new expression.
3946 /// Subclasses may override this routine to provide different behavior.
3947 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3948 SourceLocation IvarLoc,
3949 bool IsArrow, bool IsFreeIvar) {
3950 CXXScopeSpec SS;
3951 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3952 ExprResult Result = getSema().BuildMemberReferenceExpr(
3953 BaseArg, BaseArg->getType(),
3954 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3955 /*FirstQualifierInScope=*/nullptr, NameInfo,
3956 /*TemplateArgs=*/nullptr,
3957 /*S=*/nullptr);
3958 if (IsFreeIvar && Result.isUsable())
3959 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3960 return Result;
3961 }
3962
3963 /// Build a new Objective-C property reference expression.
3964 ///
3965 /// By default, performs semantic analysis to build the new expression.
3966 /// Subclasses may override this routine to provide different behavior.
3967 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3968 ObjCPropertyDecl *Property,
3969 SourceLocation PropertyLoc) {
3970 CXXScopeSpec SS;
3971 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3972 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3973 /*FIXME:*/PropertyLoc,
3974 /*IsArrow=*/false,
3975 SS, SourceLocation(),
3976 /*FirstQualifierInScope=*/nullptr,
3977 NameInfo,
3978 /*TemplateArgs=*/nullptr,
3979 /*S=*/nullptr);
3980 }
3981
3982 /// Build a new Objective-C property reference expression.
3983 ///
3984 /// By default, performs semantic analysis to build the new expression.
3985 /// Subclasses may override this routine to provide different behavior.
3986 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3987 ObjCMethodDecl *Getter,
3988 ObjCMethodDecl *Setter,
3989 SourceLocation PropertyLoc) {
3990 // Since these expressions can only be value-dependent, we do not
3991 // need to perform semantic analysis again.
3992 return Owned(
3993 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3994 VK_LValue, OK_ObjCProperty,
3995 PropertyLoc, Base));
3996 }
3997
3998 /// Build a new Objective-C "isa" expression.
3999 ///
4000 /// By default, performs semantic analysis to build the new expression.
4001 /// Subclasses may override this routine to provide different behavior.
4002 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4003 SourceLocation OpLoc, bool IsArrow) {
4004 CXXScopeSpec SS;
4005 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4006 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4007 OpLoc, IsArrow,
4008 SS, SourceLocation(),
4009 /*FirstQualifierInScope=*/nullptr,
4010 NameInfo,
4011 /*TemplateArgs=*/nullptr,
4012 /*S=*/nullptr);
4013 }
4014
4015 /// Build a new shuffle vector expression.
4016 ///
4017 /// By default, performs semantic analysis to build the new expression.
4018 /// Subclasses may override this routine to provide different behavior.
4019 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4020 MultiExprArg SubExprs,
4021 SourceLocation RParenLoc) {
4022 // Find the declaration for __builtin_shufflevector
4023 const IdentifierInfo &Name
4024 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4025 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4026 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4027 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4028
4029 // Build a reference to the __builtin_shufflevector builtin
4030 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4031 Expr *Callee = new (SemaRef.Context)
4032 DeclRefExpr(SemaRef.Context, Builtin, false,
4033 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4034 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4035 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4036 CK: CK_BuiltinFnToFnPtr).get();
4037
4038 // Build the CallExpr
4039 ExprResult TheCall = CallExpr::Create(
4040 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4041 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4042 FPFeatures: FPOptionsOverride());
4043
4044 // Type-check the __builtin_shufflevector expression.
4045 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4046 }
4047
4048 /// Build a new convert vector expression.
4049 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4050 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4051 SourceLocation RParenLoc) {
4052 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4053 }
4054
4055 /// Build a new template argument pack expansion.
4056 ///
4057 /// By default, performs semantic analysis to build a new pack expansion
4058 /// for a template argument. Subclasses may override this routine to provide
4059 /// different behavior.
4060 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4061 SourceLocation EllipsisLoc,
4062 UnsignedOrNone NumExpansions) {
4063 switch (Pattern.getArgument().getKind()) {
4064 case TemplateArgument::Expression: {
4065 ExprResult Result
4066 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4067 EllipsisLoc, NumExpansions);
4068 if (Result.isInvalid())
4069 return TemplateArgumentLoc();
4070
4071 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4072 /*IsCanonical=*/false),
4073 Result.get());
4074 }
4075
4076 case TemplateArgument::Template:
4077 return TemplateArgumentLoc(
4078 SemaRef.Context,
4079 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4080 NumExpansions),
4081 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4082 Pattern.getTemplateNameLoc(), EllipsisLoc);
4083
4084 case TemplateArgument::Null:
4085 case TemplateArgument::Integral:
4086 case TemplateArgument::Declaration:
4087 case TemplateArgument::StructuralValue:
4088 case TemplateArgument::Pack:
4089 case TemplateArgument::TemplateExpansion:
4090 case TemplateArgument::NullPtr:
4091 llvm_unreachable("Pack expansion pattern has no parameter packs");
4092
4093 case TemplateArgument::Type:
4094 if (TypeSourceInfo *Expansion
4095 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4096 EllipsisLoc,
4097 NumExpansions))
4098 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4099 Expansion);
4100 break;
4101 }
4102
4103 return TemplateArgumentLoc();
4104 }
4105
4106 /// Build a new expression pack expansion.
4107 ///
4108 /// By default, performs semantic analysis to build a new pack expansion
4109 /// for an expression. Subclasses may override this routine to provide
4110 /// different behavior.
4111 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4112 UnsignedOrNone NumExpansions) {
4113 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4114 }
4115
4116 /// Build a new C++1z fold-expression.
4117 ///
4118 /// By default, performs semantic analysis in order to build a new fold
4119 /// expression.
4120 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4121 SourceLocation LParenLoc, Expr *LHS,
4122 BinaryOperatorKind Operator,
4123 SourceLocation EllipsisLoc, Expr *RHS,
4124 SourceLocation RParenLoc,
4125 UnsignedOrNone NumExpansions) {
4126 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4127 EllipsisLoc, RHS, RParenLoc,
4128 NumExpansions);
4129 }
4130
4131 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4132 LambdaScopeInfo *LSI) {
4133 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4134 if (Expr *Init = PVD->getInit())
4135 LSI->ContainsUnexpandedParameterPack |=
4136 Init->containsUnexpandedParameterPack();
4137 else if (PVD->hasUninstantiatedDefaultArg())
4138 LSI->ContainsUnexpandedParameterPack |=
4139 PVD->getUninstantiatedDefaultArg()
4140 ->containsUnexpandedParameterPack();
4141 }
4142 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4143 }
4144
4145 /// Build an empty C++1z fold-expression with the given operator.
4146 ///
4147 /// By default, produces the fallback value for the fold-expression, or
4148 /// produce an error if there is no fallback value.
4149 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4150 BinaryOperatorKind Operator) {
4151 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4152 }
4153
4154 /// Build a new atomic operation expression.
4155 ///
4156 /// By default, performs semantic analysis to build the new expression.
4157 /// Subclasses may override this routine to provide different behavior.
4158 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4159 AtomicExpr::AtomicOp Op,
4160 SourceLocation RParenLoc) {
4161 // Use this for all of the locations, since we don't know the difference
4162 // between the call and the expr at this point.
4163 SourceRange Range{BuiltinLoc, RParenLoc};
4164 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4165 Sema::AtomicArgumentOrder::AST);
4166 }
4167
4168 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4169 ArrayRef<Expr *> SubExprs, QualType Type) {
4170 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4171 }
4172
4173 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4174 SourceLocation BeginLoc,
4175 SourceLocation DirLoc,
4176 SourceLocation EndLoc,
4177 ArrayRef<OpenACCClause *> Clauses,
4178 StmtResult StrBlock) {
4179 return getSema().OpenACC().ActOnEndStmtDirective(
4180 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4181 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4182 }
4183
4184 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4185 SourceLocation DirLoc,
4186 SourceLocation EndLoc,
4187 ArrayRef<OpenACCClause *> Clauses,
4188 StmtResult Loop) {
4189 return getSema().OpenACC().ActOnEndStmtDirective(
4190 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4191 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4192 Clauses, Loop);
4193 }
4194
4195 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4196 SourceLocation BeginLoc,
4197 SourceLocation DirLoc,
4198 SourceLocation EndLoc,
4199 ArrayRef<OpenACCClause *> Clauses,
4200 StmtResult Loop) {
4201 return getSema().OpenACC().ActOnEndStmtDirective(
4202 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4203 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4204 }
4205
4206 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4207 SourceLocation DirLoc,
4208 SourceLocation EndLoc,
4209 ArrayRef<OpenACCClause *> Clauses,
4210 StmtResult StrBlock) {
4211 return getSema().OpenACC().ActOnEndStmtDirective(
4212 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4213 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4214 Clauses, StrBlock);
4215 }
4216
4217 StmtResult
4218 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4219 SourceLocation DirLoc, SourceLocation EndLoc,
4220 ArrayRef<OpenACCClause *> Clauses) {
4221 return getSema().OpenACC().ActOnEndStmtDirective(
4222 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4223 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4224 Clauses, {});
4225 }
4226
4227 StmtResult
4228 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4229 SourceLocation DirLoc, SourceLocation EndLoc,
4230 ArrayRef<OpenACCClause *> Clauses) {
4231 return getSema().OpenACC().ActOnEndStmtDirective(
4232 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4233 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4234 Clauses, {});
4235 }
4236
4237 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4238 SourceLocation DirLoc,
4239 SourceLocation EndLoc,
4240 ArrayRef<OpenACCClause *> Clauses,
4241 StmtResult StrBlock) {
4242 return getSema().OpenACC().ActOnEndStmtDirective(
4243 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4244 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4245 Clauses, StrBlock);
4246 }
4247
4248 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4249 SourceLocation DirLoc,
4250 SourceLocation EndLoc,
4251 ArrayRef<OpenACCClause *> Clauses) {
4252 return getSema().OpenACC().ActOnEndStmtDirective(
4253 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4254 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4255 Clauses, {});
4256 }
4257
4258 StmtResult
4259 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4260 SourceLocation DirLoc, SourceLocation EndLoc,
4261 ArrayRef<OpenACCClause *> Clauses) {
4262 return getSema().OpenACC().ActOnEndStmtDirective(
4263 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4264 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4265 Clauses, {});
4266 }
4267
4268 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4269 SourceLocation DirLoc,
4270 SourceLocation EndLoc,
4271 ArrayRef<OpenACCClause *> Clauses) {
4272 return getSema().OpenACC().ActOnEndStmtDirective(
4273 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4274 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4275 Clauses, {});
4276 }
4277
4278 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4279 SourceLocation DirLoc,
4280 SourceLocation EndLoc,
4281 ArrayRef<OpenACCClause *> Clauses) {
4282 return getSema().OpenACC().ActOnEndStmtDirective(
4283 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4284 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4285 Clauses, {});
4286 }
4287
4288 StmtResult RebuildOpenACCWaitConstruct(
4289 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4290 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4291 SourceLocation RParenLoc, SourceLocation EndLoc,
4292 ArrayRef<OpenACCClause *> Clauses) {
4293 llvm::SmallVector<Expr *> Exprs;
4294 Exprs.push_back(Elt: DevNumExpr);
4295 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4296 return getSema().OpenACC().ActOnEndStmtDirective(
4297 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4298 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4299 }
4300
4301 StmtResult RebuildOpenACCCacheConstruct(
4302 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4303 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4304 SourceLocation RParenLoc, SourceLocation EndLoc) {
4305 return getSema().OpenACC().ActOnEndStmtDirective(
4306 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4307 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4308 }
4309
4310 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4311 SourceLocation DirLoc,
4312 OpenACCAtomicKind AtKind,
4313 SourceLocation EndLoc,
4314 ArrayRef<OpenACCClause *> Clauses,
4315 StmtResult AssociatedStmt) {
4316 return getSema().OpenACC().ActOnEndStmtDirective(
4317 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4318 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4319 AssociatedStmt);
4320 }
4321
4322 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4323 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4324 }
4325
4326 ExprResult
4327 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl,
4328 const NonTypeTemplateParmDecl *NTTP,
4329 SourceLocation Loc, TemplateArgument Arg,
4330 UnsignedOrNone PackIndex, bool Final) {
4331 return getSema().BuildSubstNonTypeTemplateParmExpr(
4332 AssociatedDecl, NTTP, Loc, Arg, PackIndex, Final);
4333 }
4334
4335 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4336 SourceLocation StartLoc,
4337 SourceLocation LParenLoc,
4338 SourceLocation EndLoc) {
4339 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4340 LParenLoc, EndLoc);
4341 }
4342
4343private:
4344 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4345 QualType ObjectType,
4346 NamedDecl *FirstQualifierInScope);
4347
4348 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4349 QualType ObjectType,
4350 NamedDecl *FirstQualifierInScope) {
4351 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4352 return TSInfo;
4353
4354 TypeLocBuilder TLB;
4355 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4356 ObjectType, FirstQualifierInScope);
4357 if (T.isNull())
4358 return nullptr;
4359 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4360 }
4361
4362 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4363 DependentNameTypeLoc TL,
4364 bool DeducibleTSTContext,
4365 QualType ObjectType = QualType(),
4366 NamedDecl *UnqualLookup = nullptr);
4367
4368 llvm::SmallVector<OpenACCClause *>
4369 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4370 ArrayRef<const OpenACCClause *> OldClauses);
4371
4372 OpenACCClause *
4373 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4374 OpenACCDirectiveKind DirKind,
4375 const OpenACCClause *OldClause);
4376};
4377
4378template <typename Derived>
4379StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4380 if (!S)
4381 return S;
4382
4383 switch (S->getStmtClass()) {
4384 case Stmt::NoStmtClass: break;
4385
4386 // Transform individual statement nodes
4387 // Pass SDK into statements that can produce a value
4388#define STMT(Node, Parent) \
4389 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4390#define VALUESTMT(Node, Parent) \
4391 case Stmt::Node##Class: \
4392 return getDerived().Transform##Node(cast<Node>(S), SDK);
4393#define ABSTRACT_STMT(Node)
4394#define EXPR(Node, Parent)
4395#include "clang/AST/StmtNodes.inc"
4396
4397 // Transform expressions by calling TransformExpr.
4398#define STMT(Node, Parent)
4399#define ABSTRACT_STMT(Stmt)
4400#define EXPR(Node, Parent) case Stmt::Node##Class:
4401#include "clang/AST/StmtNodes.inc"
4402 {
4403 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4404
4405 if (SDK == StmtDiscardKind::StmtExprResult)
4406 E = getSema().ActOnStmtExprResult(E);
4407 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4408 }
4409 }
4410
4411 return S;
4412}
4413
4414template<typename Derived>
4415OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4416 if (!S)
4417 return S;
4418
4419 switch (S->getClauseKind()) {
4420 default: break;
4421 // Transform individual clause nodes
4422#define GEN_CLANG_CLAUSE_CLASS
4423#define CLAUSE_CLASS(Enum, Str, Class) \
4424 case Enum: \
4425 return getDerived().Transform##Class(cast<Class>(S));
4426#include "llvm/Frontend/OpenMP/OMP.inc"
4427 }
4428
4429 return S;
4430}
4431
4432
4433template<typename Derived>
4434ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4435 if (!E)
4436 return E;
4437
4438 switch (E->getStmtClass()) {
4439 case Stmt::NoStmtClass: break;
4440#define STMT(Node, Parent) case Stmt::Node##Class: break;
4441#define ABSTRACT_STMT(Stmt)
4442#define EXPR(Node, Parent) \
4443 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4444#include "clang/AST/StmtNodes.inc"
4445 }
4446
4447 return E;
4448}
4449
4450template<typename Derived>
4451ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4452 bool NotCopyInit) {
4453 // Initializers are instantiated like expressions, except that various outer
4454 // layers are stripped.
4455 if (!Init)
4456 return Init;
4457
4458 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4459 Init = FE->getSubExpr();
4460
4461 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4462 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4463 Init = OVE->getSourceExpr();
4464 }
4465
4466 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4467 Init = MTE->getSubExpr();
4468
4469 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4470 Init = Binder->getSubExpr();
4471
4472 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4473 Init = ICE->getSubExprAsWritten();
4474
4475 if (CXXStdInitializerListExpr *ILE =
4476 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4477 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4478
4479 // If this is copy-initialization, we only need to reconstruct
4480 // InitListExprs. Other forms of copy-initialization will be a no-op if
4481 // the initializer is already the right type.
4482 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4483 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4484 return getDerived().TransformExpr(Init);
4485
4486 // Revert value-initialization back to empty parens.
4487 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4488 SourceRange Parens = VIE->getSourceRange();
4489 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4490 Parens.getEnd());
4491 }
4492
4493 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4494 if (isa<ImplicitValueInitExpr>(Val: Init))
4495 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4496 SourceLocation());
4497
4498 // Revert initialization by constructor back to a parenthesized or braced list
4499 // of expressions. Any other form of initializer can just be reused directly.
4500 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4501 return getDerived().TransformExpr(Init);
4502
4503 // If the initialization implicitly converted an initializer list to a
4504 // std::initializer_list object, unwrap the std::initializer_list too.
4505 if (Construct && Construct->isStdInitListInitialization())
4506 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4507
4508 // Enter a list-init context if this was list initialization.
4509 EnterExpressionEvaluationContext Context(
4510 getSema(), EnterExpressionEvaluationContext::InitList,
4511 Construct->isListInitialization());
4512
4513 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4514 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4515 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4516 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4517 SmallVector<Expr*, 8> NewArgs;
4518 bool ArgChanged = false;
4519 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4520 /*IsCall*/true, NewArgs, &ArgChanged))
4521 return ExprError();
4522
4523 // If this was list initialization, revert to syntactic list form.
4524 if (Construct->isListInitialization())
4525 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4526 Construct->getEndLoc());
4527
4528 // Build a ParenListExpr to represent anything else.
4529 SourceRange Parens = Construct->getParenOrBraceRange();
4530 if (Parens.isInvalid()) {
4531 // This was a variable declaration's initialization for which no initializer
4532 // was specified.
4533 assert(NewArgs.empty() &&
4534 "no parens or braces but have direct init with arguments?");
4535 return ExprEmpty();
4536 }
4537 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4538 Parens.getEnd());
4539}
4540
4541template<typename Derived>
4542bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4543 unsigned NumInputs,
4544 bool IsCall,
4545 SmallVectorImpl<Expr *> &Outputs,
4546 bool *ArgChanged) {
4547 for (unsigned I = 0; I != NumInputs; ++I) {
4548 // If requested, drop call arguments that need to be dropped.
4549 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4550 if (ArgChanged)
4551 *ArgChanged = true;
4552
4553 break;
4554 }
4555
4556 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4557 Expr *Pattern = Expansion->getPattern();
4558
4559 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4560 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4561 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4562
4563 // Determine whether the set of unexpanded parameter packs can and should
4564 // be expanded.
4565 bool Expand = true;
4566 bool RetainExpansion = false;
4567 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4568 UnsignedOrNone NumExpansions = OrigNumExpansions;
4569 if (getDerived().TryExpandParameterPacks(
4570 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4571 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4572 RetainExpansion, NumExpansions))
4573 return true;
4574
4575 if (!Expand) {
4576 // The transform has determined that we should perform a simple
4577 // transformation on the pack expansion, producing another pack
4578 // expansion.
4579 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4580 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4581 if (OutPattern.isInvalid())
4582 return true;
4583
4584 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4585 Expansion->getEllipsisLoc(),
4586 NumExpansions);
4587 if (Out.isInvalid())
4588 return true;
4589
4590 if (ArgChanged)
4591 *ArgChanged = true;
4592 Outputs.push_back(Elt: Out.get());
4593 continue;
4594 }
4595
4596 // Record right away that the argument was changed. This needs
4597 // to happen even if the array expands to nothing.
4598 if (ArgChanged) *ArgChanged = true;
4599
4600 // The transform has determined that we should perform an elementwise
4601 // expansion of the pattern. Do so.
4602 for (unsigned I = 0; I != *NumExpansions; ++I) {
4603 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4604 ExprResult Out = getDerived().TransformExpr(Pattern);
4605 if (Out.isInvalid())
4606 return true;
4607
4608 if (Out.get()->containsUnexpandedParameterPack()) {
4609 Out = getDerived().RebuildPackExpansion(
4610 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4611 if (Out.isInvalid())
4612 return true;
4613 }
4614
4615 Outputs.push_back(Elt: Out.get());
4616 }
4617
4618 // If we're supposed to retain a pack expansion, do so by temporarily
4619 // forgetting the partially-substituted parameter pack.
4620 if (RetainExpansion) {
4621 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4622
4623 ExprResult Out = getDerived().TransformExpr(Pattern);
4624 if (Out.isInvalid())
4625 return true;
4626
4627 Out = getDerived().RebuildPackExpansion(
4628 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4629 if (Out.isInvalid())
4630 return true;
4631
4632 Outputs.push_back(Elt: Out.get());
4633 }
4634
4635 continue;
4636 }
4637
4638 ExprResult Result =
4639 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4640 : getDerived().TransformExpr(Inputs[I]);
4641 if (Result.isInvalid())
4642 return true;
4643
4644 if (Result.get() != Inputs[I] && ArgChanged)
4645 *ArgChanged = true;
4646
4647 Outputs.push_back(Elt: Result.get());
4648 }
4649
4650 return false;
4651}
4652
4653template <typename Derived>
4654Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4655 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4656
4657 EnterExpressionEvaluationContext Eval(
4658 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4659 /*LambdaContextDecl=*/nullptr,
4660 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4661 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4662
4663 if (Var) {
4664 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4665 getDerived().TransformDefinition(Var->getLocation(), Var));
4666
4667 if (!ConditionVar)
4668 return Sema::ConditionError();
4669
4670 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4671 }
4672
4673 if (Expr) {
4674 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4675
4676 if (CondExpr.isInvalid())
4677 return Sema::ConditionError();
4678
4679 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4680 /*MissingOK=*/true);
4681 }
4682
4683 return Sema::ConditionResult();
4684}
4685
4686template <typename Derived>
4687NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4688 NestedNameSpecifierLoc NNS, QualType ObjectType,
4689 NamedDecl *FirstQualifierInScope) {
4690 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4691
4692 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4693 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4694 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4695 Qualifiers.push_back(Elt: Qualifier);
4696 };
4697 insertNNS(NNS);
4698
4699 CXXScopeSpec SS;
4700 while (!Qualifiers.empty()) {
4701 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4702 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4703
4704 switch (QNNS.getKind()) {
4705 case NestedNameSpecifier::Kind::Null:
4706 llvm_unreachable("unexpected null nested name specifier");
4707
4708 case NestedNameSpecifier::Kind::Namespace: {
4709 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4710 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4711 QNNS.getAsNamespaceAndPrefix().Namespace)));
4712 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4713 break;
4714 }
4715
4716 case NestedNameSpecifier::Kind::Global:
4717 // There is no meaningful transformation that one could perform on the
4718 // global scope.
4719 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4720 break;
4721
4722 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4723 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4724 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4725 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4726 ColonColonLoc: Q.getEndLoc());
4727 break;
4728 }
4729
4730 case NestedNameSpecifier::Kind::Type: {
4731 assert(SS.isEmpty());
4732 TypeLoc TL = Q.castAsTypeLoc();
4733
4734 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4735 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4736 if (QualifierLoc) {
4737 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4738 QualifierLoc, ObjectType, FirstQualifierInScope);
4739 if (!QualifierLoc)
4740 return NestedNameSpecifierLoc();
4741 ObjectType = QualType();
4742 FirstQualifierInScope = nullptr;
4743 }
4744 SS.Adopt(Other: QualifierLoc);
4745 Sema::NestedNameSpecInfo IdInfo(
4746 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4747 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4748 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4749 EnteringContext: false, SS,
4750 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4751 return NestedNameSpecifierLoc();
4752 return SS.getWithLocInContext(Context&: SemaRef.Context);
4753 }
4754
4755 QualType T = TL.getType();
4756 TypeLocBuilder TLB;
4757 if (!getDerived().AlreadyTransformed(T)) {
4758 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4759 FirstQualifierInScope);
4760 if (T.isNull())
4761 return NestedNameSpecifierLoc();
4762 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4763 }
4764
4765 if (T->isDependentType() || T->isRecordType() ||
4766 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4767 if (T->isEnumeralType())
4768 SemaRef.Diag(Loc: TL.getBeginLoc(),
4769 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4770 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4771 break;
4772 }
4773 // If the nested-name-specifier is an invalid type def, don't emit an
4774 // error because a previous error should have already been emitted.
4775 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4776 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4777 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4778 << T << SS.getRange();
4779 }
4780 return NestedNameSpecifierLoc();
4781 }
4782 }
4783 }
4784
4785 // Don't rebuild the nested-name-specifier if we don't have to.
4786 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4787 !getDerived().AlwaysRebuild())
4788 return NNS;
4789
4790 // If we can re-use the source-location data from the original
4791 // nested-name-specifier, do so.
4792 if (SS.location_size() == NNS.getDataLength() &&
4793 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4794 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4795
4796 // Allocate new nested-name-specifier location information.
4797 return SS.getWithLocInContext(Context&: SemaRef.Context);
4798}
4799
4800template<typename Derived>
4801DeclarationNameInfo
4802TreeTransform<Derived>
4803::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4804 DeclarationName Name = NameInfo.getName();
4805 if (!Name)
4806 return DeclarationNameInfo();
4807
4808 switch (Name.getNameKind()) {
4809 case DeclarationName::Identifier:
4810 case DeclarationName::ObjCZeroArgSelector:
4811 case DeclarationName::ObjCOneArgSelector:
4812 case DeclarationName::ObjCMultiArgSelector:
4813 case DeclarationName::CXXOperatorName:
4814 case DeclarationName::CXXLiteralOperatorName:
4815 case DeclarationName::CXXUsingDirective:
4816 return NameInfo;
4817
4818 case DeclarationName::CXXDeductionGuideName: {
4819 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4820 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4821 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4822 if (!NewTemplate)
4823 return DeclarationNameInfo();
4824
4825 DeclarationNameInfo NewNameInfo(NameInfo);
4826 NewNameInfo.setName(
4827 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4828 return NewNameInfo;
4829 }
4830
4831 case DeclarationName::CXXConstructorName:
4832 case DeclarationName::CXXDestructorName:
4833 case DeclarationName::CXXConversionFunctionName: {
4834 TypeSourceInfo *NewTInfo;
4835 CanQualType NewCanTy;
4836 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4837 NewTInfo = getDerived().TransformType(OldTInfo);
4838 if (!NewTInfo)
4839 return DeclarationNameInfo();
4840 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4841 }
4842 else {
4843 NewTInfo = nullptr;
4844 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4845 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4846 if (NewT.isNull())
4847 return DeclarationNameInfo();
4848 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4849 }
4850
4851 DeclarationName NewName
4852 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4853 Ty: NewCanTy);
4854 DeclarationNameInfo NewNameInfo(NameInfo);
4855 NewNameInfo.setName(NewName);
4856 NewNameInfo.setNamedTypeInfo(NewTInfo);
4857 return NewNameInfo;
4858 }
4859 }
4860
4861 llvm_unreachable("Unknown name kind.");
4862}
4863
4864template <typename Derived>
4865TemplateName TreeTransform<Derived>::RebuildTemplateName(
4866 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4867 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4868 QualType ObjectType, bool AllowInjectedClassName) {
4869 if (const IdentifierInfo *II = IO.getIdentifier())
4870 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4871 ObjectType, AllowInjectedClassName);
4872 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4873 NameLoc, ObjectType,
4874 AllowInjectedClassName);
4875}
4876
4877template <typename Derived>
4878TemplateName TreeTransform<Derived>::TransformTemplateName(
4879 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4880 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4881 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4882 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4883 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4884
4885 if (QualifierLoc) {
4886 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4887 QualifierLoc, ObjectType, FirstQualifierInScope);
4888 if (!QualifierLoc)
4889 return TemplateName();
4890 }
4891
4892 NestedNameSpecifierLoc UnderlyingQualifier;
4893 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4894 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4895 FirstQualifierInScope, AllowInjectedClassName);
4896 if (NewUnderlyingName.isNull())
4897 return TemplateName();
4898 assert(!UnderlyingQualifier && "unexpected qualifier");
4899
4900 if (!getDerived().AlwaysRebuild() &&
4901 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4902 NewUnderlyingName == UnderlyingName)
4903 return Name;
4904 CXXScopeSpec SS;
4905 SS.Adopt(Other: QualifierLoc);
4906 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4907 NewUnderlyingName);
4908 }
4909
4910 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4911 if (QualifierLoc) {
4912 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4913 QualifierLoc, ObjectType, FirstQualifierInScope);
4914 if (!QualifierLoc)
4915 return TemplateName();
4916 // The qualifier-in-scope and object type only apply to the leftmost
4917 // entity.
4918 ObjectType = QualType();
4919 }
4920
4921 if (!getDerived().AlwaysRebuild() &&
4922 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4923 ObjectType.isNull())
4924 return Name;
4925
4926 CXXScopeSpec SS;
4927 SS.Adopt(Other: QualifierLoc);
4928 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4929 NameLoc, ObjectType,
4930 AllowInjectedClassName);
4931 }
4932
4933 if (SubstTemplateTemplateParmStorage *S =
4934 Name.getAsSubstTemplateTemplateParm()) {
4935 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4936
4937 NestedNameSpecifierLoc ReplacementQualifierLoc;
4938 TemplateName ReplacementName = S->getReplacement();
4939 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4940 NestedNameSpecifierLocBuilder Builder;
4941 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4942 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4943 }
4944
4945 TemplateName NewName = getDerived().TransformTemplateName(
4946 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4947 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4948 if (NewName.isNull())
4949 return TemplateName();
4950 Decl *AssociatedDecl =
4951 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4952 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4953 AssociatedDecl == S->getAssociatedDecl())
4954 return Name;
4955 return SemaRef.Context.getSubstTemplateTemplateParm(
4956 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4957 Final: S->getFinal());
4958 }
4959
4960 assert(!Name.getAsDeducedTemplateName() &&
4961 "DeducedTemplateName should not escape partial ordering");
4962
4963 // FIXME: Preserve UsingTemplateName.
4964 if (auto *Template = Name.getAsTemplateDecl()) {
4965 assert(!QualifierLoc && "Unexpected qualifier");
4966 return TemplateName(cast_or_null<TemplateDecl>(
4967 getDerived().TransformDecl(NameLoc, Template)));
4968 }
4969
4970 if (SubstTemplateTemplateParmPackStorage *SubstPack
4971 = Name.getAsSubstTemplateTemplateParmPack()) {
4972 assert(!QualifierLoc &&
4973 "Unexpected qualified SubstTemplateTemplateParmPack");
4974 return getDerived().RebuildTemplateName(
4975 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4976 SubstPack->getIndex(), SubstPack->getFinal());
4977 }
4978
4979 // These should be getting filtered out before they reach the AST.
4980 llvm_unreachable("overloaded function decl survived to here");
4981}
4982
4983template <typename Derived>
4984TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
4985 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
4986 TemplateName Name, SourceLocation NameLoc) {
4987 TemplateName TN = getDerived().TransformTemplateName(
4988 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
4989 if (TN.isNull())
4990 return TemplateArgument();
4991 return TemplateArgument(TN);
4992}
4993
4994template<typename Derived>
4995void TreeTransform<Derived>::InventTemplateArgumentLoc(
4996 const TemplateArgument &Arg,
4997 TemplateArgumentLoc &Output) {
4998 Output = getSema().getTrivialTemplateArgumentLoc(
4999 Arg, QualType(), getDerived().getBaseLocation());
5000}
5001
5002template <typename Derived>
5003bool TreeTransform<Derived>::TransformTemplateArgument(
5004 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5005 bool Uneval) {
5006 const TemplateArgument &Arg = Input.getArgument();
5007 switch (Arg.getKind()) {
5008 case TemplateArgument::Null:
5009 case TemplateArgument::Pack:
5010 llvm_unreachable("Unexpected TemplateArgument");
5011
5012 case TemplateArgument::Integral:
5013 case TemplateArgument::NullPtr:
5014 case TemplateArgument::Declaration:
5015 case TemplateArgument::StructuralValue: {
5016 // Transform a resolved template argument straight to a resolved template
5017 // argument. We get here when substituting into an already-substituted
5018 // template type argument during concept satisfaction checking.
5019 QualType T = Arg.getNonTypeTemplateArgumentType();
5020 QualType NewT = getDerived().TransformType(T);
5021 if (NewT.isNull())
5022 return true;
5023
5024 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5025 ? Arg.getAsDecl()
5026 : nullptr;
5027 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5028 getDerived().getBaseLocation(), D))
5029 : nullptr;
5030 if (D && !NewD)
5031 return true;
5032
5033 if (NewT == T && D == NewD)
5034 Output = Input;
5035 else if (Arg.getKind() == TemplateArgument::Integral)
5036 Output = TemplateArgumentLoc(
5037 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5038 TemplateArgumentLocInfo());
5039 else if (Arg.getKind() == TemplateArgument::NullPtr)
5040 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5041 TemplateArgumentLocInfo());
5042 else if (Arg.getKind() == TemplateArgument::Declaration)
5043 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5044 TemplateArgumentLocInfo());
5045 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5046 Output = TemplateArgumentLoc(
5047 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5048 TemplateArgumentLocInfo());
5049 else
5050 llvm_unreachable("unexpected template argument kind");
5051
5052 return false;
5053 }
5054
5055 case TemplateArgument::Type: {
5056 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5057 if (!TSI)
5058 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5059
5060 TSI = getDerived().TransformType(TSI);
5061 if (!TSI)
5062 return true;
5063
5064 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5065 return false;
5066 }
5067
5068 case TemplateArgument::Template: {
5069 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5070
5071 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5072 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5073 Input.getTemplateNameLoc());
5074 if (Out.isNull())
5075 return true;
5076 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5077 QualifierLoc, Input.getTemplateNameLoc());
5078 return false;
5079 }
5080
5081 case TemplateArgument::TemplateExpansion:
5082 llvm_unreachable("Caller should expand pack expansions");
5083
5084 case TemplateArgument::Expression: {
5085 // Template argument expressions are constant expressions.
5086 EnterExpressionEvaluationContext Unevaluated(
5087 getSema(),
5088 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5089 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5090 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5091 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5092
5093 Expr *InputExpr = Input.getSourceExpression();
5094 if (!InputExpr)
5095 InputExpr = Input.getArgument().getAsExpr();
5096
5097 ExprResult E = getDerived().TransformExpr(InputExpr);
5098 E = SemaRef.ActOnConstantExpression(Res: E);
5099 if (E.isInvalid())
5100 return true;
5101 Output = TemplateArgumentLoc(
5102 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5103 return false;
5104 }
5105 }
5106
5107 // Work around bogus GCC warning
5108 return true;
5109}
5110
5111/// Iterator adaptor that invents template argument location information
5112/// for each of the template arguments in its underlying iterator.
5113template<typename Derived, typename InputIterator>
5114class TemplateArgumentLocInventIterator {
5115 TreeTransform<Derived> &Self;
5116 InputIterator Iter;
5117
5118public:
5119 typedef TemplateArgumentLoc value_type;
5120 typedef TemplateArgumentLoc reference;
5121 typedef typename std::iterator_traits<InputIterator>::difference_type
5122 difference_type;
5123 typedef std::input_iterator_tag iterator_category;
5124
5125 class pointer {
5126 TemplateArgumentLoc Arg;
5127
5128 public:
5129 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5130
5131 const TemplateArgumentLoc *operator->() const { return &Arg; }
5132 };
5133
5134 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5135 InputIterator Iter)
5136 : Self(Self), Iter(Iter) { }
5137
5138 TemplateArgumentLocInventIterator &operator++() {
5139 ++Iter;
5140 return *this;
5141 }
5142
5143 TemplateArgumentLocInventIterator operator++(int) {
5144 TemplateArgumentLocInventIterator Old(*this);
5145 ++(*this);
5146 return Old;
5147 }
5148
5149 reference operator*() const {
5150 TemplateArgumentLoc Result;
5151 Self.InventTemplateArgumentLoc(*Iter, Result);
5152 return Result;
5153 }
5154
5155 pointer operator->() const { return pointer(**this); }
5156
5157 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5158 const TemplateArgumentLocInventIterator &Y) {
5159 return X.Iter == Y.Iter;
5160 }
5161
5162 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5163 const TemplateArgumentLocInventIterator &Y) {
5164 return X.Iter != Y.Iter;
5165 }
5166};
5167
5168template<typename Derived>
5169template<typename InputIterator>
5170bool TreeTransform<Derived>::TransformTemplateArguments(
5171 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5172 bool Uneval) {
5173 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5174 TemplateArgumentLoc Out;
5175 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5176 // Unpack argument packs, which we translate them into separate
5177 // arguments.
5178 // FIXME: We could do much better if we could guarantee that the
5179 // TemplateArgumentLocInfo for the pack expansion would be usable for
5180 // all of the template arguments in the argument pack.
5181 typedef TemplateArgumentLocInventIterator<Derived,
5182 TemplateArgument::pack_iterator>
5183 PackLocIterator;
5184
5185 TemplateArgumentListInfo *PackOutput = &Outputs;
5186 TemplateArgumentListInfo New;
5187
5188 if (TransformTemplateArguments(
5189 PackLocIterator(*this, In.getArgument().pack_begin()),
5190 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5191 Uneval))
5192 return true;
5193
5194 continue;
5195 }
5196
5197 if (In.getArgument().isPackExpansion()) {
5198 UnexpandedInfo Info;
5199 TemplateArgumentLoc Prepared;
5200 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5201 return true;
5202 if (!Info.Expand) {
5203 Outputs.addArgument(Loc: Prepared);
5204 continue;
5205 }
5206
5207 // The transform has determined that we should perform an elementwise
5208 // expansion of the pattern. Do so.
5209 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5210 if (Info.ExpandUnderForgetSubstitions)
5211 ForgetSubst.emplace(getDerived());
5212 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5213 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5214
5215 TemplateArgumentLoc Out;
5216 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5217 return true;
5218
5219 if (Out.getArgument().containsUnexpandedParameterPack()) {
5220 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5221 Info.OrigNumExpansions);
5222 if (Out.getArgument().isNull())
5223 return true;
5224 }
5225
5226 Outputs.addArgument(Loc: Out);
5227 }
5228
5229 // If we're supposed to retain a pack expansion, do so by temporarily
5230 // forgetting the partially-substituted parameter pack.
5231 if (Info.RetainExpansion) {
5232 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5233
5234 TemplateArgumentLoc Out;
5235 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5236 return true;
5237
5238 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5239 Info.OrigNumExpansions);
5240 if (Out.getArgument().isNull())
5241 return true;
5242
5243 Outputs.addArgument(Loc: Out);
5244 }
5245
5246 continue;
5247 }
5248
5249 // The simple case:
5250 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5251 return true;
5252
5253 Outputs.addArgument(Loc: Out);
5254 }
5255
5256 return false;
5257}
5258
5259template <typename Derived>
5260template <typename InputIterator>
5261bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5262 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5263 bool Uneval) {
5264
5265 // [C++26][temp.constr.normal]
5266 // any non-dependent concept template argument
5267 // is substituted into the constraint-expression of C.
5268 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5269 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5270 };
5271
5272 for (; First != Last; ++First) {
5273 TemplateArgumentLoc Out;
5274 TemplateArgumentLoc In = *First;
5275
5276 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5277 typedef TemplateArgumentLocInventIterator<Derived,
5278 TemplateArgument::pack_iterator>
5279 PackLocIterator;
5280 if (TransformConceptTemplateArguments(
5281 PackLocIterator(*this, In.getArgument().pack_begin()),
5282 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5283 Uneval))
5284 return true;
5285 continue;
5286 }
5287
5288 if (!isNonDependentConceptArgument(In.getArgument())) {
5289 Outputs.addArgument(Loc: In);
5290 continue;
5291 }
5292
5293 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5294 return true;
5295
5296 Outputs.addArgument(Loc: Out);
5297 }
5298
5299 return false;
5300}
5301
5302// FIXME: Find ways to reduce code duplication for pack expansions.
5303template <typename Derived>
5304bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5305 bool Uneval,
5306 TemplateArgumentLoc &Out,
5307 UnexpandedInfo &Info) {
5308 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5309 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5310 TemplateArgumentLoc &Pattern) {
5311 assert(Arg.getArgument().isPackExpansion());
5312 // We have a pack expansion, for which we will be substituting into the
5313 // pattern.
5314 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5315 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5316 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5317 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5318 if (IsLateExpansionAttempt) {
5319 // Request expansion only when there is an opportunity to expand a pack
5320 // that required a substituion first.
5321 bool SawPackTypes =
5322 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5323 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5324 });
5325 if (!SawPackTypes) {
5326 Info.Expand = false;
5327 return false;
5328 }
5329 }
5330 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5331
5332 // Determine whether the set of unexpanded parameter packs can and
5333 // should be expanded.
5334 Info.Expand = true;
5335 Info.RetainExpansion = false;
5336 Info.NumExpansions = Info.OrigNumExpansions;
5337 return getDerived().TryExpandParameterPacks(
5338 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5339 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5340 Info.RetainExpansion, Info.NumExpansions);
5341 };
5342
5343 TemplateArgumentLoc Pattern;
5344 if (ComputeInfo(In, false, Info, Pattern))
5345 return true;
5346
5347 if (Info.Expand) {
5348 Out = Pattern;
5349 return false;
5350 }
5351
5352 // The transform has determined that we should perform a simple
5353 // transformation on the pack expansion, producing another pack
5354 // expansion.
5355 TemplateArgumentLoc OutPattern;
5356 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5357 std::in_place, getSema(), std::nullopt);
5358 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5359 return true;
5360
5361 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5362 Info.NumExpansions);
5363 if (Out.getArgument().isNull())
5364 return true;
5365 SubstIndex.reset();
5366
5367 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5368 return false;
5369
5370 // Some packs will learn their length after substitution, e.g.
5371 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5372 // value of `T`.
5373 //
5374 // We only expand after we know sizes of all packs, check if this is the case
5375 // or not. However, we avoid a full template substitution and only do
5376 // expanstions after this point.
5377
5378 // E.g. when substituting template arguments of tuple with {T -> int} in the
5379 // following example:
5380 // template <class T>
5381 // struct TupleWithInt {
5382 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5383 // };
5384 // TupleWithInt<int>::type y;
5385 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5386 // length and run `ComputeInfo()` to provide the necessary information to our
5387 // caller.
5388 //
5389 // Note that we may still have situations where builtin is not going to be
5390 // expanded. For example:
5391 // template <class T>
5392 // struct Foo {
5393 // template <class U> using tuple_with_t =
5394 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5395 // tuple_with_t<short>;
5396 // }
5397 // Because the substitution into `type` happens in dependent context, `type`
5398 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5399 // and the caller will not be able to expand it.
5400 ForgetSubstitutionRAII ForgetSubst(getDerived());
5401 if (ComputeInfo(Out, true, Info, OutPattern))
5402 return true;
5403 if (!Info.Expand)
5404 return false;
5405 Out = OutPattern;
5406 Info.ExpandUnderForgetSubstitions = true;
5407 return false;
5408}
5409
5410//===----------------------------------------------------------------------===//
5411// Type transformation
5412//===----------------------------------------------------------------------===//
5413
5414template<typename Derived>
5415QualType TreeTransform<Derived>::TransformType(QualType T) {
5416 if (getDerived().AlreadyTransformed(T))
5417 return T;
5418
5419 // Temporary workaround. All of these transformations should
5420 // eventually turn into transformations on TypeLocs.
5421 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5422 T, getDerived().getBaseLocation());
5423
5424 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5425
5426 if (!NewTSI)
5427 return QualType();
5428
5429 return NewTSI->getType();
5430}
5431
5432template <typename Derived>
5433TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5434 // Refine the base location to the type's location.
5435 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5436 getDerived().getBaseEntity());
5437 if (getDerived().AlreadyTransformed(TSI->getType()))
5438 return TSI;
5439
5440 TypeLocBuilder TLB;
5441
5442 TypeLoc TL = TSI->getTypeLoc();
5443 TLB.reserve(Requested: TL.getFullDataSize());
5444
5445 QualType Result = getDerived().TransformType(TLB, TL);
5446 if (Result.isNull())
5447 return nullptr;
5448
5449 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5450}
5451
5452template<typename Derived>
5453QualType
5454TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5455 switch (T.getTypeLocClass()) {
5456#define ABSTRACT_TYPELOC(CLASS, PARENT)
5457#define TYPELOC(CLASS, PARENT) \
5458 case TypeLoc::CLASS: \
5459 return getDerived().Transform##CLASS##Type(TLB, \
5460 T.castAs<CLASS##TypeLoc>());
5461#include "clang/AST/TypeLocNodes.def"
5462 }
5463
5464 llvm_unreachable("unhandled type loc!");
5465}
5466
5467template<typename Derived>
5468QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5469 if (!isa<DependentNameType>(Val: T))
5470 return TransformType(T);
5471
5472 if (getDerived().AlreadyTransformed(T))
5473 return T;
5474 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5475 T, getDerived().getBaseLocation());
5476 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5477 return NewTSI ? NewTSI->getType() : QualType();
5478}
5479
5480template <typename Derived>
5481TypeSourceInfo *
5482TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5483 if (!isa<DependentNameType>(Val: TSI->getType()))
5484 return TransformType(TSI);
5485
5486 // Refine the base location to the type's location.
5487 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5488 getDerived().getBaseEntity());
5489 if (getDerived().AlreadyTransformed(TSI->getType()))
5490 return TSI;
5491
5492 TypeLocBuilder TLB;
5493
5494 TypeLoc TL = TSI->getTypeLoc();
5495 TLB.reserve(Requested: TL.getFullDataSize());
5496
5497 auto QTL = TL.getAs<QualifiedTypeLoc>();
5498 if (QTL)
5499 TL = QTL.getUnqualifiedLoc();
5500
5501 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5502
5503 QualType Result = getDerived().TransformDependentNameType(
5504 TLB, DNTL, /*DeducedTSTContext*/true);
5505 if (Result.isNull())
5506 return nullptr;
5507
5508 if (QTL) {
5509 Result = getDerived().RebuildQualifiedType(Result, QTL);
5510 if (Result.isNull())
5511 return nullptr;
5512 TLB.TypeWasModifiedSafely(T: Result);
5513 }
5514
5515 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5516}
5517
5518template<typename Derived>
5519QualType
5520TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5521 QualifiedTypeLoc T) {
5522 QualType Result;
5523 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5524 auto SuppressObjCLifetime =
5525 T.getType().getLocalQualifiers().hasObjCLifetime();
5526 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5527 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5528 SuppressObjCLifetime);
5529 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5530 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5531 TLB, STTP, SuppressObjCLifetime);
5532 } else {
5533 Result = getDerived().TransformType(TLB, UnqualTL);
5534 }
5535
5536 if (Result.isNull())
5537 return QualType();
5538
5539 Result = getDerived().RebuildQualifiedType(Result, T);
5540
5541 if (Result.isNull())
5542 return QualType();
5543
5544 // RebuildQualifiedType might have updated the type, but not in a way
5545 // that invalidates the TypeLoc. (There's no location information for
5546 // qualifiers.)
5547 TLB.TypeWasModifiedSafely(T: Result);
5548
5549 return Result;
5550}
5551
5552template <typename Derived>
5553QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5554 QualifiedTypeLoc TL) {
5555
5556 SourceLocation Loc = TL.getBeginLoc();
5557 Qualifiers Quals = TL.getType().getLocalQualifiers();
5558
5559 if ((T.getAddressSpace() != LangAS::Default &&
5560 Quals.getAddressSpace() != LangAS::Default) &&
5561 T.getAddressSpace() != Quals.getAddressSpace()) {
5562 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5563 << TL.getType() << T;
5564 return QualType();
5565 }
5566
5567 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5568 if (LocalPointerAuth.isPresent()) {
5569 if (T.getPointerAuth().isPresent()) {
5570 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5571 return QualType();
5572 }
5573 if (!T->isDependentType()) {
5574 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5575 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5576 return QualType();
5577 }
5578 }
5579 }
5580 // C++ [dcl.fct]p7:
5581 // [When] adding cv-qualifications on top of the function type [...] the
5582 // cv-qualifiers are ignored.
5583 if (T->isFunctionType()) {
5584 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5585 AddressSpace: Quals.getAddressSpace());
5586 return T;
5587 }
5588
5589 // C++ [dcl.ref]p1:
5590 // when the cv-qualifiers are introduced through the use of a typedef-name
5591 // or decltype-specifier [...] the cv-qualifiers are ignored.
5592 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5593 // applied to a reference type.
5594 if (T->isReferenceType()) {
5595 // The only qualifier that applies to a reference type is restrict.
5596 if (!Quals.hasRestrict())
5597 return T;
5598 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5599 }
5600
5601 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5602 // resulting type.
5603 if (Quals.hasObjCLifetime()) {
5604 if (!T->isObjCLifetimeType() && !T->isDependentType())
5605 Quals.removeObjCLifetime();
5606 else if (T.getObjCLifetime()) {
5607 // Objective-C ARC:
5608 // A lifetime qualifier applied to a substituted template parameter
5609 // overrides the lifetime qualifier from the template argument.
5610 const AutoType *AutoTy;
5611 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5612 // 'auto' types behave the same way as template parameters.
5613 QualType Deduced = AutoTy->getDeducedType();
5614 Qualifiers Qs = Deduced.getQualifiers();
5615 Qs.removeObjCLifetime();
5616 Deduced =
5617 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5618 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5619 IsDependent: AutoTy->isDependentType(),
5620 /*isPack=*/IsPack: false,
5621 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5622 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5623 } else {
5624 // Otherwise, complain about the addition of a qualifier to an
5625 // already-qualified type.
5626 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5627 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5628 Quals.removeObjCLifetime();
5629 }
5630 }
5631 }
5632
5633 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5634}
5635
5636template <typename Derived>
5637QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5638 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5639 NamedDecl *FirstQualifierInScope) {
5640 assert(!getDerived().AlreadyTransformed(TL.getType()));
5641
5642 switch (TL.getTypeLocClass()) {
5643 case TypeLoc::TemplateSpecialization:
5644 return getDerived().TransformTemplateSpecializationType(
5645 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5646 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5647 case TypeLoc::DependentName:
5648 return getDerived().TransformDependentNameType(
5649 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5650 ObjectType, FirstQualifierInScope);
5651 default:
5652 // Any dependent canonical type can appear here, through type alias
5653 // templates.
5654 return getDerived().TransformType(TLB, TL);
5655 }
5656}
5657
5658template <class TyLoc> static inline
5659QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5660 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5661 NewT.setNameLoc(T.getNameLoc());
5662 return T.getType();
5663}
5664
5665template<typename Derived>
5666QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5667 BuiltinTypeLoc T) {
5668 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5669 NewT.setBuiltinLoc(T.getBuiltinLoc());
5670 if (T.needsExtraLocalData())
5671 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5672 return T.getType();
5673}
5674
5675template<typename Derived>
5676QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5677 ComplexTypeLoc T) {
5678 // FIXME: recurse?
5679 return TransformTypeSpecType(TLB, T);
5680}
5681
5682template <typename Derived>
5683QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5684 AdjustedTypeLoc TL) {
5685 // Adjustments applied during transformation are handled elsewhere.
5686 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5687}
5688
5689template<typename Derived>
5690QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5691 DecayedTypeLoc TL) {
5692 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5693 if (OriginalType.isNull())
5694 return QualType();
5695
5696 QualType Result = TL.getType();
5697 if (getDerived().AlwaysRebuild() ||
5698 OriginalType != TL.getOriginalLoc().getType())
5699 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5700 TLB.push<DecayedTypeLoc>(T: Result);
5701 // Nothing to set for DecayedTypeLoc.
5702 return Result;
5703}
5704
5705template <typename Derived>
5706QualType
5707TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5708 ArrayParameterTypeLoc TL) {
5709 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5710 if (OriginalType.isNull())
5711 return QualType();
5712
5713 QualType Result = TL.getType();
5714 if (getDerived().AlwaysRebuild() ||
5715 OriginalType != TL.getElementLoc().getType())
5716 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5717 TLB.push<ArrayParameterTypeLoc>(T: Result);
5718 // Nothing to set for ArrayParameterTypeLoc.
5719 return Result;
5720}
5721
5722template<typename Derived>
5723QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5724 PointerTypeLoc TL) {
5725 QualType PointeeType
5726 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5727 if (PointeeType.isNull())
5728 return QualType();
5729
5730 QualType Result = TL.getType();
5731 if (PointeeType->getAs<ObjCObjectType>()) {
5732 // A dependent pointer type 'T *' has is being transformed such
5733 // that an Objective-C class type is being replaced for 'T'. The
5734 // resulting pointer type is an ObjCObjectPointerType, not a
5735 // PointerType.
5736 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5737
5738 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5739 NewT.setStarLoc(TL.getStarLoc());
5740 return Result;
5741 }
5742
5743 if (getDerived().AlwaysRebuild() ||
5744 PointeeType != TL.getPointeeLoc().getType()) {
5745 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5746 if (Result.isNull())
5747 return QualType();
5748 }
5749
5750 // Objective-C ARC can add lifetime qualifiers to the type that we're
5751 // pointing to.
5752 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5753
5754 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5755 NewT.setSigilLoc(TL.getSigilLoc());
5756 return Result;
5757}
5758
5759template<typename Derived>
5760QualType
5761TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5762 BlockPointerTypeLoc TL) {
5763 QualType PointeeType
5764 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5765 if (PointeeType.isNull())
5766 return QualType();
5767
5768 QualType Result = TL.getType();
5769 if (getDerived().AlwaysRebuild() ||
5770 PointeeType != TL.getPointeeLoc().getType()) {
5771 Result = getDerived().RebuildBlockPointerType(PointeeType,
5772 TL.getSigilLoc());
5773 if (Result.isNull())
5774 return QualType();
5775 }
5776
5777 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5778 NewT.setSigilLoc(TL.getSigilLoc());
5779 return Result;
5780}
5781
5782/// Transforms a reference type. Note that somewhat paradoxically we
5783/// don't care whether the type itself is an l-value type or an r-value
5784/// type; we only care if the type was *written* as an l-value type
5785/// or an r-value type.
5786template<typename Derived>
5787QualType
5788TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5789 ReferenceTypeLoc TL) {
5790 const ReferenceType *T = TL.getTypePtr();
5791
5792 // Note that this works with the pointee-as-written.
5793 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5794 if (PointeeType.isNull())
5795 return QualType();
5796
5797 QualType Result = TL.getType();
5798 if (getDerived().AlwaysRebuild() ||
5799 PointeeType != T->getPointeeTypeAsWritten()) {
5800 Result = getDerived().RebuildReferenceType(PointeeType,
5801 T->isSpelledAsLValue(),
5802 TL.getSigilLoc());
5803 if (Result.isNull())
5804 return QualType();
5805 }
5806
5807 // Objective-C ARC can add lifetime qualifiers to the type that we're
5808 // referring to.
5809 TLB.TypeWasModifiedSafely(
5810 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5811
5812 // r-value references can be rebuilt as l-value references.
5813 ReferenceTypeLoc NewTL;
5814 if (isa<LValueReferenceType>(Val: Result))
5815 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5816 else
5817 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5818 NewTL.setSigilLoc(TL.getSigilLoc());
5819
5820 return Result;
5821}
5822
5823template<typename Derived>
5824QualType
5825TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5826 LValueReferenceTypeLoc TL) {
5827 return TransformReferenceType(TLB, TL);
5828}
5829
5830template<typename Derived>
5831QualType
5832TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5833 RValueReferenceTypeLoc TL) {
5834 return TransformReferenceType(TLB, TL);
5835}
5836
5837template<typename Derived>
5838QualType
5839TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5840 MemberPointerTypeLoc TL) {
5841 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5842 if (PointeeType.isNull())
5843 return QualType();
5844
5845 const MemberPointerType *T = TL.getTypePtr();
5846
5847 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5848 NestedNameSpecifierLoc NewQualifierLoc =
5849 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5850 if (!NewQualifierLoc)
5851 return QualType();
5852
5853 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5854 if (OldCls) {
5855 NewCls = cast_or_null<CXXRecordDecl>(
5856 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5857 if (!NewCls)
5858 return QualType();
5859 }
5860
5861 QualType Result = TL.getType();
5862 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5863 NewQualifierLoc.getNestedNameSpecifier() !=
5864 OldQualifierLoc.getNestedNameSpecifier() ||
5865 NewCls != OldCls) {
5866 CXXScopeSpec SS;
5867 SS.Adopt(Other: NewQualifierLoc);
5868 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5869 TL.getStarLoc());
5870 if (Result.isNull())
5871 return QualType();
5872 }
5873
5874 // If we had to adjust the pointee type when building a member pointer, make
5875 // sure to push TypeLoc info for it.
5876 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5877 if (MPT && PointeeType != MPT->getPointeeType()) {
5878 assert(isa<AdjustedType>(MPT->getPointeeType()));
5879 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5880 }
5881
5882 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5883 NewTL.setSigilLoc(TL.getSigilLoc());
5884 NewTL.setQualifierLoc(NewQualifierLoc);
5885
5886 return Result;
5887}
5888
5889template<typename Derived>
5890QualType
5891TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5892 ConstantArrayTypeLoc TL) {
5893 const ConstantArrayType *T = TL.getTypePtr();
5894 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5895 if (ElementType.isNull())
5896 return QualType();
5897
5898 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5899 Expr *OldSize = TL.getSizeExpr();
5900 if (!OldSize)
5901 OldSize = const_cast<Expr*>(T->getSizeExpr());
5902 Expr *NewSize = nullptr;
5903 if (OldSize) {
5904 EnterExpressionEvaluationContext Unevaluated(
5905 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5906 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5907 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5908 }
5909
5910 QualType Result = TL.getType();
5911 if (getDerived().AlwaysRebuild() ||
5912 ElementType != T->getElementType() ||
5913 (T->getSizeExpr() && NewSize != OldSize)) {
5914 Result = getDerived().RebuildConstantArrayType(ElementType,
5915 T->getSizeModifier(),
5916 T->getSize(), NewSize,
5917 T->getIndexTypeCVRQualifiers(),
5918 TL.getBracketsRange());
5919 if (Result.isNull())
5920 return QualType();
5921 }
5922
5923 // We might have either a ConstantArrayType or a VariableArrayType now:
5924 // a ConstantArrayType is allowed to have an element type which is a
5925 // VariableArrayType if the type is dependent. Fortunately, all array
5926 // types have the same location layout.
5927 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5928 NewTL.setLBracketLoc(TL.getLBracketLoc());
5929 NewTL.setRBracketLoc(TL.getRBracketLoc());
5930 NewTL.setSizeExpr(NewSize);
5931
5932 return Result;
5933}
5934
5935template<typename Derived>
5936QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5937 TypeLocBuilder &TLB,
5938 IncompleteArrayTypeLoc TL) {
5939 const IncompleteArrayType *T = TL.getTypePtr();
5940 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5941 if (ElementType.isNull())
5942 return QualType();
5943
5944 QualType Result = TL.getType();
5945 if (getDerived().AlwaysRebuild() ||
5946 ElementType != T->getElementType()) {
5947 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5948 T->getSizeModifier(),
5949 T->getIndexTypeCVRQualifiers(),
5950 TL.getBracketsRange());
5951 if (Result.isNull())
5952 return QualType();
5953 }
5954
5955 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5956 NewTL.setLBracketLoc(TL.getLBracketLoc());
5957 NewTL.setRBracketLoc(TL.getRBracketLoc());
5958 NewTL.setSizeExpr(nullptr);
5959
5960 return Result;
5961}
5962
5963template<typename Derived>
5964QualType
5965TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5966 VariableArrayTypeLoc TL) {
5967 const VariableArrayType *T = TL.getTypePtr();
5968 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5969 if (ElementType.isNull())
5970 return QualType();
5971
5972 ExprResult SizeResult;
5973 {
5974 EnterExpressionEvaluationContext Context(
5975 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5976 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5977 }
5978 if (SizeResult.isInvalid())
5979 return QualType();
5980 SizeResult =
5981 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5982 if (SizeResult.isInvalid())
5983 return QualType();
5984
5985 Expr *Size = SizeResult.get();
5986
5987 QualType Result = TL.getType();
5988 if (getDerived().AlwaysRebuild() ||
5989 ElementType != T->getElementType() ||
5990 Size != T->getSizeExpr()) {
5991 Result = getDerived().RebuildVariableArrayType(ElementType,
5992 T->getSizeModifier(),
5993 Size,
5994 T->getIndexTypeCVRQualifiers(),
5995 TL.getBracketsRange());
5996 if (Result.isNull())
5997 return QualType();
5998 }
5999
6000 // We might have constant size array now, but fortunately it has the same
6001 // location layout.
6002 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6003 NewTL.setLBracketLoc(TL.getLBracketLoc());
6004 NewTL.setRBracketLoc(TL.getRBracketLoc());
6005 NewTL.setSizeExpr(Size);
6006
6007 return Result;
6008}
6009
6010template<typename Derived>
6011QualType
6012TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6013 DependentSizedArrayTypeLoc TL) {
6014 const DependentSizedArrayType *T = TL.getTypePtr();
6015 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6016 if (ElementType.isNull())
6017 return QualType();
6018
6019 // Array bounds are constant expressions.
6020 EnterExpressionEvaluationContext Unevaluated(
6021 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6022
6023 // If we have a VLA then it won't be a constant.
6024 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6025
6026 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6027 Expr *origSize = TL.getSizeExpr();
6028 if (!origSize) origSize = T->getSizeExpr();
6029
6030 ExprResult sizeResult
6031 = getDerived().TransformExpr(origSize);
6032 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6033 if (sizeResult.isInvalid())
6034 return QualType();
6035
6036 Expr *size = sizeResult.get();
6037
6038 QualType Result = TL.getType();
6039 if (getDerived().AlwaysRebuild() ||
6040 ElementType != T->getElementType() ||
6041 size != origSize) {
6042 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6043 T->getSizeModifier(),
6044 size,
6045 T->getIndexTypeCVRQualifiers(),
6046 TL.getBracketsRange());
6047 if (Result.isNull())
6048 return QualType();
6049 }
6050
6051 // We might have any sort of array type now, but fortunately they
6052 // all have the same location layout.
6053 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6054 NewTL.setLBracketLoc(TL.getLBracketLoc());
6055 NewTL.setRBracketLoc(TL.getRBracketLoc());
6056 NewTL.setSizeExpr(size);
6057
6058 return Result;
6059}
6060
6061template <typename Derived>
6062QualType TreeTransform<Derived>::TransformDependentVectorType(
6063 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6064 const DependentVectorType *T = TL.getTypePtr();
6065 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6066 if (ElementType.isNull())
6067 return QualType();
6068
6069 EnterExpressionEvaluationContext Unevaluated(
6070 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6071
6072 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6073 Size = SemaRef.ActOnConstantExpression(Res: Size);
6074 if (Size.isInvalid())
6075 return QualType();
6076
6077 QualType Result = TL.getType();
6078 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6079 Size.get() != T->getSizeExpr()) {
6080 Result = getDerived().RebuildDependentVectorType(
6081 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6082 if (Result.isNull())
6083 return QualType();
6084 }
6085
6086 // Result might be dependent or not.
6087 if (isa<DependentVectorType>(Val: Result)) {
6088 DependentVectorTypeLoc NewTL =
6089 TLB.push<DependentVectorTypeLoc>(T: Result);
6090 NewTL.setNameLoc(TL.getNameLoc());
6091 } else {
6092 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6093 NewTL.setNameLoc(TL.getNameLoc());
6094 }
6095
6096 return Result;
6097}
6098
6099template<typename Derived>
6100QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6101 TypeLocBuilder &TLB,
6102 DependentSizedExtVectorTypeLoc TL) {
6103 const DependentSizedExtVectorType *T = TL.getTypePtr();
6104
6105 // FIXME: ext vector locs should be nested
6106 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6107 if (ElementType.isNull())
6108 return QualType();
6109
6110 // Vector sizes are constant expressions.
6111 EnterExpressionEvaluationContext Unevaluated(
6112 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6113
6114 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6115 Size = SemaRef.ActOnConstantExpression(Res: Size);
6116 if (Size.isInvalid())
6117 return QualType();
6118
6119 QualType Result = TL.getType();
6120 if (getDerived().AlwaysRebuild() ||
6121 ElementType != T->getElementType() ||
6122 Size.get() != T->getSizeExpr()) {
6123 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6124 Size.get(),
6125 T->getAttributeLoc());
6126 if (Result.isNull())
6127 return QualType();
6128 }
6129
6130 // Result might be dependent or not.
6131 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6132 DependentSizedExtVectorTypeLoc NewTL
6133 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6134 NewTL.setNameLoc(TL.getNameLoc());
6135 } else {
6136 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6137 NewTL.setNameLoc(TL.getNameLoc());
6138 }
6139
6140 return Result;
6141}
6142
6143template <typename Derived>
6144QualType
6145TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6146 ConstantMatrixTypeLoc TL) {
6147 const ConstantMatrixType *T = TL.getTypePtr();
6148 QualType ElementType = getDerived().TransformType(T->getElementType());
6149 if (ElementType.isNull())
6150 return QualType();
6151
6152 QualType Result = TL.getType();
6153 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6154 Result = getDerived().RebuildConstantMatrixType(
6155 ElementType, T->getNumRows(), T->getNumColumns());
6156 if (Result.isNull())
6157 return QualType();
6158 }
6159
6160 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6161 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6162 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6163 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6164 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6165
6166 return Result;
6167}
6168
6169template <typename Derived>
6170QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6171 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6172 const DependentSizedMatrixType *T = TL.getTypePtr();
6173
6174 QualType ElementType = getDerived().TransformType(T->getElementType());
6175 if (ElementType.isNull()) {
6176 return QualType();
6177 }
6178
6179 // Matrix dimensions are constant expressions.
6180 EnterExpressionEvaluationContext Unevaluated(
6181 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6182
6183 Expr *origRows = TL.getAttrRowOperand();
6184 if (!origRows)
6185 origRows = T->getRowExpr();
6186 Expr *origColumns = TL.getAttrColumnOperand();
6187 if (!origColumns)
6188 origColumns = T->getColumnExpr();
6189
6190 ExprResult rowResult = getDerived().TransformExpr(origRows);
6191 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6192 if (rowResult.isInvalid())
6193 return QualType();
6194
6195 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6196 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6197 if (columnResult.isInvalid())
6198 return QualType();
6199
6200 Expr *rows = rowResult.get();
6201 Expr *columns = columnResult.get();
6202
6203 QualType Result = TL.getType();
6204 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6205 rows != origRows || columns != origColumns) {
6206 Result = getDerived().RebuildDependentSizedMatrixType(
6207 ElementType, rows, columns, T->getAttributeLoc());
6208
6209 if (Result.isNull())
6210 return QualType();
6211 }
6212
6213 // We might have any sort of matrix type now, but fortunately they
6214 // all have the same location layout.
6215 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6216 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6217 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6218 NewTL.setAttrRowOperand(rows);
6219 NewTL.setAttrColumnOperand(columns);
6220 return Result;
6221}
6222
6223template <typename Derived>
6224QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6225 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6226 const DependentAddressSpaceType *T = TL.getTypePtr();
6227
6228 QualType pointeeType =
6229 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6230
6231 if (pointeeType.isNull())
6232 return QualType();
6233
6234 // Address spaces are constant expressions.
6235 EnterExpressionEvaluationContext Unevaluated(
6236 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6237
6238 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6239 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6240 if (AddrSpace.isInvalid())
6241 return QualType();
6242
6243 QualType Result = TL.getType();
6244 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6245 AddrSpace.get() != T->getAddrSpaceExpr()) {
6246 Result = getDerived().RebuildDependentAddressSpaceType(
6247 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6248 if (Result.isNull())
6249 return QualType();
6250 }
6251
6252 // Result might be dependent or not.
6253 if (isa<DependentAddressSpaceType>(Val: Result)) {
6254 DependentAddressSpaceTypeLoc NewTL =
6255 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6256
6257 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6258 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6259 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6260
6261 } else {
6262 TLB.TypeWasModifiedSafely(T: Result);
6263 }
6264
6265 return Result;
6266}
6267
6268template <typename Derived>
6269QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6270 VectorTypeLoc TL) {
6271 const VectorType *T = TL.getTypePtr();
6272 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6273 if (ElementType.isNull())
6274 return QualType();
6275
6276 QualType Result = TL.getType();
6277 if (getDerived().AlwaysRebuild() ||
6278 ElementType != T->getElementType()) {
6279 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6280 T->getVectorKind());
6281 if (Result.isNull())
6282 return QualType();
6283 }
6284
6285 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6286 NewTL.setNameLoc(TL.getNameLoc());
6287
6288 return Result;
6289}
6290
6291template<typename Derived>
6292QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6293 ExtVectorTypeLoc TL) {
6294 const VectorType *T = TL.getTypePtr();
6295 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6296 if (ElementType.isNull())
6297 return QualType();
6298
6299 QualType Result = TL.getType();
6300 if (getDerived().AlwaysRebuild() ||
6301 ElementType != T->getElementType()) {
6302 Result = getDerived().RebuildExtVectorType(ElementType,
6303 T->getNumElements(),
6304 /*FIXME*/ SourceLocation());
6305 if (Result.isNull())
6306 return QualType();
6307 }
6308
6309 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6310 NewTL.setNameLoc(TL.getNameLoc());
6311
6312 return Result;
6313}
6314
6315template <typename Derived>
6316ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6317 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6318 bool ExpectParameterPack) {
6319 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6320 TypeSourceInfo *NewTSI = nullptr;
6321
6322 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6323 // If we're substituting into a pack expansion type and we know the
6324 // length we want to expand to, just substitute for the pattern.
6325 TypeLoc OldTL = OldTSI->getTypeLoc();
6326 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6327
6328 TypeLocBuilder TLB;
6329 TypeLoc NewTL = OldTSI->getTypeLoc();
6330 TLB.reserve(Requested: NewTL.getFullDataSize());
6331
6332 QualType Result = getDerived().TransformType(TLB,
6333 OldExpansionTL.getPatternLoc());
6334 if (Result.isNull())
6335 return nullptr;
6336
6337 Result = RebuildPackExpansionType(Pattern: Result,
6338 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6339 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6340 NumExpansions);
6341 if (Result.isNull())
6342 return nullptr;
6343
6344 PackExpansionTypeLoc NewExpansionTL
6345 = TLB.push<PackExpansionTypeLoc>(T: Result);
6346 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6347 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6348 } else
6349 NewTSI = getDerived().TransformType(OldTSI);
6350 if (!NewTSI)
6351 return nullptr;
6352
6353 if (NewTSI == OldTSI && indexAdjustment == 0)
6354 return OldParm;
6355
6356 ParmVarDecl *newParm = ParmVarDecl::Create(
6357 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6358 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6359 TInfo: NewTSI, S: OldParm->getStorageClass(),
6360 /* DefArg */ DefArg: nullptr);
6361 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6362 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6363 getDerived().transformedLocalDecl(OldParm, {newParm});
6364 return newParm;
6365}
6366
6367template <typename Derived>
6368bool TreeTransform<Derived>::TransformFunctionTypeParams(
6369 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6370 const QualType *ParamTypes,
6371 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6372 SmallVectorImpl<QualType> &OutParamTypes,
6373 SmallVectorImpl<ParmVarDecl *> *PVars,
6374 Sema::ExtParameterInfoBuilder &PInfos,
6375 unsigned *LastParamTransformed) {
6376 int indexAdjustment = 0;
6377
6378 unsigned NumParams = Params.size();
6379 for (unsigned i = 0; i != NumParams; ++i) {
6380 if (LastParamTransformed)
6381 *LastParamTransformed = i;
6382 if (ParmVarDecl *OldParm = Params[i]) {
6383 assert(OldParm->getFunctionScopeIndex() == i);
6384
6385 UnsignedOrNone NumExpansions = std::nullopt;
6386 ParmVarDecl *NewParm = nullptr;
6387 if (OldParm->isParameterPack()) {
6388 // We have a function parameter pack that may need to be expanded.
6389 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6390
6391 // Find the parameter packs that could be expanded.
6392 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6393 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6394 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6395 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6396
6397 // Determine whether we should expand the parameter packs.
6398 bool ShouldExpand = false;
6399 bool RetainExpansion = false;
6400 UnsignedOrNone OrigNumExpansions = std::nullopt;
6401 if (Unexpanded.size() > 0) {
6402 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6403 NumExpansions = OrigNumExpansions;
6404 if (getDerived().TryExpandParameterPacks(
6405 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6406 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6407 ShouldExpand, RetainExpansion, NumExpansions)) {
6408 return true;
6409 }
6410 } else {
6411#ifndef NDEBUG
6412 const AutoType *AT =
6413 Pattern.getType().getTypePtr()->getContainedAutoType();
6414 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6415 "Could not find parameter packs or undeduced auto type!");
6416#endif
6417 }
6418
6419 if (ShouldExpand) {
6420 // Expand the function parameter pack into multiple, separate
6421 // parameters.
6422 getDerived().ExpandingFunctionParameterPack(OldParm);
6423 for (unsigned I = 0; I != *NumExpansions; ++I) {
6424 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6425 ParmVarDecl *NewParm
6426 = getDerived().TransformFunctionTypeParam(OldParm,
6427 indexAdjustment++,
6428 OrigNumExpansions,
6429 /*ExpectParameterPack=*/false);
6430 if (!NewParm)
6431 return true;
6432
6433 if (ParamInfos)
6434 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6435 OutParamTypes.push_back(Elt: NewParm->getType());
6436 if (PVars)
6437 PVars->push_back(Elt: NewParm);
6438 }
6439
6440 // If we're supposed to retain a pack expansion, do so by temporarily
6441 // forgetting the partially-substituted parameter pack.
6442 if (RetainExpansion) {
6443 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6444 ParmVarDecl *NewParm
6445 = getDerived().TransformFunctionTypeParam(OldParm,
6446 indexAdjustment++,
6447 OrigNumExpansions,
6448 /*ExpectParameterPack=*/false);
6449 if (!NewParm)
6450 return true;
6451
6452 if (ParamInfos)
6453 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6454 OutParamTypes.push_back(Elt: NewParm->getType());
6455 if (PVars)
6456 PVars->push_back(Elt: NewParm);
6457 }
6458
6459 // The next parameter should have the same adjustment as the
6460 // last thing we pushed, but we post-incremented indexAdjustment
6461 // on every push. Also, if we push nothing, the adjustment should
6462 // go down by one.
6463 indexAdjustment--;
6464
6465 // We're done with the pack expansion.
6466 continue;
6467 }
6468
6469 // We'll substitute the parameter now without expanding the pack
6470 // expansion.
6471 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6472 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6473 indexAdjustment,
6474 NumExpansions,
6475 /*ExpectParameterPack=*/true);
6476 assert(NewParm->isParameterPack() &&
6477 "Parameter pack no longer a parameter pack after "
6478 "transformation.");
6479 } else {
6480 NewParm = getDerived().TransformFunctionTypeParam(
6481 OldParm, indexAdjustment, std::nullopt,
6482 /*ExpectParameterPack=*/false);
6483 }
6484
6485 if (!NewParm)
6486 return true;
6487
6488 if (ParamInfos)
6489 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6490 OutParamTypes.push_back(Elt: NewParm->getType());
6491 if (PVars)
6492 PVars->push_back(Elt: NewParm);
6493 continue;
6494 }
6495
6496 // Deal with the possibility that we don't have a parameter
6497 // declaration for this parameter.
6498 assert(ParamTypes);
6499 QualType OldType = ParamTypes[i];
6500 bool IsPackExpansion = false;
6501 UnsignedOrNone NumExpansions = std::nullopt;
6502 QualType NewType;
6503 if (const PackExpansionType *Expansion
6504 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6505 // We have a function parameter pack that may need to be expanded.
6506 QualType Pattern = Expansion->getPattern();
6507 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6508 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6509
6510 // Determine whether we should expand the parameter packs.
6511 bool ShouldExpand = false;
6512 bool RetainExpansion = false;
6513 if (getDerived().TryExpandParameterPacks(
6514 Loc, SourceRange(), Unexpanded,
6515 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6516 RetainExpansion, NumExpansions)) {
6517 return true;
6518 }
6519
6520 if (ShouldExpand) {
6521 // Expand the function parameter pack into multiple, separate
6522 // parameters.
6523 for (unsigned I = 0; I != *NumExpansions; ++I) {
6524 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6525 QualType NewType = getDerived().TransformType(Pattern);
6526 if (NewType.isNull())
6527 return true;
6528
6529 if (NewType->containsUnexpandedParameterPack()) {
6530 NewType = getSema().getASTContext().getPackExpansionType(
6531 NewType, std::nullopt);
6532
6533 if (NewType.isNull())
6534 return true;
6535 }
6536
6537 if (ParamInfos)
6538 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6539 OutParamTypes.push_back(Elt: NewType);
6540 if (PVars)
6541 PVars->push_back(Elt: nullptr);
6542 }
6543
6544 // We're done with the pack expansion.
6545 continue;
6546 }
6547
6548 // If we're supposed to retain a pack expansion, do so by temporarily
6549 // forgetting the partially-substituted parameter pack.
6550 if (RetainExpansion) {
6551 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6552 QualType NewType = getDerived().TransformType(Pattern);
6553 if (NewType.isNull())
6554 return true;
6555
6556 if (ParamInfos)
6557 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6558 OutParamTypes.push_back(Elt: NewType);
6559 if (PVars)
6560 PVars->push_back(Elt: nullptr);
6561 }
6562
6563 // We'll substitute the parameter now without expanding the pack
6564 // expansion.
6565 OldType = Expansion->getPattern();
6566 IsPackExpansion = true;
6567 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6568 NewType = getDerived().TransformType(OldType);
6569 } else {
6570 NewType = getDerived().TransformType(OldType);
6571 }
6572
6573 if (NewType.isNull())
6574 return true;
6575
6576 if (IsPackExpansion)
6577 NewType = getSema().Context.getPackExpansionType(NewType,
6578 NumExpansions);
6579
6580 if (ParamInfos)
6581 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6582 OutParamTypes.push_back(Elt: NewType);
6583 if (PVars)
6584 PVars->push_back(Elt: nullptr);
6585 }
6586
6587#ifndef NDEBUG
6588 if (PVars) {
6589 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6590 if (ParmVarDecl *parm = (*PVars)[i])
6591 assert(parm->getFunctionScopeIndex() == i);
6592 }
6593#endif
6594
6595 return false;
6596}
6597
6598template<typename Derived>
6599QualType
6600TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6601 FunctionProtoTypeLoc TL) {
6602 SmallVector<QualType, 4> ExceptionStorage;
6603 return getDerived().TransformFunctionProtoType(
6604 TLB, TL, nullptr, Qualifiers(),
6605 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6606 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6607 ExceptionStorage, Changed);
6608 });
6609}
6610
6611template<typename Derived> template<typename Fn>
6612QualType TreeTransform<Derived>::TransformFunctionProtoType(
6613 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6614 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6615
6616 // Transform the parameters and return type.
6617 //
6618 // We are required to instantiate the params and return type in source order.
6619 // When the function has a trailing return type, we instantiate the
6620 // parameters before the return type, since the return type can then refer
6621 // to the parameters themselves (via decltype, sizeof, etc.).
6622 //
6623 SmallVector<QualType, 4> ParamTypes;
6624 SmallVector<ParmVarDecl*, 4> ParamDecls;
6625 Sema::ExtParameterInfoBuilder ExtParamInfos;
6626 const FunctionProtoType *T = TL.getTypePtr();
6627
6628 QualType ResultType;
6629
6630 if (T->hasTrailingReturn()) {
6631 if (getDerived().TransformFunctionTypeParams(
6632 TL.getBeginLoc(), TL.getParams(),
6633 TL.getTypePtr()->param_type_begin(),
6634 T->getExtParameterInfosOrNull(),
6635 ParamTypes, &ParamDecls, ExtParamInfos))
6636 return QualType();
6637
6638 {
6639 // C++11 [expr.prim.general]p3:
6640 // If a declaration declares a member function or member function
6641 // template of a class X, the expression this is a prvalue of type
6642 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6643 // and the end of the function-definition, member-declarator, or
6644 // declarator.
6645 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6646 Sema::CXXThisScopeRAII ThisScope(
6647 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6648
6649 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6650 if (ResultType.isNull())
6651 return QualType();
6652 }
6653 }
6654 else {
6655 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6656 if (ResultType.isNull())
6657 return QualType();
6658
6659 if (getDerived().TransformFunctionTypeParams(
6660 TL.getBeginLoc(), TL.getParams(),
6661 TL.getTypePtr()->param_type_begin(),
6662 T->getExtParameterInfosOrNull(),
6663 ParamTypes, &ParamDecls, ExtParamInfos))
6664 return QualType();
6665 }
6666
6667 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6668
6669 bool EPIChanged = false;
6670 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6671 return QualType();
6672
6673 // Handle extended parameter information.
6674 if (auto NewExtParamInfos =
6675 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6676 if (!EPI.ExtParameterInfos ||
6677 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6678 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6679 EPIChanged = true;
6680 }
6681 EPI.ExtParameterInfos = NewExtParamInfos;
6682 } else if (EPI.ExtParameterInfos) {
6683 EPIChanged = true;
6684 EPI.ExtParameterInfos = nullptr;
6685 }
6686
6687 // Transform any function effects with unevaluated conditions.
6688 // Hold this set in a local for the rest of this function, since EPI
6689 // may need to hold a FunctionEffectsRef pointing into it.
6690 std::optional<FunctionEffectSet> NewFX;
6691 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6692 NewFX.emplace();
6693 EnterExpressionEvaluationContext Unevaluated(
6694 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6695
6696 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6697 FunctionEffectWithCondition NewEC = PrevEC;
6698 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6699 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6700 if (NewExpr.isInvalid())
6701 return QualType();
6702 std::optional<FunctionEffectMode> Mode =
6703 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6704 if (!Mode)
6705 return QualType();
6706
6707 // The condition expression has been transformed, and re-evaluated.
6708 // It may or may not have become constant.
6709 switch (*Mode) {
6710 case FunctionEffectMode::True:
6711 NewEC.Cond = {};
6712 break;
6713 case FunctionEffectMode::False:
6714 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6715 NewEC.Cond = {};
6716 break;
6717 case FunctionEffectMode::Dependent:
6718 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6719 break;
6720 case FunctionEffectMode::None:
6721 llvm_unreachable(
6722 "FunctionEffectMode::None shouldn't be possible here");
6723 }
6724 }
6725 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6726 NewAttrLoc: TL.getBeginLoc())) {
6727 FunctionEffectSet::Conflicts Errs;
6728 NewFX->insert(NewEC, Errs);
6729 assert(Errs.empty());
6730 }
6731 }
6732 EPI.FunctionEffects = *NewFX;
6733 EPIChanged = true;
6734 }
6735
6736 QualType Result = TL.getType();
6737 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6738 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6739 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6740 if (Result.isNull())
6741 return QualType();
6742 }
6743
6744 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6745 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6746 NewTL.setLParenLoc(TL.getLParenLoc());
6747 NewTL.setRParenLoc(TL.getRParenLoc());
6748 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6749 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6750 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6751 NewTL.setParam(i, VD: ParamDecls[i]);
6752
6753 return Result;
6754}
6755
6756template<typename Derived>
6757bool TreeTransform<Derived>::TransformExceptionSpec(
6758 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6759 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6760 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6761
6762 // Instantiate a dynamic noexcept expression, if any.
6763 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6764 // Update this scrope because ContextDecl in Sema will be used in
6765 // TransformExpr.
6766 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6767 Sema::CXXThisScopeRAII ThisScope(
6768 SemaRef, Method ? Method->getParent() : nullptr,
6769 Method ? Method->getMethodQualifiers() : Qualifiers{},
6770 Method != nullptr);
6771 EnterExpressionEvaluationContext Unevaluated(
6772 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6773 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6774 if (NoexceptExpr.isInvalid())
6775 return true;
6776
6777 ExceptionSpecificationType EST = ESI.Type;
6778 NoexceptExpr =
6779 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6780 if (NoexceptExpr.isInvalid())
6781 return true;
6782
6783 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6784 Changed = true;
6785 ESI.NoexceptExpr = NoexceptExpr.get();
6786 ESI.Type = EST;
6787 }
6788
6789 if (ESI.Type != EST_Dynamic)
6790 return false;
6791
6792 // Instantiate a dynamic exception specification's type.
6793 for (QualType T : ESI.Exceptions) {
6794 if (const PackExpansionType *PackExpansion =
6795 T->getAs<PackExpansionType>()) {
6796 Changed = true;
6797
6798 // We have a pack expansion. Instantiate it.
6799 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6800 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6801 Unexpanded);
6802 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6803
6804 // Determine whether the set of unexpanded parameter packs can and
6805 // should
6806 // be expanded.
6807 bool Expand = false;
6808 bool RetainExpansion = false;
6809 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6810 // FIXME: Track the location of the ellipsis (and track source location
6811 // information for the types in the exception specification in general).
6812 if (getDerived().TryExpandParameterPacks(
6813 Loc, SourceRange(), Unexpanded,
6814 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6815 NumExpansions))
6816 return true;
6817
6818 if (!Expand) {
6819 // We can't expand this pack expansion into separate arguments yet;
6820 // just substitute into the pattern and create a new pack expansion
6821 // type.
6822 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6823 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6824 if (U.isNull())
6825 return true;
6826
6827 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6828 Exceptions.push_back(Elt: U);
6829 continue;
6830 }
6831
6832 // Substitute into the pack expansion pattern for each slice of the
6833 // pack.
6834 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6835 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6836
6837 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6838 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6839 return true;
6840
6841 Exceptions.push_back(Elt: U);
6842 }
6843 } else {
6844 QualType U = getDerived().TransformType(T);
6845 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6846 return true;
6847 if (T != U)
6848 Changed = true;
6849
6850 Exceptions.push_back(Elt: U);
6851 }
6852 }
6853
6854 ESI.Exceptions = Exceptions;
6855 if (ESI.Exceptions.empty())
6856 ESI.Type = EST_DynamicNone;
6857 return false;
6858}
6859
6860template<typename Derived>
6861QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6862 TypeLocBuilder &TLB,
6863 FunctionNoProtoTypeLoc TL) {
6864 const FunctionNoProtoType *T = TL.getTypePtr();
6865 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6866 if (ResultType.isNull())
6867 return QualType();
6868
6869 QualType Result = TL.getType();
6870 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6871 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6872
6873 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6874 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6875 NewTL.setLParenLoc(TL.getLParenLoc());
6876 NewTL.setRParenLoc(TL.getRParenLoc());
6877 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6878
6879 return Result;
6880}
6881
6882template <typename Derived>
6883QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6884 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6885
6886 const UnresolvedUsingType *T = TL.getTypePtr();
6887 bool Changed = false;
6888
6889 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6890 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6891 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6892 if (!QualifierLoc)
6893 return QualType();
6894 Changed |= QualifierLoc != OldQualifierLoc;
6895 }
6896
6897 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6898 if (!D)
6899 return QualType();
6900 Changed |= D != T->getDecl();
6901
6902 QualType Result = TL.getType();
6903 if (getDerived().AlwaysRebuild() || Changed) {
6904 Result = getDerived().RebuildUnresolvedUsingType(
6905 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
6906 D);
6907 if (Result.isNull())
6908 return QualType();
6909 }
6910
6911 if (isa<UsingType>(Val: Result))
6912 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6913 QualifierLoc, NameLoc: TL.getNameLoc());
6914 else
6915 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6916 QualifierLoc, NameLoc: TL.getNameLoc());
6917 return Result;
6918}
6919
6920template <typename Derived>
6921QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6922 UsingTypeLoc TL) {
6923 const UsingType *T = TL.getTypePtr();
6924 bool Changed = false;
6925
6926 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6927 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6928 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6929 if (!QualifierLoc)
6930 return QualType();
6931 Changed |= QualifierLoc != OldQualifierLoc;
6932 }
6933
6934 auto *D = cast_or_null<UsingShadowDecl>(
6935 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6936 if (!D)
6937 return QualType();
6938 Changed |= D != T->getDecl();
6939
6940 QualType UnderlyingType = getDerived().TransformType(T->desugar());
6941 if (UnderlyingType.isNull())
6942 return QualType();
6943 Changed |= UnderlyingType != T->desugar();
6944
6945 QualType Result = TL.getType();
6946 if (getDerived().AlwaysRebuild() || Changed) {
6947 Result = getDerived().RebuildUsingType(
6948 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
6949 UnderlyingType);
6950 if (Result.isNull())
6951 return QualType();
6952 }
6953 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
6954 NameLoc: TL.getNameLoc());
6955 return Result;
6956}
6957
6958template<typename Derived>
6959QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6960 TypedefTypeLoc TL) {
6961 const TypedefType *T = TL.getTypePtr();
6962 bool Changed = false;
6963
6964 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6965 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6966 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6967 if (!QualifierLoc)
6968 return QualType();
6969 Changed |= QualifierLoc != OldQualifierLoc;
6970 }
6971
6972 auto *Typedef = cast_or_null<TypedefNameDecl>(
6973 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6974 if (!Typedef)
6975 return QualType();
6976 Changed |= Typedef != T->getDecl();
6977
6978 // FIXME: Transform the UnderlyingType if different from decl.
6979
6980 QualType Result = TL.getType();
6981 if (getDerived().AlwaysRebuild() || Changed) {
6982 Result = getDerived().RebuildTypedefType(
6983 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
6984 if (Result.isNull())
6985 return QualType();
6986 }
6987
6988 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6989 QualifierLoc, NameLoc: TL.getNameLoc());
6990 return Result;
6991}
6992
6993template<typename Derived>
6994QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6995 TypeOfExprTypeLoc TL) {
6996 // typeof expressions are not potentially evaluated contexts
6997 EnterExpressionEvaluationContext Unevaluated(
6998 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6999 Sema::ReuseLambdaContextDecl);
7000
7001 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7002 if (E.isInvalid())
7003 return QualType();
7004
7005 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7006 if (E.isInvalid())
7007 return QualType();
7008
7009 QualType Result = TL.getType();
7010 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7011 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7012 Result =
7013 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7014 if (Result.isNull())
7015 return QualType();
7016 }
7017
7018 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7019 NewTL.setTypeofLoc(TL.getTypeofLoc());
7020 NewTL.setLParenLoc(TL.getLParenLoc());
7021 NewTL.setRParenLoc(TL.getRParenLoc());
7022
7023 return Result;
7024}
7025
7026template<typename Derived>
7027QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7028 TypeOfTypeLoc TL) {
7029 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7030 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7031 if (!New_Under_TI)
7032 return QualType();
7033
7034 QualType Result = TL.getType();
7035 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7036 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7037 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7038 if (Result.isNull())
7039 return QualType();
7040 }
7041
7042 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7043 NewTL.setTypeofLoc(TL.getTypeofLoc());
7044 NewTL.setLParenLoc(TL.getLParenLoc());
7045 NewTL.setRParenLoc(TL.getRParenLoc());
7046 NewTL.setUnmodifiedTInfo(New_Under_TI);
7047
7048 return Result;
7049}
7050
7051template<typename Derived>
7052QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7053 DecltypeTypeLoc TL) {
7054 const DecltypeType *T = TL.getTypePtr();
7055
7056 // decltype expressions are not potentially evaluated contexts
7057 EnterExpressionEvaluationContext Unevaluated(
7058 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7059 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7060
7061 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7062 if (E.isInvalid())
7063 return QualType();
7064
7065 E = getSema().ActOnDecltypeExpression(E.get());
7066 if (E.isInvalid())
7067 return QualType();
7068
7069 QualType Result = TL.getType();
7070 if (getDerived().AlwaysRebuild() ||
7071 E.get() != T->getUnderlyingExpr()) {
7072 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7073 if (Result.isNull())
7074 return QualType();
7075 }
7076 else E.get();
7077
7078 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7079 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7080 NewTL.setRParenLoc(TL.getRParenLoc());
7081 return Result;
7082}
7083
7084template <typename Derived>
7085QualType
7086TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7087 PackIndexingTypeLoc TL) {
7088 // Transform the index
7089 ExprResult IndexExpr;
7090 {
7091 EnterExpressionEvaluationContext ConstantContext(
7092 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7093
7094 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7095 if (IndexExpr.isInvalid())
7096 return QualType();
7097 }
7098 QualType Pattern = TL.getPattern();
7099
7100 const PackIndexingType *PIT = TL.getTypePtr();
7101 SmallVector<QualType, 5> SubtitutedTypes;
7102 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7103
7104 bool NotYetExpanded = Types.empty();
7105 bool FullySubstituted = true;
7106
7107 if (Types.empty() && !PIT->expandsToEmptyPack())
7108 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7109
7110 for (QualType T : Types) {
7111 if (!T->containsUnexpandedParameterPack()) {
7112 QualType Transformed = getDerived().TransformType(T);
7113 if (Transformed.isNull())
7114 return QualType();
7115 SubtitutedTypes.push_back(Elt: Transformed);
7116 continue;
7117 }
7118
7119 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7120 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7121 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7122 // Determine whether the set of unexpanded parameter packs can and should
7123 // be expanded.
7124 bool ShouldExpand = true;
7125 bool RetainExpansion = false;
7126 UnsignedOrNone NumExpansions = std::nullopt;
7127 if (getDerived().TryExpandParameterPacks(
7128 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7129 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7130 RetainExpansion, NumExpansions))
7131 return QualType();
7132 if (!ShouldExpand) {
7133 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7134 // FIXME: should we keep TypeLoc for individual expansions in
7135 // PackIndexingTypeLoc?
7136 TypeSourceInfo *TI =
7137 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7138 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7139 if (Pack.isNull())
7140 return QualType();
7141 if (NotYetExpanded) {
7142 FullySubstituted = false;
7143 QualType Out = getDerived().RebuildPackIndexingType(
7144 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7145 FullySubstituted);
7146 if (Out.isNull())
7147 return QualType();
7148
7149 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7150 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7151 return Out;
7152 }
7153 SubtitutedTypes.push_back(Elt: Pack);
7154 continue;
7155 }
7156 for (unsigned I = 0; I != *NumExpansions; ++I) {
7157 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7158 QualType Out = getDerived().TransformType(T);
7159 if (Out.isNull())
7160 return QualType();
7161 SubtitutedTypes.push_back(Elt: Out);
7162 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7163 }
7164 // If we're supposed to retain a pack expansion, do so by temporarily
7165 // forgetting the partially-substituted parameter pack.
7166 if (RetainExpansion) {
7167 FullySubstituted = false;
7168 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7169 QualType Out = getDerived().TransformType(T);
7170 if (Out.isNull())
7171 return QualType();
7172 SubtitutedTypes.push_back(Elt: Out);
7173 }
7174 }
7175
7176 // A pack indexing type can appear in a larger pack expansion,
7177 // e.g. `Pack...[pack_of_indexes]...`
7178 // so we need to temporarily disable substitution of pack elements
7179 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7180 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7181
7182 QualType Out = getDerived().RebuildPackIndexingType(
7183 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7184 FullySubstituted, SubtitutedTypes);
7185 if (Out.isNull())
7186 return Out;
7187
7188 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7189 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7190 return Out;
7191}
7192
7193template<typename Derived>
7194QualType TreeTransform<Derived>::TransformUnaryTransformType(
7195 TypeLocBuilder &TLB,
7196 UnaryTransformTypeLoc TL) {
7197 QualType Result = TL.getType();
7198 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7199 if (Result->isDependentType()) {
7200 const UnaryTransformType *T = TL.getTypePtr();
7201
7202 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7203 if (!NewBaseTSI)
7204 return QualType();
7205 QualType NewBase = NewBaseTSI->getType();
7206
7207 Result = getDerived().RebuildUnaryTransformType(NewBase,
7208 T->getUTTKind(),
7209 TL.getKWLoc());
7210 if (Result.isNull())
7211 return QualType();
7212 }
7213
7214 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7215 NewTL.setKWLoc(TL.getKWLoc());
7216 NewTL.setParensRange(TL.getParensRange());
7217 NewTL.setUnderlyingTInfo(NewBaseTSI);
7218 return Result;
7219}
7220
7221template<typename Derived>
7222QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7223 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7224 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7225
7226 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7227 TemplateName TemplateName = getDerived().TransformTemplateName(
7228 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7229 TL.getTemplateNameLoc());
7230 if (TemplateName.isNull())
7231 return QualType();
7232
7233 QualType OldDeduced = T->getDeducedType();
7234 QualType NewDeduced;
7235 if (!OldDeduced.isNull()) {
7236 NewDeduced = getDerived().TransformType(OldDeduced);
7237 if (NewDeduced.isNull())
7238 return QualType();
7239 }
7240
7241 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7242 T->getKeyword(), TemplateName, NewDeduced);
7243 if (Result.isNull())
7244 return QualType();
7245
7246 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7247 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7248 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7249 NewTL.setQualifierLoc(QualifierLoc);
7250 return Result;
7251}
7252
7253template <typename Derived>
7254QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7255 TagTypeLoc TL) {
7256 const TagType *T = TL.getTypePtr();
7257
7258 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7259 if (QualifierLoc) {
7260 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7261 if (!QualifierLoc)
7262 return QualType();
7263 }
7264
7265 auto *TD = cast_or_null<TagDecl>(
7266 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7267 if (!TD)
7268 return QualType();
7269
7270 QualType Result = TL.getType();
7271 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7272 TD != T->getDecl()) {
7273 if (T->isCanonicalUnqualified())
7274 Result = getDerived().RebuildCanonicalTagType(TD);
7275 else
7276 Result = getDerived().RebuildTagType(
7277 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7278 if (Result.isNull())
7279 return QualType();
7280 }
7281
7282 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7283 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7284 NewTL.setQualifierLoc(QualifierLoc);
7285 NewTL.setNameLoc(TL.getNameLoc());
7286
7287 return Result;
7288}
7289
7290template <typename Derived>
7291QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7292 EnumTypeLoc TL) {
7293 return getDerived().TransformTagType(TLB, TL);
7294}
7295
7296template <typename Derived>
7297QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7298 RecordTypeLoc TL) {
7299 return getDerived().TransformTagType(TLB, TL);
7300}
7301
7302template<typename Derived>
7303QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7304 TypeLocBuilder &TLB,
7305 InjectedClassNameTypeLoc TL) {
7306 return getDerived().TransformTagType(TLB, TL);
7307}
7308
7309template<typename Derived>
7310QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7311 TypeLocBuilder &TLB,
7312 TemplateTypeParmTypeLoc TL) {
7313 return getDerived().TransformTemplateTypeParmType(
7314 TLB, TL,
7315 /*SuppressObjCLifetime=*/false);
7316}
7317
7318template <typename Derived>
7319QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7320 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7321 return TransformTypeSpecType(TLB, T: TL);
7322}
7323
7324template<typename Derived>
7325QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7326 TypeLocBuilder &TLB,
7327 SubstTemplateTypeParmTypeLoc TL) {
7328 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7329
7330 Decl *NewReplaced =
7331 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7332
7333 // Substitute into the replacement type, which itself might involve something
7334 // that needs to be transformed. This only tends to occur with default
7335 // template arguments of template template parameters.
7336 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7337 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7338 if (Replacement.isNull())
7339 return QualType();
7340
7341 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7342 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7343 Final: T->getFinal());
7344
7345 // Propagate type-source information.
7346 SubstTemplateTypeParmTypeLoc NewTL
7347 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7348 NewTL.setNameLoc(TL.getNameLoc());
7349 return Result;
7350
7351}
7352template <typename Derived>
7353QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7354 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7355 return TransformTypeSpecType(TLB, T: TL);
7356}
7357
7358template<typename Derived>
7359QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7360 TypeLocBuilder &TLB,
7361 SubstTemplateTypeParmPackTypeLoc TL) {
7362 return getDerived().TransformSubstTemplateTypeParmPackType(
7363 TLB, TL, /*SuppressObjCLifetime=*/false);
7364}
7365
7366template <typename Derived>
7367QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7368 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7369 return TransformTypeSpecType(TLB, T: TL);
7370}
7371
7372template<typename Derived>
7373QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7374 AtomicTypeLoc TL) {
7375 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7376 if (ValueType.isNull())
7377 return QualType();
7378
7379 QualType Result = TL.getType();
7380 if (getDerived().AlwaysRebuild() ||
7381 ValueType != TL.getValueLoc().getType()) {
7382 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7383 if (Result.isNull())
7384 return QualType();
7385 }
7386
7387 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7388 NewTL.setKWLoc(TL.getKWLoc());
7389 NewTL.setLParenLoc(TL.getLParenLoc());
7390 NewTL.setRParenLoc(TL.getRParenLoc());
7391
7392 return Result;
7393}
7394
7395template <typename Derived>
7396QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7397 PipeTypeLoc TL) {
7398 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7399 if (ValueType.isNull())
7400 return QualType();
7401
7402 QualType Result = TL.getType();
7403 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7404 const PipeType *PT = Result->castAs<PipeType>();
7405 bool isReadPipe = PT->isReadOnly();
7406 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7407 if (Result.isNull())
7408 return QualType();
7409 }
7410
7411 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7412 NewTL.setKWLoc(TL.getKWLoc());
7413
7414 return Result;
7415}
7416
7417template <typename Derived>
7418QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7419 BitIntTypeLoc TL) {
7420 const BitIntType *EIT = TL.getTypePtr();
7421 QualType Result = TL.getType();
7422
7423 if (getDerived().AlwaysRebuild()) {
7424 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7425 EIT->getNumBits(), TL.getNameLoc());
7426 if (Result.isNull())
7427 return QualType();
7428 }
7429
7430 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7431 NewTL.setNameLoc(TL.getNameLoc());
7432 return Result;
7433}
7434
7435template <typename Derived>
7436QualType TreeTransform<Derived>::TransformDependentBitIntType(
7437 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7438 const DependentBitIntType *EIT = TL.getTypePtr();
7439
7440 EnterExpressionEvaluationContext Unevaluated(
7441 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7442 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7443 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7444
7445 if (BitsExpr.isInvalid())
7446 return QualType();
7447
7448 QualType Result = TL.getType();
7449
7450 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7451 Result = getDerived().RebuildDependentBitIntType(
7452 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7453
7454 if (Result.isNull())
7455 return QualType();
7456 }
7457
7458 if (isa<DependentBitIntType>(Val: Result)) {
7459 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7460 NewTL.setNameLoc(TL.getNameLoc());
7461 } else {
7462 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7463 NewTL.setNameLoc(TL.getNameLoc());
7464 }
7465 return Result;
7466}
7467
7468template <typename Derived>
7469QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7470 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7471 llvm_unreachable("This type does not need to be transformed.");
7472}
7473
7474 /// Simple iterator that traverses the template arguments in a
7475 /// container that provides a \c getArgLoc() member function.
7476 ///
7477 /// This iterator is intended to be used with the iterator form of
7478 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7479 template<typename ArgLocContainer>
7480 class TemplateArgumentLocContainerIterator {
7481 ArgLocContainer *Container;
7482 unsigned Index;
7483
7484 public:
7485 typedef TemplateArgumentLoc value_type;
7486 typedef TemplateArgumentLoc reference;
7487 typedef int difference_type;
7488 typedef std::input_iterator_tag iterator_category;
7489
7490 class pointer {
7491 TemplateArgumentLoc Arg;
7492
7493 public:
7494 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7495
7496 const TemplateArgumentLoc *operator->() const {
7497 return &Arg;
7498 }
7499 };
7500
7501
7502 TemplateArgumentLocContainerIterator() {}
7503
7504 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7505 unsigned Index)
7506 : Container(&Container), Index(Index) { }
7507
7508 TemplateArgumentLocContainerIterator &operator++() {
7509 ++Index;
7510 return *this;
7511 }
7512
7513 TemplateArgumentLocContainerIterator operator++(int) {
7514 TemplateArgumentLocContainerIterator Old(*this);
7515 ++(*this);
7516 return Old;
7517 }
7518
7519 TemplateArgumentLoc operator*() const {
7520 return Container->getArgLoc(Index);
7521 }
7522
7523 pointer operator->() const {
7524 return pointer(Container->getArgLoc(Index));
7525 }
7526
7527 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7528 const TemplateArgumentLocContainerIterator &Y) {
7529 return X.Container == Y.Container && X.Index == Y.Index;
7530 }
7531
7532 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7533 const TemplateArgumentLocContainerIterator &Y) {
7534 return !(X == Y);
7535 }
7536 };
7537
7538template<typename Derived>
7539QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7540 AutoTypeLoc TL) {
7541 const AutoType *T = TL.getTypePtr();
7542 QualType OldDeduced = T->getDeducedType();
7543 QualType NewDeduced;
7544 if (!OldDeduced.isNull()) {
7545 NewDeduced = getDerived().TransformType(OldDeduced);
7546 if (NewDeduced.isNull())
7547 return QualType();
7548 }
7549
7550 ConceptDecl *NewCD = nullptr;
7551 TemplateArgumentListInfo NewTemplateArgs;
7552 NestedNameSpecifierLoc NewNestedNameSpec;
7553 if (T->isConstrained()) {
7554 assert(TL.getConceptReference());
7555 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7556 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7557
7558 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7559 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7560 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7561 if (getDerived().TransformTemplateArguments(
7562 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7563 NewTemplateArgs))
7564 return QualType();
7565
7566 if (TL.getNestedNameSpecifierLoc()) {
7567 NewNestedNameSpec
7568 = getDerived().TransformNestedNameSpecifierLoc(
7569 TL.getNestedNameSpecifierLoc());
7570 if (!NewNestedNameSpec)
7571 return QualType();
7572 }
7573 }
7574
7575 QualType Result = TL.getType();
7576 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7577 T->isDependentType() || T->isConstrained()) {
7578 // FIXME: Maybe don't rebuild if all template arguments are the same.
7579 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7580 NewArgList.reserve(N: NewTemplateArgs.size());
7581 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7582 NewArgList.push_back(Elt: ArgLoc.getArgument());
7583 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7584 NewArgList);
7585 if (Result.isNull())
7586 return QualType();
7587 }
7588
7589 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7590 NewTL.setNameLoc(TL.getNameLoc());
7591 NewTL.setRParenLoc(TL.getRParenLoc());
7592 NewTL.setConceptReference(nullptr);
7593
7594 if (T->isConstrained()) {
7595 DeclarationNameInfo DNI = DeclarationNameInfo(
7596 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7597 TL.getConceptNameLoc(),
7598 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7599 auto *CR = ConceptReference::Create(
7600 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7601 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7602 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7603 NewTL.setConceptReference(CR);
7604 }
7605
7606 return Result;
7607}
7608
7609template <typename Derived>
7610QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7611 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7612 return getDerived().TransformTemplateSpecializationType(
7613 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7614 /*AllowInjectedClassName=*/false);
7615}
7616
7617template <typename Derived>
7618QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7619 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7620 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7621 const TemplateSpecializationType *T = TL.getTypePtr();
7622
7623 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7624 TemplateName Template = getDerived().TransformTemplateName(
7625 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7626 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7627 AllowInjectedClassName);
7628 if (Template.isNull())
7629 return QualType();
7630
7631 TemplateArgumentListInfo NewTemplateArgs;
7632 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7633 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7634 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7635 ArgIterator;
7636 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7637 ArgIterator(TL, TL.getNumArgs()),
7638 NewTemplateArgs))
7639 return QualType();
7640
7641 // This needs to be rebuilt if either the arguments changed, or if the
7642 // original template changed. If the template changed, and even if the
7643 // arguments didn't change, these arguments might not correspond to their
7644 // respective parameters, therefore needing conversions.
7645 QualType Result = getDerived().RebuildTemplateSpecializationType(
7646 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7647 NewTemplateArgs);
7648
7649 if (!Result.isNull()) {
7650 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7651 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7652 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7653 }
7654
7655 return Result;
7656}
7657
7658template <typename Derived>
7659QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7660 AttributedTypeLoc TL) {
7661 const AttributedType *oldType = TL.getTypePtr();
7662 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7663 if (modifiedType.isNull())
7664 return QualType();
7665
7666 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7667 const Attr *oldAttr = TL.getAttr();
7668 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7669 if (oldAttr && !newAttr)
7670 return QualType();
7671
7672 QualType result = TL.getType();
7673
7674 // FIXME: dependent operand expressions?
7675 if (getDerived().AlwaysRebuild() ||
7676 modifiedType != oldType->getModifiedType()) {
7677 // If the equivalent type is equal to the modified type, we don't want to
7678 // transform it as well because:
7679 //
7680 // 1. The transformation would yield the same result and is therefore
7681 // superfluous, and
7682 //
7683 // 2. Transforming the same type twice can cause problems, e.g. if it
7684 // is a FunctionProtoType, we may end up instantiating the function
7685 // parameters twice, which causes an assertion since the parameters
7686 // are already bound to their counterparts in the template for this
7687 // instantiation.
7688 //
7689 QualType equivalentType = modifiedType;
7690 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7691 TypeLocBuilder AuxiliaryTLB;
7692 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7693 equivalentType =
7694 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7695 if (equivalentType.isNull())
7696 return QualType();
7697 }
7698
7699 // Check whether we can add nullability; it is only represented as
7700 // type sugar, and therefore cannot be diagnosed in any other way.
7701 if (auto nullability = oldType->getImmediateNullability()) {
7702 if (!modifiedType->canHaveNullability()) {
7703 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7704 : TL.getModifiedLoc().getBeginLoc()),
7705 DiagID: diag::err_nullability_nonpointer)
7706 << DiagNullabilityKind(*nullability, false) << modifiedType;
7707 return QualType();
7708 }
7709 }
7710
7711 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7712 modifiedType,
7713 equivalentType,
7714 attr: TL.getAttr());
7715 }
7716
7717 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7718 newTL.setAttr(newAttr);
7719 return result;
7720}
7721
7722template <typename Derived>
7723QualType TreeTransform<Derived>::TransformCountAttributedType(
7724 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7725 const CountAttributedType *OldTy = TL.getTypePtr();
7726 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7727 if (InnerTy.isNull())
7728 return QualType();
7729
7730 Expr *OldCount = TL.getCountExpr();
7731 Expr *NewCount = nullptr;
7732 if (OldCount) {
7733 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7734 if (CountResult.isInvalid())
7735 return QualType();
7736 NewCount = CountResult.get();
7737 }
7738
7739 QualType Result = TL.getType();
7740 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7741 OldCount != NewCount) {
7742 // Currently, CountAttributedType can only wrap incomplete array types.
7743 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7744 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7745 }
7746
7747 TLB.push<CountAttributedTypeLoc>(T: Result);
7748 return Result;
7749}
7750
7751template <typename Derived>
7752QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7753 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7754 // The BTFTagAttributedType is available for C only.
7755 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7756}
7757
7758template <typename Derived>
7759QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7760 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7761
7762 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7763
7764 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7765 if (WrappedTy.isNull())
7766 return QualType();
7767
7768 QualType ContainedTy = QualType();
7769 QualType OldContainedTy = oldType->getContainedType();
7770 TypeSourceInfo *ContainedTSI = nullptr;
7771 if (!OldContainedTy.isNull()) {
7772 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7773 if (!oldContainedTSI)
7774 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7775 OldContainedTy, SourceLocation());
7776 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7777 if (!ContainedTSI)
7778 return QualType();
7779 ContainedTy = ContainedTSI->getType();
7780 }
7781
7782 QualType Result = TL.getType();
7783 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7784 ContainedTy != oldType->getContainedType()) {
7785 Result = SemaRef.Context.getHLSLAttributedResourceType(
7786 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7787 }
7788
7789 HLSLAttributedResourceTypeLoc NewTL =
7790 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7791 NewTL.setSourceRange(TL.getLocalSourceRange());
7792 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7793 return Result;
7794}
7795
7796template <typename Derived>
7797QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7798 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7799 // No transformations needed.
7800 return TL.getType();
7801}
7802
7803template<typename Derived>
7804QualType
7805TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7806 ParenTypeLoc TL) {
7807 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7808 if (Inner.isNull())
7809 return QualType();
7810
7811 QualType Result = TL.getType();
7812 if (getDerived().AlwaysRebuild() ||
7813 Inner != TL.getInnerLoc().getType()) {
7814 Result = getDerived().RebuildParenType(Inner);
7815 if (Result.isNull())
7816 return QualType();
7817 }
7818
7819 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7820 NewTL.setLParenLoc(TL.getLParenLoc());
7821 NewTL.setRParenLoc(TL.getRParenLoc());
7822 return Result;
7823}
7824
7825template <typename Derived>
7826QualType
7827TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7828 MacroQualifiedTypeLoc 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() || Inner != TL.getInnerLoc().getType()) {
7835 Result =
7836 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7837 if (Result.isNull())
7838 return QualType();
7839 }
7840
7841 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7842 NewTL.setExpansionLoc(TL.getExpansionLoc());
7843 return Result;
7844}
7845
7846template<typename Derived>
7847QualType TreeTransform<Derived>::TransformDependentNameType(
7848 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7849 return TransformDependentNameType(TLB, TL, false);
7850}
7851
7852template <typename Derived>
7853QualType TreeTransform<Derived>::TransformDependentNameType(
7854 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
7855 QualType ObjectType, NamedDecl *UnqualLookup) {
7856 const DependentNameType *T = TL.getTypePtr();
7857
7858 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7859 if (QualifierLoc) {
7860 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
7861 QualifierLoc, ObjectType, UnqualLookup);
7862 if (!QualifierLoc)
7863 return QualType();
7864 } else {
7865 assert((ObjectType.isNull() && !UnqualLookup) &&
7866 "must be transformed by TransformNestedNameSpecifierLoc");
7867 }
7868
7869 QualType Result
7870 = getDerived().RebuildDependentNameType(T->getKeyword(),
7871 TL.getElaboratedKeywordLoc(),
7872 QualifierLoc,
7873 T->getIdentifier(),
7874 TL.getNameLoc(),
7875 DeducedTSTContext);
7876 if (Result.isNull())
7877 return QualType();
7878
7879 if (isa<TagType>(Val: Result)) {
7880 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
7881 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7882 NewTL.setQualifierLoc(QualifierLoc);
7883 NewTL.setNameLoc(TL.getNameLoc());
7884 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
7885 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7886 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7887 NewTL.setTemplateNameLoc(TL.getNameLoc());
7888 NewTL.setQualifierLoc(QualifierLoc);
7889 } else if (isa<TypedefType>(Val: Result)) {
7890 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7891 QualifierLoc, NameLoc: TL.getNameLoc());
7892 } else if (isa<UnresolvedUsingType>(Val: Result)) {
7893 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
7894 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
7895 } else {
7896 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7897 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7898 NewTL.setQualifierLoc(QualifierLoc);
7899 NewTL.setNameLoc(TL.getNameLoc());
7900 }
7901 return Result;
7902}
7903
7904template<typename Derived>
7905QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7906 PackExpansionTypeLoc TL) {
7907 QualType Pattern
7908 = getDerived().TransformType(TLB, TL.getPatternLoc());
7909 if (Pattern.isNull())
7910 return QualType();
7911
7912 QualType Result = TL.getType();
7913 if (getDerived().AlwaysRebuild() ||
7914 Pattern != TL.getPatternLoc().getType()) {
7915 Result = getDerived().RebuildPackExpansionType(Pattern,
7916 TL.getPatternLoc().getSourceRange(),
7917 TL.getEllipsisLoc(),
7918 TL.getTypePtr()->getNumExpansions());
7919 if (Result.isNull())
7920 return QualType();
7921 }
7922
7923 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7924 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7925 return Result;
7926}
7927
7928template<typename Derived>
7929QualType
7930TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7931 ObjCInterfaceTypeLoc TL) {
7932 // ObjCInterfaceType is never dependent.
7933 TLB.pushFullCopy(L: TL);
7934 return TL.getType();
7935}
7936
7937template<typename Derived>
7938QualType
7939TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7940 ObjCTypeParamTypeLoc TL) {
7941 const ObjCTypeParamType *T = TL.getTypePtr();
7942 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7943 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7944 if (!OTP)
7945 return QualType();
7946
7947 QualType Result = TL.getType();
7948 if (getDerived().AlwaysRebuild() ||
7949 OTP != T->getDecl()) {
7950 Result = getDerived().RebuildObjCTypeParamType(
7951 OTP, TL.getProtocolLAngleLoc(),
7952 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7953 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7954 if (Result.isNull())
7955 return QualType();
7956 }
7957
7958 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7959 if (TL.getNumProtocols()) {
7960 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7961 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7962 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7963 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7964 }
7965 return Result;
7966}
7967
7968template<typename Derived>
7969QualType
7970TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7971 ObjCObjectTypeLoc TL) {
7972 // Transform base type.
7973 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7974 if (BaseType.isNull())
7975 return QualType();
7976
7977 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7978
7979 // Transform type arguments.
7980 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7981 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7982 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7983 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7984 QualType TypeArg = TypeArgInfo->getType();
7985 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7986 AnyChanged = true;
7987
7988 // We have a pack expansion. Instantiate it.
7989 const auto *PackExpansion = PackExpansionLoc.getType()
7990 ->castAs<PackExpansionType>();
7991 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7992 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
7993 Unexpanded);
7994 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7995
7996 // Determine whether the set of unexpanded parameter packs can
7997 // and should be expanded.
7998 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7999 bool Expand = false;
8000 bool RetainExpansion = false;
8001 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8002 if (getDerived().TryExpandParameterPacks(
8003 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8004 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8005 RetainExpansion, NumExpansions))
8006 return QualType();
8007
8008 if (!Expand) {
8009 // We can't expand this pack expansion into separate arguments yet;
8010 // just substitute into the pattern and create a new pack expansion
8011 // type.
8012 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8013
8014 TypeLocBuilder TypeArgBuilder;
8015 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8016 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8017 PatternLoc);
8018 if (NewPatternType.isNull())
8019 return QualType();
8020
8021 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8022 Pattern: NewPatternType, NumExpansions);
8023 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8024 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8025 NewTypeArgInfos.push_back(
8026 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8027 continue;
8028 }
8029
8030 // Substitute into the pack expansion pattern for each slice of the
8031 // pack.
8032 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8033 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8034
8035 TypeLocBuilder TypeArgBuilder;
8036 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8037
8038 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8039 PatternLoc);
8040 if (NewTypeArg.isNull())
8041 return QualType();
8042
8043 NewTypeArgInfos.push_back(
8044 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8045 }
8046
8047 continue;
8048 }
8049
8050 TypeLocBuilder TypeArgBuilder;
8051 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8052 QualType NewTypeArg =
8053 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8054 if (NewTypeArg.isNull())
8055 return QualType();
8056
8057 // If nothing changed, just keep the old TypeSourceInfo.
8058 if (NewTypeArg == TypeArg) {
8059 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8060 continue;
8061 }
8062
8063 NewTypeArgInfos.push_back(
8064 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8065 AnyChanged = true;
8066 }
8067
8068 QualType Result = TL.getType();
8069 if (getDerived().AlwaysRebuild() || AnyChanged) {
8070 // Rebuild the type.
8071 Result = getDerived().RebuildObjCObjectType(
8072 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8073 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8074 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8075 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8076
8077 if (Result.isNull())
8078 return QualType();
8079 }
8080
8081 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8082 NewT.setHasBaseTypeAsWritten(true);
8083 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8084 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8085 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8086 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8087 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8088 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8089 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8090 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8091 return Result;
8092}
8093
8094template<typename Derived>
8095QualType
8096TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8097 ObjCObjectPointerTypeLoc TL) {
8098 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8099 if (PointeeType.isNull())
8100 return QualType();
8101
8102 QualType Result = TL.getType();
8103 if (getDerived().AlwaysRebuild() ||
8104 PointeeType != TL.getPointeeLoc().getType()) {
8105 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8106 TL.getStarLoc());
8107 if (Result.isNull())
8108 return QualType();
8109 }
8110
8111 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8112 NewT.setStarLoc(TL.getStarLoc());
8113 return Result;
8114}
8115
8116//===----------------------------------------------------------------------===//
8117// Statement transformation
8118//===----------------------------------------------------------------------===//
8119template<typename Derived>
8120StmtResult
8121TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8122 return S;
8123}
8124
8125template<typename Derived>
8126StmtResult
8127TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8128 return getDerived().TransformCompoundStmt(S, false);
8129}
8130
8131template<typename Derived>
8132StmtResult
8133TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8134 bool IsStmtExpr) {
8135 Sema::CompoundScopeRAII CompoundScope(getSema());
8136 Sema::FPFeaturesStateRAII FPSave(getSema());
8137 if (S->hasStoredFPFeatures())
8138 getSema().resetFPOptions(
8139 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8140
8141 bool SubStmtInvalid = false;
8142 bool SubStmtChanged = false;
8143 SmallVector<Stmt*, 8> Statements;
8144 for (auto *B : S->body()) {
8145 StmtResult Result = getDerived().TransformStmt(
8146 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8147 : StmtDiscardKind::Discarded);
8148
8149 if (Result.isInvalid()) {
8150 // Immediately fail if this was a DeclStmt, since it's very
8151 // likely that this will cause problems for future statements.
8152 if (isa<DeclStmt>(Val: B))
8153 return StmtError();
8154
8155 // Otherwise, just keep processing substatements and fail later.
8156 SubStmtInvalid = true;
8157 continue;
8158 }
8159
8160 SubStmtChanged = SubStmtChanged || Result.get() != B;
8161 Statements.push_back(Elt: Result.getAs<Stmt>());
8162 }
8163
8164 if (SubStmtInvalid)
8165 return StmtError();
8166
8167 if (!getDerived().AlwaysRebuild() &&
8168 !SubStmtChanged)
8169 return S;
8170
8171 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8172 Statements,
8173 S->getRBracLoc(),
8174 IsStmtExpr);
8175}
8176
8177template<typename Derived>
8178StmtResult
8179TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8180 ExprResult LHS, RHS;
8181 {
8182 EnterExpressionEvaluationContext Unevaluated(
8183 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8184
8185 // Transform the left-hand case value.
8186 LHS = getDerived().TransformExpr(S->getLHS());
8187 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8188 if (LHS.isInvalid())
8189 return StmtError();
8190
8191 // Transform the right-hand case value (for the GNU case-range extension).
8192 RHS = getDerived().TransformExpr(S->getRHS());
8193 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8194 if (RHS.isInvalid())
8195 return StmtError();
8196 }
8197
8198 // Build the case statement.
8199 // Case statements are always rebuilt so that they will attached to their
8200 // transformed switch statement.
8201 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8202 LHS.get(),
8203 S->getEllipsisLoc(),
8204 RHS.get(),
8205 S->getColonLoc());
8206 if (Case.isInvalid())
8207 return StmtError();
8208
8209 // Transform the statement following the case
8210 StmtResult SubStmt =
8211 getDerived().TransformStmt(S->getSubStmt());
8212 if (SubStmt.isInvalid())
8213 return StmtError();
8214
8215 // Attach the body to the case statement
8216 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8217}
8218
8219template <typename Derived>
8220StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8221 // Transform the statement following the default case
8222 StmtResult SubStmt =
8223 getDerived().TransformStmt(S->getSubStmt());
8224 if (SubStmt.isInvalid())
8225 return StmtError();
8226
8227 // Default statements are always rebuilt
8228 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8229 SubStmt.get());
8230}
8231
8232template<typename Derived>
8233StmtResult
8234TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8235 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8236 if (SubStmt.isInvalid())
8237 return StmtError();
8238
8239 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8240 S->getDecl());
8241 if (!LD)
8242 return StmtError();
8243
8244 // If we're transforming "in-place" (we're not creating new local
8245 // declarations), assume we're replacing the old label statement
8246 // and clear out the reference to it.
8247 if (LD == S->getDecl())
8248 S->getDecl()->setStmt(nullptr);
8249
8250 // FIXME: Pass the real colon location in.
8251 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8252 cast<LabelDecl>(Val: LD), SourceLocation(),
8253 SubStmt.get());
8254}
8255
8256template <typename Derived>
8257const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8258 if (!R)
8259 return R;
8260
8261 switch (R->getKind()) {
8262// Transform attributes by calling TransformXXXAttr.
8263#define ATTR(X) \
8264 case attr::X: \
8265 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8266#include "clang/Basic/AttrList.inc"
8267 }
8268 return R;
8269}
8270
8271template <typename Derived>
8272const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8273 const Stmt *InstS,
8274 const Attr *R) {
8275 if (!R)
8276 return R;
8277
8278 switch (R->getKind()) {
8279// Transform attributes by calling TransformStmtXXXAttr.
8280#define ATTR(X) \
8281 case attr::X: \
8282 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8283#include "clang/Basic/AttrList.inc"
8284 }
8285 return TransformAttr(R);
8286}
8287
8288template <typename Derived>
8289StmtResult
8290TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8291 StmtDiscardKind SDK) {
8292 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8293 if (SubStmt.isInvalid())
8294 return StmtError();
8295
8296 bool AttrsChanged = false;
8297 SmallVector<const Attr *, 1> Attrs;
8298
8299 // Visit attributes and keep track if any are transformed.
8300 for (const auto *I : S->getAttrs()) {
8301 const Attr *R =
8302 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8303 AttrsChanged |= (I != R);
8304 if (R)
8305 Attrs.push_back(Elt: R);
8306 }
8307
8308 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8309 return S;
8310
8311 // If transforming the attributes failed for all of the attributes in the
8312 // statement, don't make an AttributedStmt without attributes.
8313 if (Attrs.empty())
8314 return SubStmt;
8315
8316 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8317 SubStmt.get());
8318}
8319
8320template<typename Derived>
8321StmtResult
8322TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8323 // Transform the initialization statement
8324 StmtResult Init = getDerived().TransformStmt(S->getInit());
8325 if (Init.isInvalid())
8326 return StmtError();
8327
8328 Sema::ConditionResult Cond;
8329 if (!S->isConsteval()) {
8330 // Transform the condition
8331 Cond = getDerived().TransformCondition(
8332 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8333 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8334 : Sema::ConditionKind::Boolean);
8335 if (Cond.isInvalid())
8336 return StmtError();
8337 }
8338
8339 // If this is a constexpr if, determine which arm we should instantiate.
8340 std::optional<bool> ConstexprConditionValue;
8341 if (S->isConstexpr())
8342 ConstexprConditionValue = Cond.getKnownValue();
8343
8344 // Transform the "then" branch.
8345 StmtResult Then;
8346 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8347 EnterExpressionEvaluationContext Ctx(
8348 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8349 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8350 S->isNonNegatedConsteval());
8351
8352 Then = getDerived().TransformStmt(S->getThen());
8353 if (Then.isInvalid())
8354 return StmtError();
8355 } else {
8356 // Discarded branch is replaced with empty CompoundStmt so we can keep
8357 // proper source location for start and end of original branch, so
8358 // subsequent transformations like CoverageMapping work properly
8359 Then = new (getSema().Context)
8360 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8361 }
8362
8363 // Transform the "else" branch.
8364 StmtResult Else;
8365 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8366 EnterExpressionEvaluationContext Ctx(
8367 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8368 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8369 S->isNegatedConsteval());
8370
8371 Else = getDerived().TransformStmt(S->getElse());
8372 if (Else.isInvalid())
8373 return StmtError();
8374 } else if (S->getElse() && ConstexprConditionValue &&
8375 *ConstexprConditionValue) {
8376 // Same thing here as with <then> branch, we are discarding it, we can't
8377 // replace it with NULL nor NullStmt as we need to keep for source location
8378 // range, for CoverageMapping
8379 Else = new (getSema().Context)
8380 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8381 }
8382
8383 if (!getDerived().AlwaysRebuild() &&
8384 Init.get() == S->getInit() &&
8385 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8386 Then.get() == S->getThen() &&
8387 Else.get() == S->getElse())
8388 return S;
8389
8390 return getDerived().RebuildIfStmt(
8391 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8392 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8393}
8394
8395template<typename Derived>
8396StmtResult
8397TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8398 // Transform the initialization statement
8399 StmtResult Init = getDerived().TransformStmt(S->getInit());
8400 if (Init.isInvalid())
8401 return StmtError();
8402
8403 // Transform the condition.
8404 Sema::ConditionResult Cond = getDerived().TransformCondition(
8405 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8406 Sema::ConditionKind::Switch);
8407 if (Cond.isInvalid())
8408 return StmtError();
8409
8410 // Rebuild the switch statement.
8411 StmtResult Switch =
8412 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8413 Init.get(), Cond, S->getRParenLoc());
8414 if (Switch.isInvalid())
8415 return StmtError();
8416
8417 // Transform the body of the switch statement.
8418 StmtResult Body = getDerived().TransformStmt(S->getBody());
8419 if (Body.isInvalid())
8420 return StmtError();
8421
8422 // Complete the switch statement.
8423 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8424 Body.get());
8425}
8426
8427template<typename Derived>
8428StmtResult
8429TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8430 // Transform the condition
8431 Sema::ConditionResult Cond = getDerived().TransformCondition(
8432 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8433 Sema::ConditionKind::Boolean);
8434 if (Cond.isInvalid())
8435 return StmtError();
8436
8437 // OpenACC Restricts a while-loop inside of certain construct/clause
8438 // combinations, so diagnose that here in OpenACC mode.
8439 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8440 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8441
8442 // Transform the body
8443 StmtResult Body = getDerived().TransformStmt(S->getBody());
8444 if (Body.isInvalid())
8445 return StmtError();
8446
8447 if (!getDerived().AlwaysRebuild() &&
8448 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8449 Body.get() == S->getBody())
8450 return Owned(S);
8451
8452 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8453 Cond, S->getRParenLoc(), Body.get());
8454}
8455
8456template<typename Derived>
8457StmtResult
8458TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8459 // OpenACC Restricts a do-loop inside of certain construct/clause
8460 // combinations, so diagnose that here in OpenACC mode.
8461 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8462 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8463
8464 // Transform the body
8465 StmtResult Body = getDerived().TransformStmt(S->getBody());
8466 if (Body.isInvalid())
8467 return StmtError();
8468
8469 // Transform the condition
8470 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8471 if (Cond.isInvalid())
8472 return StmtError();
8473
8474 if (!getDerived().AlwaysRebuild() &&
8475 Cond.get() == S->getCond() &&
8476 Body.get() == S->getBody())
8477 return S;
8478
8479 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8480 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8481 S->getRParenLoc());
8482}
8483
8484template<typename Derived>
8485StmtResult
8486TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8487 if (getSema().getLangOpts().OpenMP)
8488 getSema().OpenMP().startOpenMPLoop();
8489
8490 // Transform the initialization statement
8491 StmtResult Init = getDerived().TransformStmt(S->getInit());
8492 if (Init.isInvalid())
8493 return StmtError();
8494
8495 // In OpenMP loop region loop control variable must be captured and be
8496 // private. Perform analysis of first part (if any).
8497 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8498 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8499 Init.get());
8500
8501 // Transform the condition
8502 Sema::ConditionResult Cond = getDerived().TransformCondition(
8503 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8504 Sema::ConditionKind::Boolean);
8505 if (Cond.isInvalid())
8506 return StmtError();
8507
8508 // Transform the increment
8509 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8510 if (Inc.isInvalid())
8511 return StmtError();
8512
8513 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8514 if (S->getInc() && !FullInc.get())
8515 return StmtError();
8516
8517 // OpenACC Restricts a for-loop inside of certain construct/clause
8518 // combinations, so diagnose that here in OpenACC mode.
8519 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8520 SemaRef.OpenACC().ActOnForStmtBegin(
8521 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8522 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8523
8524 // Transform the body
8525 StmtResult Body = getDerived().TransformStmt(S->getBody());
8526 if (Body.isInvalid())
8527 return StmtError();
8528
8529 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8530
8531 if (!getDerived().AlwaysRebuild() &&
8532 Init.get() == S->getInit() &&
8533 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8534 Inc.get() == S->getInc() &&
8535 Body.get() == S->getBody())
8536 return S;
8537
8538 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8539 Init.get(), Cond, FullInc,
8540 S->getRParenLoc(), Body.get());
8541}
8542
8543template<typename Derived>
8544StmtResult
8545TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8546 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8547 S->getLabel());
8548 if (!LD)
8549 return StmtError();
8550
8551 // Goto statements must always be rebuilt, to resolve the label.
8552 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8553 cast<LabelDecl>(Val: LD));
8554}
8555
8556template<typename Derived>
8557StmtResult
8558TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8559 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8560 if (Target.isInvalid())
8561 return StmtError();
8562 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8563
8564 if (!getDerived().AlwaysRebuild() &&
8565 Target.get() == S->getTarget())
8566 return S;
8567
8568 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8569 Target.get());
8570}
8571
8572template<typename Derived>
8573StmtResult
8574TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8575 if (!S->hasLabelTarget())
8576 return S;
8577
8578 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8579 S->getLabelDecl());
8580 if (!LD)
8581 return StmtError();
8582
8583 return new (SemaRef.Context)
8584 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8585}
8586
8587template<typename Derived>
8588StmtResult
8589TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8590 if (!S->hasLabelTarget())
8591 return S;
8592
8593 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8594 S->getLabelDecl());
8595 if (!LD)
8596 return StmtError();
8597
8598 return new (SemaRef.Context)
8599 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8600}
8601
8602template <typename Derived>
8603StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8604 StmtResult Result = getDerived().TransformStmt(S->getBody());
8605 if (!Result.isUsable())
8606 return StmtError();
8607 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8608}
8609
8610template<typename Derived>
8611StmtResult
8612TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8613 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8614 /*NotCopyInit*/false);
8615 if (Result.isInvalid())
8616 return StmtError();
8617
8618 // FIXME: We always rebuild the return statement because there is no way
8619 // to tell whether the return type of the function has changed.
8620 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8621}
8622
8623template<typename Derived>
8624StmtResult
8625TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8626 bool DeclChanged = false;
8627 SmallVector<Decl *, 4> Decls;
8628 LambdaScopeInfo *LSI = getSema().getCurLambda();
8629 for (auto *D : S->decls()) {
8630 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8631 if (!Transformed)
8632 return StmtError();
8633
8634 if (Transformed != D)
8635 DeclChanged = true;
8636
8637 if (LSI) {
8638 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8639 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8640 LSI->ContainsUnexpandedParameterPack |=
8641 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8642 } else {
8643 LSI->ContainsUnexpandedParameterPack |=
8644 getSema()
8645 .getASTContext()
8646 .getTypeDeclType(TD)
8647 ->containsUnexpandedParameterPack();
8648 }
8649 }
8650 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8651 LSI->ContainsUnexpandedParameterPack |=
8652 VD->getType()->containsUnexpandedParameterPack();
8653 }
8654
8655 Decls.push_back(Elt: Transformed);
8656 }
8657
8658 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8659 return S;
8660
8661 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8662}
8663
8664template<typename Derived>
8665StmtResult
8666TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8667
8668 SmallVector<Expr*, 8> Constraints;
8669 SmallVector<Expr*, 8> Exprs;
8670 SmallVector<IdentifierInfo *, 4> Names;
8671
8672 SmallVector<Expr*, 8> Clobbers;
8673
8674 bool ExprsChanged = false;
8675
8676 auto RebuildString = [&](Expr *E) {
8677 ExprResult Result = getDerived().TransformExpr(E);
8678 if (!Result.isUsable())
8679 return Result;
8680 if (Result.get() != E) {
8681 ExprsChanged = true;
8682 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8683 }
8684 return Result;
8685 };
8686
8687 // Go through the outputs.
8688 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8689 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8690
8691 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8692 if (Result.isInvalid())
8693 return StmtError();
8694
8695 Constraints.push_back(Elt: Result.get());
8696
8697 // Transform the output expr.
8698 Expr *OutputExpr = S->getOutputExpr(i: I);
8699 Result = getDerived().TransformExpr(OutputExpr);
8700 if (Result.isInvalid())
8701 return StmtError();
8702
8703 ExprsChanged |= Result.get() != OutputExpr;
8704
8705 Exprs.push_back(Elt: Result.get());
8706 }
8707
8708 // Go through the inputs.
8709 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8710 Names.push_back(Elt: S->getInputIdentifier(i: I));
8711
8712 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8713 if (Result.isInvalid())
8714 return StmtError();
8715
8716 Constraints.push_back(Elt: Result.get());
8717
8718 // Transform the input expr.
8719 Expr *InputExpr = S->getInputExpr(i: I);
8720 Result = getDerived().TransformExpr(InputExpr);
8721 if (Result.isInvalid())
8722 return StmtError();
8723
8724 ExprsChanged |= Result.get() != InputExpr;
8725
8726 Exprs.push_back(Elt: Result.get());
8727 }
8728
8729 // Go through the Labels.
8730 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8731 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8732
8733 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8734 if (Result.isInvalid())
8735 return StmtError();
8736 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8737 Exprs.push_back(Elt: Result.get());
8738 }
8739
8740 // Go through the clobbers.
8741 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8742 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8743 if (Result.isInvalid())
8744 return StmtError();
8745 Clobbers.push_back(Elt: Result.get());
8746 }
8747
8748 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8749 if (AsmString.isInvalid())
8750 return StmtError();
8751
8752 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8753 return S;
8754
8755 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8756 S->isVolatile(), S->getNumOutputs(),
8757 S->getNumInputs(), Names.data(),
8758 Constraints, Exprs, AsmString.get(),
8759 Clobbers, S->getNumLabels(),
8760 S->getRParenLoc());
8761}
8762
8763template<typename Derived>
8764StmtResult
8765TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8766 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8767
8768 bool HadError = false, HadChange = false;
8769
8770 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8771 SmallVector<Expr*, 8> TransformedExprs;
8772 TransformedExprs.reserve(N: SrcExprs.size());
8773 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8774 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8775 if (!Result.isUsable()) {
8776 HadError = true;
8777 } else {
8778 HadChange |= (Result.get() != SrcExprs[i]);
8779 TransformedExprs.push_back(Elt: Result.get());
8780 }
8781 }
8782
8783 if (HadError) return StmtError();
8784 if (!HadChange && !getDerived().AlwaysRebuild())
8785 return Owned(S);
8786
8787 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8788 AsmToks, S->getAsmString(),
8789 S->getNumOutputs(), S->getNumInputs(),
8790 S->getAllConstraints(), S->getClobbers(),
8791 TransformedExprs, S->getEndLoc());
8792}
8793
8794// C++ Coroutines
8795template<typename Derived>
8796StmtResult
8797TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8798 auto *ScopeInfo = SemaRef.getCurFunction();
8799 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8800 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8801 ScopeInfo->NeedsCoroutineSuspends &&
8802 ScopeInfo->CoroutineSuspends.first == nullptr &&
8803 ScopeInfo->CoroutineSuspends.second == nullptr &&
8804 "expected clean scope info");
8805
8806 // Set that we have (possibly-invalid) suspend points before we do anything
8807 // that may fail.
8808 ScopeInfo->setNeedsCoroutineSuspends(false);
8809
8810 // We re-build the coroutine promise object (and the coroutine parameters its
8811 // type and constructor depend on) based on the types used in our current
8812 // function. We must do so, and set it on the current FunctionScopeInfo,
8813 // before attempting to transform the other parts of the coroutine body
8814 // statement, such as the implicit suspend statements (because those
8815 // statements reference the FunctionScopeInfo::CoroutinePromise).
8816 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8817 return StmtError();
8818 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8819 if (!Promise)
8820 return StmtError();
8821 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8822 ScopeInfo->CoroutinePromise = Promise;
8823
8824 // Transform the implicit coroutine statements constructed using dependent
8825 // types during the previous parse: initial and final suspensions, the return
8826 // object, and others. We also transform the coroutine function's body.
8827 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8828 if (InitSuspend.isInvalid())
8829 return StmtError();
8830 StmtResult FinalSuspend =
8831 getDerived().TransformStmt(S->getFinalSuspendStmt());
8832 if (FinalSuspend.isInvalid() ||
8833 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8834 return StmtError();
8835 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8836 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8837
8838 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8839 if (BodyRes.isInvalid())
8840 return StmtError();
8841
8842 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8843 if (Builder.isInvalid())
8844 return StmtError();
8845
8846 Expr *ReturnObject = S->getReturnValueInit();
8847 assert(ReturnObject && "the return object is expected to be valid");
8848 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8849 /*NoCopyInit*/ false);
8850 if (Res.isInvalid())
8851 return StmtError();
8852 Builder.ReturnValue = Res.get();
8853
8854 // If during the previous parse the coroutine still had a dependent promise
8855 // statement, we may need to build some implicit coroutine statements
8856 // (such as exception and fallthrough handlers) for the first time.
8857 if (S->hasDependentPromiseType()) {
8858 // We can only build these statements, however, if the current promise type
8859 // is not dependent.
8860 if (!Promise->getType()->isDependentType()) {
8861 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8862 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8863 "these nodes should not have been built yet");
8864 if (!Builder.buildDependentStatements())
8865 return StmtError();
8866 }
8867 } else {
8868 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8869 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8870 if (Res.isInvalid())
8871 return StmtError();
8872 Builder.OnFallthrough = Res.get();
8873 }
8874
8875 if (auto *OnException = S->getExceptionHandler()) {
8876 StmtResult Res = getDerived().TransformStmt(OnException);
8877 if (Res.isInvalid())
8878 return StmtError();
8879 Builder.OnException = Res.get();
8880 }
8881
8882 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8883 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8884 if (Res.isInvalid())
8885 return StmtError();
8886 Builder.ReturnStmtOnAllocFailure = Res.get();
8887 }
8888
8889 // Transform any additional statements we may have already built
8890 assert(S->getAllocate() && S->getDeallocate() &&
8891 "allocation and deallocation calls must already be built");
8892 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8893 if (AllocRes.isInvalid())
8894 return StmtError();
8895 Builder.Allocate = AllocRes.get();
8896
8897 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8898 if (DeallocRes.isInvalid())
8899 return StmtError();
8900 Builder.Deallocate = DeallocRes.get();
8901
8902 if (auto *ResultDecl = S->getResultDecl()) {
8903 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8904 if (Res.isInvalid())
8905 return StmtError();
8906 Builder.ResultDecl = Res.get();
8907 }
8908
8909 if (auto *ReturnStmt = S->getReturnStmt()) {
8910 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8911 if (Res.isInvalid())
8912 return StmtError();
8913 Builder.ReturnStmt = Res.get();
8914 }
8915 }
8916
8917 return getDerived().RebuildCoroutineBodyStmt(Builder);
8918}
8919
8920template<typename Derived>
8921StmtResult
8922TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8923 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8924 /*NotCopyInit*/false);
8925 if (Result.isInvalid())
8926 return StmtError();
8927
8928 // Always rebuild; we don't know if this needs to be injected into a new
8929 // context or if the promise type has changed.
8930 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8931 S->isImplicit());
8932}
8933
8934template <typename Derived>
8935ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8936 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8937 /*NotCopyInit*/ false);
8938 if (Operand.isInvalid())
8939 return ExprError();
8940
8941 // Rebuild the common-expr from the operand rather than transforming it
8942 // separately.
8943
8944 // FIXME: getCurScope() should not be used during template instantiation.
8945 // We should pick up the set of unqualified lookup results for operator
8946 // co_await during the initial parse.
8947 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8948 getSema().getCurScope(), E->getKeywordLoc());
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().RebuildCoawaitExpr(
8953 E->getKeywordLoc(), Operand.get(),
8954 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8955}
8956
8957template <typename Derived>
8958ExprResult
8959TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8960 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8961 /*NotCopyInit*/ false);
8962 if (OperandResult.isInvalid())
8963 return ExprError();
8964
8965 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8966 E->getOperatorCoawaitLookup());
8967
8968 if (LookupResult.isInvalid())
8969 return ExprError();
8970
8971 // Always rebuild; we don't know if this needs to be injected into a new
8972 // context or if the promise type has changed.
8973 return getDerived().RebuildDependentCoawaitExpr(
8974 E->getKeywordLoc(), OperandResult.get(),
8975 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8976}
8977
8978template<typename Derived>
8979ExprResult
8980TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8981 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8982 /*NotCopyInit*/false);
8983 if (Result.isInvalid())
8984 return ExprError();
8985
8986 // Always rebuild; we don't know if this needs to be injected into a new
8987 // context or if the promise type has changed.
8988 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8989}
8990
8991// Objective-C Statements.
8992
8993template<typename Derived>
8994StmtResult
8995TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8996 // Transform the body of the @try.
8997 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8998 if (TryBody.isInvalid())
8999 return StmtError();
9000
9001 // Transform the @catch statements (if present).
9002 bool AnyCatchChanged = false;
9003 SmallVector<Stmt*, 8> CatchStmts;
9004 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9005 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9006 if (Catch.isInvalid())
9007 return StmtError();
9008 if (Catch.get() != S->getCatchStmt(I))
9009 AnyCatchChanged = true;
9010 CatchStmts.push_back(Elt: Catch.get());
9011 }
9012
9013 // Transform the @finally statement (if present).
9014 StmtResult Finally;
9015 if (S->getFinallyStmt()) {
9016 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9017 if (Finally.isInvalid())
9018 return StmtError();
9019 }
9020
9021 // If nothing changed, just retain this statement.
9022 if (!getDerived().AlwaysRebuild() &&
9023 TryBody.get() == S->getTryBody() &&
9024 !AnyCatchChanged &&
9025 Finally.get() == S->getFinallyStmt())
9026 return S;
9027
9028 // Build a new statement.
9029 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9030 CatchStmts, Finally.get());
9031}
9032
9033template<typename Derived>
9034StmtResult
9035TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9036 // Transform the @catch parameter, if there is one.
9037 VarDecl *Var = nullptr;
9038 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9039 TypeSourceInfo *TSInfo = nullptr;
9040 if (FromVar->getTypeSourceInfo()) {
9041 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9042 if (!TSInfo)
9043 return StmtError();
9044 }
9045
9046 QualType T;
9047 if (TSInfo)
9048 T = TSInfo->getType();
9049 else {
9050 T = getDerived().TransformType(FromVar->getType());
9051 if (T.isNull())
9052 return StmtError();
9053 }
9054
9055 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9056 if (!Var)
9057 return StmtError();
9058 }
9059
9060 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9061 if (Body.isInvalid())
9062 return StmtError();
9063
9064 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9065 S->getRParenLoc(),
9066 Var, Body.get());
9067}
9068
9069template<typename Derived>
9070StmtResult
9071TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9072 // Transform the body.
9073 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9074 if (Body.isInvalid())
9075 return StmtError();
9076
9077 // If nothing changed, just retain this statement.
9078 if (!getDerived().AlwaysRebuild() &&
9079 Body.get() == S->getFinallyBody())
9080 return S;
9081
9082 // Build a new statement.
9083 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9084 Body.get());
9085}
9086
9087template<typename Derived>
9088StmtResult
9089TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9090 ExprResult Operand;
9091 if (S->getThrowExpr()) {
9092 Operand = getDerived().TransformExpr(S->getThrowExpr());
9093 if (Operand.isInvalid())
9094 return StmtError();
9095 }
9096
9097 if (!getDerived().AlwaysRebuild() &&
9098 Operand.get() == S->getThrowExpr())
9099 return S;
9100
9101 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9102}
9103
9104template<typename Derived>
9105StmtResult
9106TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9107 ObjCAtSynchronizedStmt *S) {
9108 // Transform the object we are locking.
9109 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9110 if (Object.isInvalid())
9111 return StmtError();
9112 Object =
9113 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9114 Object.get());
9115 if (Object.isInvalid())
9116 return StmtError();
9117
9118 // Transform the body.
9119 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9120 if (Body.isInvalid())
9121 return StmtError();
9122
9123 // If nothing change, just retain the current statement.
9124 if (!getDerived().AlwaysRebuild() &&
9125 Object.get() == S->getSynchExpr() &&
9126 Body.get() == S->getSynchBody())
9127 return S;
9128
9129 // Build a new statement.
9130 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9131 Object.get(), Body.get());
9132}
9133
9134template<typename Derived>
9135StmtResult
9136TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9137 ObjCAutoreleasePoolStmt *S) {
9138 // Transform the body.
9139 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9140 if (Body.isInvalid())
9141 return StmtError();
9142
9143 // If nothing changed, just retain this statement.
9144 if (!getDerived().AlwaysRebuild() &&
9145 Body.get() == S->getSubStmt())
9146 return S;
9147
9148 // Build a new statement.
9149 return getDerived().RebuildObjCAutoreleasePoolStmt(
9150 S->getAtLoc(), Body.get());
9151}
9152
9153template<typename Derived>
9154StmtResult
9155TreeTransform<Derived>::TransformObjCForCollectionStmt(
9156 ObjCForCollectionStmt *S) {
9157 // Transform the element statement.
9158 StmtResult Element = getDerived().TransformStmt(
9159 S->getElement(), StmtDiscardKind::NotDiscarded);
9160 if (Element.isInvalid())
9161 return StmtError();
9162
9163 // Transform the collection expression.
9164 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9165 if (Collection.isInvalid())
9166 return StmtError();
9167
9168 // Transform the body.
9169 StmtResult Body = getDerived().TransformStmt(S->getBody());
9170 if (Body.isInvalid())
9171 return StmtError();
9172
9173 // If nothing changed, just retain this statement.
9174 if (!getDerived().AlwaysRebuild() &&
9175 Element.get() == S->getElement() &&
9176 Collection.get() == S->getCollection() &&
9177 Body.get() == S->getBody())
9178 return S;
9179
9180 // Build a new statement.
9181 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9182 Element.get(),
9183 Collection.get(),
9184 S->getRParenLoc(),
9185 Body.get());
9186}
9187
9188template <typename Derived>
9189StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9190 // Transform the exception declaration, if any.
9191 VarDecl *Var = nullptr;
9192 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9193 TypeSourceInfo *T =
9194 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9195 if (!T)
9196 return StmtError();
9197
9198 Var = getDerived().RebuildExceptionDecl(
9199 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9200 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9201 if (!Var || Var->isInvalidDecl())
9202 return StmtError();
9203 }
9204
9205 // Transform the actual exception handler.
9206 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9207 if (Handler.isInvalid())
9208 return StmtError();
9209
9210 if (!getDerived().AlwaysRebuild() && !Var &&
9211 Handler.get() == S->getHandlerBlock())
9212 return S;
9213
9214 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9215}
9216
9217template <typename Derived>
9218StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9219 // Transform the try block itself.
9220 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9221 if (TryBlock.isInvalid())
9222 return StmtError();
9223
9224 // Transform the handlers.
9225 bool HandlerChanged = false;
9226 SmallVector<Stmt *, 8> Handlers;
9227 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9228 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9229 if (Handler.isInvalid())
9230 return StmtError();
9231
9232 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9233 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9234 }
9235
9236 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9237
9238 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9239 !HandlerChanged)
9240 return S;
9241
9242 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9243 Handlers);
9244}
9245
9246template<typename Derived>
9247StmtResult
9248TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9249 EnterExpressionEvaluationContext ForRangeInitContext(
9250 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9251 /*LambdaContextDecl=*/nullptr,
9252 Sema::ExpressionEvaluationContextRecord::EK_Other,
9253 getSema().getLangOpts().CPlusPlus23);
9254
9255 // P2718R0 - Lifetime extension in range-based for loops.
9256 if (getSema().getLangOpts().CPlusPlus23) {
9257 auto &LastRecord = getSema().currentEvaluationContext();
9258 LastRecord.InLifetimeExtendingContext = true;
9259 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9260 }
9261 StmtResult Init =
9262 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9263 if (Init.isInvalid())
9264 return StmtError();
9265
9266 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9267 if (Range.isInvalid())
9268 return StmtError();
9269
9270 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9271 assert(getSema().getLangOpts().CPlusPlus23 ||
9272 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9273 auto ForRangeLifetimeExtendTemps =
9274 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9275
9276 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9277 if (Begin.isInvalid())
9278 return StmtError();
9279 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9280 if (End.isInvalid())
9281 return StmtError();
9282
9283 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9284 if (Cond.isInvalid())
9285 return StmtError();
9286 if (Cond.get())
9287 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9288 if (Cond.isInvalid())
9289 return StmtError();
9290 if (Cond.get())
9291 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9292
9293 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9294 if (Inc.isInvalid())
9295 return StmtError();
9296 if (Inc.get())
9297 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9298
9299 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9300 if (LoopVar.isInvalid())
9301 return StmtError();
9302
9303 StmtResult NewStmt = S;
9304 if (getDerived().AlwaysRebuild() ||
9305 Init.get() != S->getInit() ||
9306 Range.get() != S->getRangeStmt() ||
9307 Begin.get() != S->getBeginStmt() ||
9308 End.get() != S->getEndStmt() ||
9309 Cond.get() != S->getCond() ||
9310 Inc.get() != S->getInc() ||
9311 LoopVar.get() != S->getLoopVarStmt()) {
9312 NewStmt = getDerived().RebuildCXXForRangeStmt(
9313 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9314 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9315 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9316 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9317 // Might not have attached any initializer to the loop variable.
9318 getSema().ActOnInitializerError(
9319 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9320 return StmtError();
9321 }
9322 }
9323
9324 // OpenACC Restricts a while-loop inside of certain construct/clause
9325 // combinations, so diagnose that here in OpenACC mode.
9326 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9327 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9328
9329 StmtResult Body = getDerived().TransformStmt(S->getBody());
9330 if (Body.isInvalid())
9331 return StmtError();
9332
9333 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9334
9335 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9336 // it now so we have a new statement to attach the body to.
9337 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9338 NewStmt = getDerived().RebuildCXXForRangeStmt(
9339 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9340 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9341 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9342 if (NewStmt.isInvalid())
9343 return StmtError();
9344 }
9345
9346 if (NewStmt.get() == S)
9347 return S;
9348
9349 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9350}
9351
9352template<typename Derived>
9353StmtResult
9354TreeTransform<Derived>::TransformMSDependentExistsStmt(
9355 MSDependentExistsStmt *S) {
9356 // Transform the nested-name-specifier, if any.
9357 NestedNameSpecifierLoc QualifierLoc;
9358 if (S->getQualifierLoc()) {
9359 QualifierLoc
9360 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9361 if (!QualifierLoc)
9362 return StmtError();
9363 }
9364
9365 // Transform the declaration name.
9366 DeclarationNameInfo NameInfo = S->getNameInfo();
9367 if (NameInfo.getName()) {
9368 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9369 if (!NameInfo.getName())
9370 return StmtError();
9371 }
9372
9373 // Check whether anything changed.
9374 if (!getDerived().AlwaysRebuild() &&
9375 QualifierLoc == S->getQualifierLoc() &&
9376 NameInfo.getName() == S->getNameInfo().getName())
9377 return S;
9378
9379 // Determine whether this name exists, if we can.
9380 CXXScopeSpec SS;
9381 SS.Adopt(Other: QualifierLoc);
9382 bool Dependent = false;
9383 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9384 case IfExistsResult::Exists:
9385 if (S->isIfExists())
9386 break;
9387
9388 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9389
9390 case IfExistsResult::DoesNotExist:
9391 if (S->isIfNotExists())
9392 break;
9393
9394 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9395
9396 case IfExistsResult::Dependent:
9397 Dependent = true;
9398 break;
9399
9400 case IfExistsResult::Error:
9401 return StmtError();
9402 }
9403
9404 // We need to continue with the instantiation, so do so now.
9405 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9406 if (SubStmt.isInvalid())
9407 return StmtError();
9408
9409 // If we have resolved the name, just transform to the substatement.
9410 if (!Dependent)
9411 return SubStmt;
9412
9413 // The name is still dependent, so build a dependent expression again.
9414 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9415 S->isIfExists(),
9416 QualifierLoc,
9417 NameInfo,
9418 SubStmt.get());
9419}
9420
9421template<typename Derived>
9422ExprResult
9423TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9424 NestedNameSpecifierLoc QualifierLoc;
9425 if (E->getQualifierLoc()) {
9426 QualifierLoc
9427 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9428 if (!QualifierLoc)
9429 return ExprError();
9430 }
9431
9432 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9433 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9434 if (!PD)
9435 return ExprError();
9436
9437 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9438 if (Base.isInvalid())
9439 return ExprError();
9440
9441 return new (SemaRef.getASTContext())
9442 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9443 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9444 QualifierLoc, E->getMemberLoc());
9445}
9446
9447template <typename Derived>
9448ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9449 MSPropertySubscriptExpr *E) {
9450 auto BaseRes = getDerived().TransformExpr(E->getBase());
9451 if (BaseRes.isInvalid())
9452 return ExprError();
9453 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9454 if (IdxRes.isInvalid())
9455 return ExprError();
9456
9457 if (!getDerived().AlwaysRebuild() &&
9458 BaseRes.get() == E->getBase() &&
9459 IdxRes.get() == E->getIdx())
9460 return E;
9461
9462 return getDerived().RebuildArraySubscriptExpr(
9463 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9464}
9465
9466template <typename Derived>
9467StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9468 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9469 if (TryBlock.isInvalid())
9470 return StmtError();
9471
9472 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9473 if (Handler.isInvalid())
9474 return StmtError();
9475
9476 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9477 Handler.get() == S->getHandler())
9478 return S;
9479
9480 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9481 TryBlock.get(), Handler.get());
9482}
9483
9484template <typename Derived>
9485StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9486 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9487 if (Block.isInvalid())
9488 return StmtError();
9489
9490 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9491}
9492
9493template <typename Derived>
9494StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9495 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9496 if (FilterExpr.isInvalid())
9497 return StmtError();
9498
9499 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9500 if (Block.isInvalid())
9501 return StmtError();
9502
9503 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9504 Block.get());
9505}
9506
9507template <typename Derived>
9508StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9509 if (isa<SEHFinallyStmt>(Val: Handler))
9510 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9511 else
9512 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9513}
9514
9515template<typename Derived>
9516StmtResult
9517TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9518 return S;
9519}
9520
9521//===----------------------------------------------------------------------===//
9522// OpenMP directive transformation
9523//===----------------------------------------------------------------------===//
9524
9525template <typename Derived>
9526StmtResult
9527TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9528 // OMPCanonicalLoops are eliminated during transformation, since they will be
9529 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9530 // after transformation.
9531 return getDerived().TransformStmt(L->getLoopStmt());
9532}
9533
9534template <typename Derived>
9535StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9536 OMPExecutableDirective *D) {
9537
9538 // Transform the clauses
9539 llvm::SmallVector<OMPClause *, 16> TClauses;
9540 ArrayRef<OMPClause *> Clauses = D->clauses();
9541 TClauses.reserve(N: Clauses.size());
9542 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9543 I != E; ++I) {
9544 if (*I) {
9545 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9546 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9547 getDerived().getSema().OpenMP().EndOpenMPClause();
9548 if (Clause)
9549 TClauses.push_back(Elt: Clause);
9550 } else {
9551 TClauses.push_back(Elt: nullptr);
9552 }
9553 }
9554 StmtResult AssociatedStmt;
9555 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9556 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9557 D->getDirectiveKind(),
9558 /*CurScope=*/nullptr);
9559 StmtResult Body;
9560 {
9561 Sema::CompoundScopeRAII CompoundScope(getSema());
9562 Stmt *CS;
9563 if (D->getDirectiveKind() == OMPD_atomic ||
9564 D->getDirectiveKind() == OMPD_critical ||
9565 D->getDirectiveKind() == OMPD_section ||
9566 D->getDirectiveKind() == OMPD_master)
9567 CS = D->getAssociatedStmt();
9568 else
9569 CS = D->getRawStmt();
9570 Body = getDerived().TransformStmt(CS);
9571 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9572 getSema().getLangOpts().OpenMPIRBuilder)
9573 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9574 }
9575 AssociatedStmt =
9576 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9577 if (AssociatedStmt.isInvalid()) {
9578 return StmtError();
9579 }
9580 }
9581 if (TClauses.size() != Clauses.size()) {
9582 return StmtError();
9583 }
9584
9585 // Transform directive name for 'omp critical' directive.
9586 DeclarationNameInfo DirName;
9587 if (D->getDirectiveKind() == OMPD_critical) {
9588 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9589 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9590 }
9591 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9592 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9593 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9594 } else if (D->getDirectiveKind() == OMPD_cancel) {
9595 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9596 }
9597
9598 return getDerived().RebuildOMPExecutableDirective(
9599 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9600 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9601}
9602
9603/// This is mostly the same as above, but allows 'informational' class
9604/// directives when rebuilding the stmt. It still takes an
9605/// OMPExecutableDirective-type argument because we're reusing that as the
9606/// superclass for the 'assume' directive at present, instead of defining a
9607/// mostly-identical OMPInformationalDirective parent class.
9608template <typename Derived>
9609StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9610 OMPExecutableDirective *D) {
9611
9612 // Transform the clauses
9613 llvm::SmallVector<OMPClause *, 16> TClauses;
9614 ArrayRef<OMPClause *> Clauses = D->clauses();
9615 TClauses.reserve(N: Clauses.size());
9616 for (OMPClause *C : Clauses) {
9617 if (C) {
9618 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9619 OMPClause *Clause = getDerived().TransformOMPClause(C);
9620 getDerived().getSema().OpenMP().EndOpenMPClause();
9621 if (Clause)
9622 TClauses.push_back(Elt: Clause);
9623 } else {
9624 TClauses.push_back(Elt: nullptr);
9625 }
9626 }
9627 StmtResult AssociatedStmt;
9628 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9629 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9630 D->getDirectiveKind(),
9631 /*CurScope=*/nullptr);
9632 StmtResult Body;
9633 {
9634 Sema::CompoundScopeRAII CompoundScope(getSema());
9635 assert(D->getDirectiveKind() == OMPD_assume &&
9636 "Unexpected informational directive");
9637 Stmt *CS = D->getAssociatedStmt();
9638 Body = getDerived().TransformStmt(CS);
9639 }
9640 AssociatedStmt =
9641 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9642 if (AssociatedStmt.isInvalid())
9643 return StmtError();
9644 }
9645 if (TClauses.size() != Clauses.size())
9646 return StmtError();
9647
9648 DeclarationNameInfo DirName;
9649
9650 return getDerived().RebuildOMPInformationalDirective(
9651 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9652 D->getBeginLoc(), D->getEndLoc());
9653}
9654
9655template <typename Derived>
9656StmtResult
9657TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9658 // TODO: Fix This
9659 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9660 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9661 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9662 return StmtError();
9663}
9664
9665template <typename Derived>
9666StmtResult
9667TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9668 DeclarationNameInfo DirName;
9669 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9670 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9671 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9672 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9673 return Res;
9674}
9675
9676template <typename Derived>
9677StmtResult
9678TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9679 DeclarationNameInfo DirName;
9680 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9681 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9682 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9683 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9684 return Res;
9685}
9686
9687template <typename Derived>
9688StmtResult
9689TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9690 DeclarationNameInfo DirName;
9691 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9692 D->getDirectiveKind(), 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>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9701 DeclarationNameInfo DirName;
9702 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9703 D->getDirectiveKind(), 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>::TransformOMPUnrollDirective(OMPUnrollDirective *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>::TransformOMPReverseDirective(OMPReverseDirective *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 TreeTransform<Derived>::TransformOMPInterchangeDirective(
9733 OMPInterchangeDirective *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>::TransformOMPFuseDirective(OMPFuseDirective *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
9755TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9756 DeclarationNameInfo DirName;
9757 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9758 OMPD_for, 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>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9767 DeclarationNameInfo DirName;
9768 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9769 OMPD_for_simd, 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>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9778 DeclarationNameInfo DirName;
9779 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9780 OMPD_sections, 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>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9789 DeclarationNameInfo DirName;
9790 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9791 OMPD_section, 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>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9800 DeclarationNameInfo DirName;
9801 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9802 OMPD_scope, 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>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9811 DeclarationNameInfo DirName;
9812 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9813 OMPD_single, 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>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9822 DeclarationNameInfo DirName;
9823 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9824 OMPD_master, 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>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9833 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9834 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9835 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9836 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9837 return Res;
9838}
9839
9840template <typename Derived>
9841StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9842 OMPParallelForDirective *D) {
9843 DeclarationNameInfo DirName;
9844 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9845 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9846 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9847 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9848 return Res;
9849}
9850
9851template <typename Derived>
9852StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9853 OMPParallelForSimdDirective *D) {
9854 DeclarationNameInfo DirName;
9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9856 OMPD_parallel_for_simd, DirName, 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>::TransformOMPParallelMasterDirective(
9864 OMPParallelMasterDirective *D) {
9865 DeclarationNameInfo DirName;
9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9867 OMPD_parallel_master, 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>::TransformOMPParallelMaskedDirective(
9875 OMPParallelMaskedDirective *D) {
9876 DeclarationNameInfo DirName;
9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9878 OMPD_parallel_masked, 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>::TransformOMPParallelSectionsDirective(
9886 OMPParallelSectionsDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_parallel_sections, 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
9897TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9898 DeclarationNameInfo DirName;
9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9900 OMPD_task, 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>::TransformOMPTaskyieldDirective(
9908 OMPTaskyieldDirective *D) {
9909 DeclarationNameInfo DirName;
9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9911 OMPD_taskyield, 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>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9920 DeclarationNameInfo DirName;
9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9922 OMPD_barrier, 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
9930TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9931 DeclarationNameInfo DirName;
9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9933 OMPD_taskwait, 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>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9942 DeclarationNameInfo DirName;
9943 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9944 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9945 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9946 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9947 return Res;
9948}
9949
9950template <typename Derived>
9951StmtResult
9952TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9953 DeclarationNameInfo DirName;
9954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9955 OMPD_error, 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 TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9963 OMPTaskgroupDirective *D) {
9964 DeclarationNameInfo DirName;
9965 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9966 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9967 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9968 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9969 return Res;
9970}
9971
9972template <typename Derived>
9973StmtResult
9974TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9975 DeclarationNameInfo DirName;
9976 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9977 OMPD_flush, 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
9985TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9986 DeclarationNameInfo DirName;
9987 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9988 OMPD_depobj, 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>::TransformOMPScanDirective(OMPScanDirective *D) {
9997 DeclarationNameInfo DirName;
9998 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9999 OMPD_scan, 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>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
10008 DeclarationNameInfo DirName;
10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10010 OMPD_ordered, 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>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10019 DeclarationNameInfo DirName;
10020 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10021 OMPD_atomic, 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>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10030 DeclarationNameInfo DirName;
10031 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10032 OMPD_target, 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 TreeTransform<Derived>::TransformOMPTargetDataDirective(
10040 OMPTargetDataDirective *D) {
10041 DeclarationNameInfo DirName;
10042 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10043 OMPD_target_data, 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 TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10051 OMPTargetEnterDataDirective *D) {
10052 DeclarationNameInfo DirName;
10053 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10054 OMPD_target_enter_data, 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>::TransformOMPTargetExitDataDirective(
10062 OMPTargetExitDataDirective *D) {
10063 DeclarationNameInfo DirName;
10064 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10065 OMPD_target_exit_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>::TransformOMPTargetParallelDirective(
10073 OMPTargetParallelDirective *D) {
10074 DeclarationNameInfo DirName;
10075 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10076 OMPD_target_parallel, 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>::TransformOMPTargetParallelForDirective(
10084 OMPTargetParallelForDirective *D) {
10085 DeclarationNameInfo DirName;
10086 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10087 OMPD_target_parallel_for, 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>::TransformOMPTargetUpdateDirective(
10095 OMPTargetUpdateDirective *D) {
10096 DeclarationNameInfo DirName;
10097 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10098 OMPD_target_update, 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
10106TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10107 DeclarationNameInfo DirName;
10108 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10109 OMPD_teams, 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>::TransformOMPCancellationPointDirective(
10117 OMPCancellationPointDirective *D) {
10118 DeclarationNameInfo DirName;
10119 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10120 OMPD_cancellation_point, 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>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10129 DeclarationNameInfo DirName;
10130 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10131 OMPD_cancel, 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
10139TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10140 DeclarationNameInfo DirName;
10141 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10142 OMPD_taskloop, 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 TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10150 OMPTaskLoopSimdDirective *D) {
10151 DeclarationNameInfo DirName;
10152 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10153 OMPD_taskloop_simd, 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 TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10161 OMPMasterTaskLoopDirective *D) {
10162 DeclarationNameInfo DirName;
10163 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10164 OMPD_master_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>::TransformOMPMaskedTaskLoopDirective(
10172 OMPMaskedTaskLoopDirective *D) {
10173 DeclarationNameInfo DirName;
10174 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10175 OMPD_masked_taskloop, 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>::TransformOMPMasterTaskLoopSimdDirective(
10183 OMPMasterTaskLoopSimdDirective *D) {
10184 DeclarationNameInfo DirName;
10185 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10186 OMPD_master_taskloop_simd, 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>::TransformOMPMaskedTaskLoopSimdDirective(
10194 OMPMaskedTaskLoopSimdDirective *D) {
10195 DeclarationNameInfo DirName;
10196 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10197 OMPD_masked_taskloop_simd, 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>::TransformOMPParallelMasterTaskLoopDirective(
10205 OMPParallelMasterTaskLoopDirective *D) {
10206 DeclarationNameInfo DirName;
10207 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10208 OMPD_parallel_master_taskloop, 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>::TransformOMPParallelMaskedTaskLoopDirective(
10216 OMPParallelMaskedTaskLoopDirective *D) {
10217 DeclarationNameInfo DirName;
10218 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10219 OMPD_parallel_masked_taskloop, 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
10227TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10228 OMPParallelMasterTaskLoopSimdDirective *D) {
10229 DeclarationNameInfo DirName;
10230 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10231 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10232 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10233 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10234 return Res;
10235}
10236
10237template <typename Derived>
10238StmtResult
10239TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10240 OMPParallelMaskedTaskLoopSimdDirective *D) {
10241 DeclarationNameInfo DirName;
10242 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10243 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10244 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10245 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10246 return Res;
10247}
10248
10249template <typename Derived>
10250StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10251 OMPDistributeDirective *D) {
10252 DeclarationNameInfo DirName;
10253 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10254 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10255 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10256 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10257 return Res;
10258}
10259
10260template <typename Derived>
10261StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10262 OMPDistributeParallelForDirective *D) {
10263 DeclarationNameInfo DirName;
10264 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10265 OMPD_distribute_parallel_for, 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
10273TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10274 OMPDistributeParallelForSimdDirective *D) {
10275 DeclarationNameInfo DirName;
10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10277 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10278 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10279 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10280 return Res;
10281}
10282
10283template <typename Derived>
10284StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10285 OMPDistributeSimdDirective *D) {
10286 DeclarationNameInfo DirName;
10287 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10288 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10289 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10290 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10291 return Res;
10292}
10293
10294template <typename Derived>
10295StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10296 OMPTargetParallelForSimdDirective *D) {
10297 DeclarationNameInfo DirName;
10298 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10299 OMPD_target_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>::TransformOMPTargetSimdDirective(
10307 OMPTargetSimdDirective *D) {
10308 DeclarationNameInfo DirName;
10309 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10310 OMPD_target_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>::TransformOMPTeamsDistributeDirective(
10318 OMPTeamsDistributeDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_teams_distribute, 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>::TransformOMPTeamsDistributeSimdDirective(
10329 OMPTeamsDistributeSimdDirective *D) {
10330 DeclarationNameInfo DirName;
10331 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10332 OMPD_teams_distribute_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>::TransformOMPTeamsDistributeParallelForSimdDirective(
10340 OMPTeamsDistributeParallelForSimdDirective *D) {
10341 DeclarationNameInfo DirName;
10342 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10343 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10344 D->getBeginLoc());
10345 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10346 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10347 return Res;
10348}
10349
10350template <typename Derived>
10351StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10352 OMPTeamsDistributeParallelForDirective *D) {
10353 DeclarationNameInfo DirName;
10354 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10355 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10356 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10357 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10358 return Res;
10359}
10360
10361template <typename Derived>
10362StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10363 OMPTargetTeamsDirective *D) {
10364 DeclarationNameInfo DirName;
10365 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10366 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10367 auto Res = getDerived().TransformOMPExecutableDirective(D);
10368 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10369 return Res;
10370}
10371
10372template <typename Derived>
10373StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10374 OMPTargetTeamsDistributeDirective *D) {
10375 DeclarationNameInfo DirName;
10376 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10377 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10378 auto Res = getDerived().TransformOMPExecutableDirective(D);
10379 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10380 return Res;
10381}
10382
10383template <typename Derived>
10384StmtResult
10385TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10386 OMPTargetTeamsDistributeParallelForDirective *D) {
10387 DeclarationNameInfo DirName;
10388 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10389 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10390 D->getBeginLoc());
10391 auto Res = getDerived().TransformOMPExecutableDirective(D);
10392 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10393 return Res;
10394}
10395
10396template <typename Derived>
10397StmtResult TreeTransform<Derived>::
10398 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10399 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10400 DeclarationNameInfo DirName;
10401 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10402 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10403 D->getBeginLoc());
10404 auto Res = getDerived().TransformOMPExecutableDirective(D);
10405 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10406 return Res;
10407}
10408
10409template <typename Derived>
10410StmtResult
10411TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10412 OMPTargetTeamsDistributeSimdDirective *D) {
10413 DeclarationNameInfo DirName;
10414 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10415 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10416 auto Res = getDerived().TransformOMPExecutableDirective(D);
10417 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10418 return Res;
10419}
10420
10421template <typename Derived>
10422StmtResult
10423TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10424 DeclarationNameInfo DirName;
10425 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10426 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10427 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10428 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10429 return Res;
10430}
10431
10432template <typename Derived>
10433StmtResult
10434TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10435 DeclarationNameInfo DirName;
10436 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10437 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10438 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10439 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10440 return Res;
10441}
10442
10443template <typename Derived>
10444StmtResult
10445TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10446 DeclarationNameInfo DirName;
10447 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10448 OMPD_masked, 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 TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10456 OMPGenericLoopDirective *D) {
10457 DeclarationNameInfo DirName;
10458 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10459 OMPD_loop, 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 TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10467 OMPTeamsGenericLoopDirective *D) {
10468 DeclarationNameInfo DirName;
10469 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10470 OMPD_teams_loop, 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>::TransformOMPTargetTeamsGenericLoopDirective(
10478 OMPTargetTeamsGenericLoopDirective *D) {
10479 DeclarationNameInfo DirName;
10480 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10481 OMPD_target_teams_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>::TransformOMPParallelGenericLoopDirective(
10489 OMPParallelGenericLoopDirective *D) {
10490 DeclarationNameInfo DirName;
10491 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10492 OMPD_parallel_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
10500TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10501 OMPTargetParallelGenericLoopDirective *D) {
10502 DeclarationNameInfo DirName;
10503 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10504 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10505 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10506 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10507 return Res;
10508}
10509
10510//===----------------------------------------------------------------------===//
10511// OpenMP clause transformation
10512//===----------------------------------------------------------------------===//
10513template <typename Derived>
10514OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10515 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10516 if (Cond.isInvalid())
10517 return nullptr;
10518 return getDerived().RebuildOMPIfClause(
10519 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10520 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10521}
10522
10523template <typename Derived>
10524OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10525 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10526 if (Cond.isInvalid())
10527 return nullptr;
10528 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10529 C->getLParenLoc(), C->getEndLoc());
10530}
10531
10532template <typename Derived>
10533OMPClause *
10534TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10535 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10536 if (NumThreads.isInvalid())
10537 return nullptr;
10538 return getDerived().RebuildOMPNumThreadsClause(
10539 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10540 C->getModifierLoc(), C->getEndLoc());
10541}
10542
10543template <typename Derived>
10544OMPClause *
10545TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10546 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10547 if (E.isInvalid())
10548 return nullptr;
10549 return getDerived().RebuildOMPSafelenClause(
10550 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10551}
10552
10553template <typename Derived>
10554OMPClause *
10555TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10556 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10557 if (E.isInvalid())
10558 return nullptr;
10559 return getDerived().RebuildOMPAllocatorClause(
10560 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10561}
10562
10563template <typename Derived>
10564OMPClause *
10565TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10566 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10567 if (E.isInvalid())
10568 return nullptr;
10569 return getDerived().RebuildOMPSimdlenClause(
10570 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10571}
10572
10573template <typename Derived>
10574OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10575 SmallVector<Expr *, 4> TransformedSizes;
10576 TransformedSizes.reserve(N: C->getNumSizes());
10577 bool Changed = false;
10578 for (Expr *E : C->getSizesRefs()) {
10579 if (!E) {
10580 TransformedSizes.push_back(Elt: nullptr);
10581 continue;
10582 }
10583
10584 ExprResult T = getDerived().TransformExpr(E);
10585 if (T.isInvalid())
10586 return nullptr;
10587 if (E != T.get())
10588 Changed = true;
10589 TransformedSizes.push_back(Elt: T.get());
10590 }
10591
10592 if (!Changed && !getDerived().AlwaysRebuild())
10593 return C;
10594 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10595 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10596}
10597
10598template <typename Derived>
10599OMPClause *
10600TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10601 SmallVector<Expr *> TransformedArgs;
10602 TransformedArgs.reserve(N: C->getNumLoops());
10603 bool Changed = false;
10604 for (Expr *E : C->getArgsRefs()) {
10605 if (!E) {
10606 TransformedArgs.push_back(Elt: nullptr);
10607 continue;
10608 }
10609
10610 ExprResult T = getDerived().TransformExpr(E);
10611 if (T.isInvalid())
10612 return nullptr;
10613 if (E != T.get())
10614 Changed = true;
10615 TransformedArgs.push_back(Elt: T.get());
10616 }
10617
10618 if (!Changed && !getDerived().AlwaysRebuild())
10619 return C;
10620 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10621 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10622}
10623
10624template <typename Derived>
10625OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10626 if (!getDerived().AlwaysRebuild())
10627 return C;
10628 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10629}
10630
10631template <typename Derived>
10632OMPClause *
10633TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10634 ExprResult T = getDerived().TransformExpr(C->getFactor());
10635 if (T.isInvalid())
10636 return nullptr;
10637 Expr *Factor = T.get();
10638 bool Changed = Factor != C->getFactor();
10639
10640 if (!Changed && !getDerived().AlwaysRebuild())
10641 return C;
10642 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10643 EndLoc: C->getEndLoc());
10644}
10645
10646template <typename Derived>
10647OMPClause *
10648TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
10649 ExprResult F = getDerived().TransformExpr(C->getFirst());
10650 if (F.isInvalid())
10651 return nullptr;
10652
10653 ExprResult Cn = getDerived().TransformExpr(C->getCount());
10654 if (Cn.isInvalid())
10655 return nullptr;
10656
10657 Expr *First = F.get();
10658 Expr *Count = Cn.get();
10659
10660 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
10661
10662 // If no changes and AlwaysRebuild() is false, return the original clause
10663 if (!Changed && !getDerived().AlwaysRebuild())
10664 return C;
10665
10666 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
10667 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
10668 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
10669}
10670
10671template <typename Derived>
10672OMPClause *
10673TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10674 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10675 if (E.isInvalid())
10676 return nullptr;
10677 return getDerived().RebuildOMPCollapseClause(
10678 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10679}
10680
10681template <typename Derived>
10682OMPClause *
10683TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10684 return getDerived().RebuildOMPDefaultClause(
10685 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
10686 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
10687 C->getEndLoc());
10688}
10689
10690template <typename Derived>
10691OMPClause *
10692TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
10693 // No need to rebuild this clause, no template-dependent parameters.
10694 return C;
10695}
10696
10697template <typename Derived>
10698OMPClause *
10699TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
10700 Expr *Impex = C->getImpexType();
10701 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
10702
10703 if (TransformedImpex.isInvalid())
10704 return nullptr;
10705
10706 return getDerived().RebuildOMPTransparentClause(
10707 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
10708 C->getEndLoc());
10709}
10710
10711template <typename Derived>
10712OMPClause *
10713TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10714 return getDerived().RebuildOMPProcBindClause(
10715 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10716 C->getLParenLoc(), C->getEndLoc());
10717}
10718
10719template <typename Derived>
10720OMPClause *
10721TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10722 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10723 if (E.isInvalid())
10724 return nullptr;
10725 return getDerived().RebuildOMPScheduleClause(
10726 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10727 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10728 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10729 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10730}
10731
10732template <typename Derived>
10733OMPClause *
10734TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10735 ExprResult E;
10736 if (auto *Num = C->getNumForLoops()) {
10737 E = getDerived().TransformExpr(Num);
10738 if (E.isInvalid())
10739 return nullptr;
10740 }
10741 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10742 C->getLParenLoc(), E.get());
10743}
10744
10745template <typename Derived>
10746OMPClause *
10747TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10748 ExprResult E;
10749 if (Expr *Evt = C->getEventHandler()) {
10750 E = getDerived().TransformExpr(Evt);
10751 if (E.isInvalid())
10752 return nullptr;
10753 }
10754 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10755 C->getLParenLoc(), C->getEndLoc());
10756}
10757
10758template <typename Derived>
10759OMPClause *
10760TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10761 ExprResult Cond;
10762 if (auto *Condition = C->getCondition()) {
10763 Cond = getDerived().TransformExpr(Condition);
10764 if (Cond.isInvalid())
10765 return nullptr;
10766 }
10767 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
10768 C->getLParenLoc(), C->getEndLoc());
10769}
10770
10771template <typename Derived>
10772OMPClause *
10773TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10774 // No need to rebuild this clause, no template-dependent parameters.
10775 return C;
10776}
10777
10778template <typename Derived>
10779OMPClause *
10780TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10781 // No need to rebuild this clause, no template-dependent parameters.
10782 return C;
10783}
10784
10785template <typename Derived>
10786OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10787 // No need to rebuild this clause, no template-dependent parameters.
10788 return C;
10789}
10790
10791template <typename Derived>
10792OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10793 // No need to rebuild this clause, no template-dependent parameters.
10794 return C;
10795}
10796
10797template <typename Derived>
10798OMPClause *
10799TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10800 // No need to rebuild this clause, no template-dependent parameters.
10801 return C;
10802}
10803
10804template <typename Derived>
10805OMPClause *
10806TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10807 // No need to rebuild this clause, no template-dependent parameters.
10808 return C;
10809}
10810
10811template <typename Derived>
10812OMPClause *
10813TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10814 // No need to rebuild this clause, no template-dependent parameters.
10815 return C;
10816}
10817
10818template <typename Derived>
10819OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10820 // No need to rebuild this clause, no template-dependent parameters.
10821 return C;
10822}
10823
10824template <typename Derived>
10825OMPClause *
10826TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10827 return C;
10828}
10829
10830template <typename Derived>
10831OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10832 ExprResult E = getDerived().TransformExpr(C->getExpr());
10833 if (E.isInvalid())
10834 return nullptr;
10835 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10836 C->getLParenLoc(), C->getEndLoc());
10837}
10838
10839template <typename Derived>
10840OMPClause *
10841TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10842 return C;
10843}
10844
10845template <typename Derived>
10846OMPClause *
10847TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10848 return C;
10849}
10850template <typename Derived>
10851OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10852 OMPNoOpenMPRoutinesClause *C) {
10853 return C;
10854}
10855template <typename Derived>
10856OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10857 OMPNoOpenMPConstructsClause *C) {
10858 return C;
10859}
10860template <typename Derived>
10861OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10862 OMPNoParallelismClause *C) {
10863 return C;
10864}
10865
10866template <typename Derived>
10867OMPClause *
10868TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10869 // No need to rebuild this clause, no template-dependent parameters.
10870 return C;
10871}
10872
10873template <typename Derived>
10874OMPClause *
10875TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10876 // No need to rebuild this clause, no template-dependent parameters.
10877 return C;
10878}
10879
10880template <typename Derived>
10881OMPClause *
10882TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10883 // No need to rebuild this clause, no template-dependent parameters.
10884 return C;
10885}
10886
10887template <typename Derived>
10888OMPClause *
10889TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10890 // No need to rebuild this clause, no template-dependent parameters.
10891 return C;
10892}
10893
10894template <typename Derived>
10895OMPClause *
10896TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10897 // No need to rebuild this clause, no template-dependent parameters.
10898 return C;
10899}
10900
10901template <typename Derived>
10902OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10903 // No need to rebuild this clause, no template-dependent parameters.
10904 return C;
10905}
10906
10907template <typename Derived>
10908OMPClause *
10909TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10910 // No need to rebuild this clause, no template-dependent parameters.
10911 return C;
10912}
10913
10914template <typename Derived>
10915OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10916 // No need to rebuild this clause, no template-dependent parameters.
10917 return C;
10918}
10919
10920template <typename Derived>
10921OMPClause *
10922TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10923 // No need to rebuild this clause, no template-dependent parameters.
10924 return C;
10925}
10926
10927template <typename Derived>
10928OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10929 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10930 if (IVR.isInvalid())
10931 return nullptr;
10932
10933 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10934 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10935 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlist())) {
10936 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10937 if (ER.isInvalid())
10938 return nullptr;
10939 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10940 }
10941 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10942 C->getBeginLoc(), C->getLParenLoc(),
10943 C->getVarLoc(), C->getEndLoc());
10944}
10945
10946template <typename Derived>
10947OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10948 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10949 if (ER.isInvalid())
10950 return nullptr;
10951 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10952 C->getLParenLoc(), C->getVarLoc(),
10953 C->getEndLoc());
10954}
10955
10956template <typename Derived>
10957OMPClause *
10958TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10959 ExprResult ER;
10960 if (Expr *IV = C->getInteropVar()) {
10961 ER = getDerived().TransformExpr(IV);
10962 if (ER.isInvalid())
10963 return nullptr;
10964 }
10965 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10966 C->getLParenLoc(), C->getVarLoc(),
10967 C->getEndLoc());
10968}
10969
10970template <typename Derived>
10971OMPClause *
10972TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10973 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10974 if (Cond.isInvalid())
10975 return nullptr;
10976 return getDerived().RebuildOMPNovariantsClause(
10977 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10978}
10979
10980template <typename Derived>
10981OMPClause *
10982TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10983 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10984 if (Cond.isInvalid())
10985 return nullptr;
10986 return getDerived().RebuildOMPNocontextClause(
10987 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10988}
10989
10990template <typename Derived>
10991OMPClause *
10992TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10993 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10994 if (ThreadID.isInvalid())
10995 return nullptr;
10996 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10997 C->getLParenLoc(), C->getEndLoc());
10998}
10999
11000template <typename Derived>
11001OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11002 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11003 if (E.isInvalid())
11004 return nullptr;
11005 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11006 C->getLParenLoc(), C->getEndLoc());
11007}
11008
11009template <typename Derived>
11010OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11011 OMPUnifiedAddressClause *C) {
11012 llvm_unreachable("unified_address clause cannot appear in dependent context");
11013}
11014
11015template <typename Derived>
11016OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11017 OMPUnifiedSharedMemoryClause *C) {
11018 llvm_unreachable(
11019 "unified_shared_memory clause cannot appear in dependent context");
11020}
11021
11022template <typename Derived>
11023OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11024 OMPReverseOffloadClause *C) {
11025 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11026}
11027
11028template <typename Derived>
11029OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11030 OMPDynamicAllocatorsClause *C) {
11031 llvm_unreachable(
11032 "dynamic_allocators clause cannot appear in dependent context");
11033}
11034
11035template <typename Derived>
11036OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11037 OMPAtomicDefaultMemOrderClause *C) {
11038 llvm_unreachable(
11039 "atomic_default_mem_order clause cannot appear in dependent context");
11040}
11041
11042template <typename Derived>
11043OMPClause *
11044TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11045 llvm_unreachable("self_maps clause cannot appear in dependent context");
11046}
11047
11048template <typename Derived>
11049OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11050 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11051 C->getBeginLoc(), C->getLParenLoc(),
11052 C->getEndLoc());
11053}
11054
11055template <typename Derived>
11056OMPClause *
11057TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11058 return getDerived().RebuildOMPSeverityClause(
11059 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11060 C->getLParenLoc(), C->getEndLoc());
11061}
11062
11063template <typename Derived>
11064OMPClause *
11065TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11066 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11067 if (E.isInvalid())
11068 return nullptr;
11069 return getDerived().RebuildOMPMessageClause(
11070 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11071}
11072
11073template <typename Derived>
11074OMPClause *
11075TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11076 llvm::SmallVector<Expr *, 16> Vars;
11077 Vars.reserve(N: C->varlist_size());
11078 for (auto *VE : C->varlist()) {
11079 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11080 if (EVar.isInvalid())
11081 return nullptr;
11082 Vars.push_back(Elt: EVar.get());
11083 }
11084 return getDerived().RebuildOMPPrivateClause(
11085 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11086}
11087
11088template <typename Derived>
11089OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11090 OMPFirstprivateClause *C) {
11091 llvm::SmallVector<Expr *, 16> Vars;
11092 Vars.reserve(N: C->varlist_size());
11093 for (auto *VE : C->varlist()) {
11094 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11095 if (EVar.isInvalid())
11096 return nullptr;
11097 Vars.push_back(Elt: EVar.get());
11098 }
11099 return getDerived().RebuildOMPFirstprivateClause(
11100 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11101}
11102
11103template <typename Derived>
11104OMPClause *
11105TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11106 llvm::SmallVector<Expr *, 16> Vars;
11107 Vars.reserve(N: C->varlist_size());
11108 for (auto *VE : C->varlist()) {
11109 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11110 if (EVar.isInvalid())
11111 return nullptr;
11112 Vars.push_back(Elt: EVar.get());
11113 }
11114 return getDerived().RebuildOMPLastprivateClause(
11115 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11116 C->getLParenLoc(), C->getEndLoc());
11117}
11118
11119template <typename Derived>
11120OMPClause *
11121TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11122 llvm::SmallVector<Expr *, 16> Vars;
11123 Vars.reserve(N: C->varlist_size());
11124 for (auto *VE : C->varlist()) {
11125 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11126 if (EVar.isInvalid())
11127 return nullptr;
11128 Vars.push_back(Elt: EVar.get());
11129 }
11130 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11131 C->getLParenLoc(), C->getEndLoc());
11132}
11133
11134template <typename Derived>
11135OMPClause *
11136TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11137 llvm::SmallVector<Expr *, 16> Vars;
11138 Vars.reserve(N: C->varlist_size());
11139 for (auto *VE : C->varlist()) {
11140 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11141 if (EVar.isInvalid())
11142 return nullptr;
11143 Vars.push_back(Elt: EVar.get());
11144 }
11145 CXXScopeSpec ReductionIdScopeSpec;
11146 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11147
11148 DeclarationNameInfo NameInfo = C->getNameInfo();
11149 if (NameInfo.getName()) {
11150 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11151 if (!NameInfo.getName())
11152 return nullptr;
11153 }
11154 // Build a list of all UDR decls with the same names ranged by the Scopes.
11155 // The Scope boundary is a duplication of the previous decl.
11156 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11157 for (auto *E : C->reduction_ops()) {
11158 // Transform all the decls.
11159 if (E) {
11160 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11161 UnresolvedSet<8> Decls;
11162 for (auto *D : ULE->decls()) {
11163 NamedDecl *InstD =
11164 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11165 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11166 }
11167 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11168 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11169 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11170 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11171 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11172 } else
11173 UnresolvedReductions.push_back(Elt: nullptr);
11174 }
11175 return getDerived().RebuildOMPReductionClause(
11176 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11177 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11178 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11179}
11180
11181template <typename Derived>
11182OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11183 OMPTaskReductionClause *C) {
11184 llvm::SmallVector<Expr *, 16> Vars;
11185 Vars.reserve(N: C->varlist_size());
11186 for (auto *VE : C->varlist()) {
11187 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11188 if (EVar.isInvalid())
11189 return nullptr;
11190 Vars.push_back(Elt: EVar.get());
11191 }
11192 CXXScopeSpec ReductionIdScopeSpec;
11193 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11194
11195 DeclarationNameInfo NameInfo = C->getNameInfo();
11196 if (NameInfo.getName()) {
11197 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11198 if (!NameInfo.getName())
11199 return nullptr;
11200 }
11201 // Build a list of all UDR decls with the same names ranged by the Scopes.
11202 // The Scope boundary is a duplication of the previous decl.
11203 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11204 for (auto *E : C->reduction_ops()) {
11205 // Transform all the decls.
11206 if (E) {
11207 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11208 UnresolvedSet<8> Decls;
11209 for (auto *D : ULE->decls()) {
11210 NamedDecl *InstD =
11211 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11212 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11213 }
11214 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11215 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11216 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11217 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11218 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11219 } else
11220 UnresolvedReductions.push_back(Elt: nullptr);
11221 }
11222 return getDerived().RebuildOMPTaskReductionClause(
11223 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11224 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11225}
11226
11227template <typename Derived>
11228OMPClause *
11229TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11230 llvm::SmallVector<Expr *, 16> Vars;
11231 Vars.reserve(N: C->varlist_size());
11232 for (auto *VE : C->varlist()) {
11233 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11234 if (EVar.isInvalid())
11235 return nullptr;
11236 Vars.push_back(Elt: EVar.get());
11237 }
11238 CXXScopeSpec ReductionIdScopeSpec;
11239 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11240
11241 DeclarationNameInfo NameInfo = C->getNameInfo();
11242 if (NameInfo.getName()) {
11243 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11244 if (!NameInfo.getName())
11245 return nullptr;
11246 }
11247 // Build a list of all UDR decls with the same names ranged by the Scopes.
11248 // The Scope boundary is a duplication of the previous decl.
11249 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11250 for (auto *E : C->reduction_ops()) {
11251 // Transform all the decls.
11252 if (E) {
11253 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11254 UnresolvedSet<8> Decls;
11255 for (auto *D : ULE->decls()) {
11256 NamedDecl *InstD =
11257 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11258 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11259 }
11260 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11261 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11262 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11263 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11264 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11265 } else
11266 UnresolvedReductions.push_back(Elt: nullptr);
11267 }
11268 return getDerived().RebuildOMPInReductionClause(
11269 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11270 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11271}
11272
11273template <typename Derived>
11274OMPClause *
11275TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11276 llvm::SmallVector<Expr *, 16> Vars;
11277 Vars.reserve(N: C->varlist_size());
11278 for (auto *VE : C->varlist()) {
11279 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11280 if (EVar.isInvalid())
11281 return nullptr;
11282 Vars.push_back(Elt: EVar.get());
11283 }
11284 ExprResult Step = getDerived().TransformExpr(C->getStep());
11285 if (Step.isInvalid())
11286 return nullptr;
11287 return getDerived().RebuildOMPLinearClause(
11288 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11289 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11290 C->getEndLoc());
11291}
11292
11293template <typename Derived>
11294OMPClause *
11295TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11296 llvm::SmallVector<Expr *, 16> Vars;
11297 Vars.reserve(N: C->varlist_size());
11298 for (auto *VE : C->varlist()) {
11299 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11300 if (EVar.isInvalid())
11301 return nullptr;
11302 Vars.push_back(Elt: EVar.get());
11303 }
11304 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11305 if (Alignment.isInvalid())
11306 return nullptr;
11307 return getDerived().RebuildOMPAlignedClause(
11308 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11309 C->getColonLoc(), C->getEndLoc());
11310}
11311
11312template <typename Derived>
11313OMPClause *
11314TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11315 llvm::SmallVector<Expr *, 16> Vars;
11316 Vars.reserve(N: C->varlist_size());
11317 for (auto *VE : C->varlist()) {
11318 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11319 if (EVar.isInvalid())
11320 return nullptr;
11321 Vars.push_back(Elt: EVar.get());
11322 }
11323 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11324 C->getLParenLoc(), C->getEndLoc());
11325}
11326
11327template <typename Derived>
11328OMPClause *
11329TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11330 llvm::SmallVector<Expr *, 16> Vars;
11331 Vars.reserve(N: C->varlist_size());
11332 for (auto *VE : C->varlist()) {
11333 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11334 if (EVar.isInvalid())
11335 return nullptr;
11336 Vars.push_back(Elt: EVar.get());
11337 }
11338 return getDerived().RebuildOMPCopyprivateClause(
11339 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11340}
11341
11342template <typename Derived>
11343OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11344 llvm::SmallVector<Expr *, 16> Vars;
11345 Vars.reserve(N: C->varlist_size());
11346 for (auto *VE : C->varlist()) {
11347 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11348 if (EVar.isInvalid())
11349 return nullptr;
11350 Vars.push_back(Elt: EVar.get());
11351 }
11352 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11353 C->getLParenLoc(), C->getEndLoc());
11354}
11355
11356template <typename Derived>
11357OMPClause *
11358TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11359 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11360 if (E.isInvalid())
11361 return nullptr;
11362 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11363 C->getLParenLoc(), C->getEndLoc());
11364}
11365
11366template <typename Derived>
11367OMPClause *
11368TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11369 llvm::SmallVector<Expr *, 16> Vars;
11370 Expr *DepModifier = C->getModifier();
11371 if (DepModifier) {
11372 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11373 if (DepModRes.isInvalid())
11374 return nullptr;
11375 DepModifier = DepModRes.get();
11376 }
11377 Vars.reserve(N: C->varlist_size());
11378 for (auto *VE : C->varlist()) {
11379 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11380 if (EVar.isInvalid())
11381 return nullptr;
11382 Vars.push_back(Elt: EVar.get());
11383 }
11384 return getDerived().RebuildOMPDependClause(
11385 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11386 C->getOmpAllMemoryLoc()},
11387 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11388}
11389
11390template <typename Derived>
11391OMPClause *
11392TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11393 ExprResult E = getDerived().TransformExpr(C->getDevice());
11394 if (E.isInvalid())
11395 return nullptr;
11396 return getDerived().RebuildOMPDeviceClause(
11397 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11398 C->getModifierLoc(), C->getEndLoc());
11399}
11400
11401template <typename Derived, class T>
11402bool transformOMPMappableExprListClause(
11403 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11404 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11405 DeclarationNameInfo &MapperIdInfo,
11406 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11407 // Transform expressions in the list.
11408 Vars.reserve(N: C->varlist_size());
11409 for (auto *VE : C->varlist()) {
11410 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11411 if (EVar.isInvalid())
11412 return true;
11413 Vars.push_back(Elt: EVar.get());
11414 }
11415 // Transform mapper scope specifier and identifier.
11416 NestedNameSpecifierLoc QualifierLoc;
11417 if (C->getMapperQualifierLoc()) {
11418 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11419 C->getMapperQualifierLoc());
11420 if (!QualifierLoc)
11421 return true;
11422 }
11423 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11424 MapperIdInfo = C->getMapperIdInfo();
11425 if (MapperIdInfo.getName()) {
11426 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11427 if (!MapperIdInfo.getName())
11428 return true;
11429 }
11430 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11431 // the previous user-defined mapper lookup in dependent environment.
11432 for (auto *E : C->mapperlists()) {
11433 // Transform all the decls.
11434 if (E) {
11435 auto *ULE = cast<UnresolvedLookupExpr>(E);
11436 UnresolvedSet<8> Decls;
11437 for (auto *D : ULE->decls()) {
11438 NamedDecl *InstD =
11439 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11440 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11441 }
11442 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11443 TT.getSema().Context, /*NamingClass=*/nullptr,
11444 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11445 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11446 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11447 } else {
11448 UnresolvedMappers.push_back(Elt: nullptr);
11449 }
11450 }
11451 return false;
11452}
11453
11454template <typename Derived>
11455OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11456 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11457 llvm::SmallVector<Expr *, 16> Vars;
11458 Expr *IteratorModifier = C->getIteratorModifier();
11459 if (IteratorModifier) {
11460 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11461 if (MapModRes.isInvalid())
11462 return nullptr;
11463 IteratorModifier = MapModRes.get();
11464 }
11465 CXXScopeSpec MapperIdScopeSpec;
11466 DeclarationNameInfo MapperIdInfo;
11467 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11468 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11469 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11470 return nullptr;
11471 return getDerived().RebuildOMPMapClause(
11472 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11473 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11474 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11475}
11476
11477template <typename Derived>
11478OMPClause *
11479TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11480 Expr *Allocator = C->getAllocator();
11481 if (Allocator) {
11482 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11483 if (AllocatorRes.isInvalid())
11484 return nullptr;
11485 Allocator = AllocatorRes.get();
11486 }
11487 Expr *Alignment = C->getAlignment();
11488 if (Alignment) {
11489 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11490 if (AlignmentRes.isInvalid())
11491 return nullptr;
11492 Alignment = AlignmentRes.get();
11493 }
11494 llvm::SmallVector<Expr *, 16> Vars;
11495 Vars.reserve(N: C->varlist_size());
11496 for (auto *VE : C->varlist()) {
11497 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11498 if (EVar.isInvalid())
11499 return nullptr;
11500 Vars.push_back(Elt: EVar.get());
11501 }
11502 return getDerived().RebuildOMPAllocateClause(
11503 Allocator, Alignment, C->getFirstAllocateModifier(),
11504 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11505 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11506 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11507}
11508
11509template <typename Derived>
11510OMPClause *
11511TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11512 llvm::SmallVector<Expr *, 3> Vars;
11513 Vars.reserve(N: C->varlist_size());
11514 for (auto *VE : C->varlist()) {
11515 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11516 if (EVar.isInvalid())
11517 return nullptr;
11518 Vars.push_back(Elt: EVar.get());
11519 }
11520 return getDerived().RebuildOMPNumTeamsClause(
11521 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11522}
11523
11524template <typename Derived>
11525OMPClause *
11526TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11527 llvm::SmallVector<Expr *, 3> Vars;
11528 Vars.reserve(N: C->varlist_size());
11529 for (auto *VE : C->varlist()) {
11530 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11531 if (EVar.isInvalid())
11532 return nullptr;
11533 Vars.push_back(Elt: EVar.get());
11534 }
11535 return getDerived().RebuildOMPThreadLimitClause(
11536 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11537}
11538
11539template <typename Derived>
11540OMPClause *
11541TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11542 ExprResult E = getDerived().TransformExpr(C->getPriority());
11543 if (E.isInvalid())
11544 return nullptr;
11545 return getDerived().RebuildOMPPriorityClause(
11546 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11547}
11548
11549template <typename Derived>
11550OMPClause *
11551TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11552 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11553 if (E.isInvalid())
11554 return nullptr;
11555 return getDerived().RebuildOMPGrainsizeClause(
11556 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11557 C->getModifierLoc(), C->getEndLoc());
11558}
11559
11560template <typename Derived>
11561OMPClause *
11562TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11563 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11564 if (E.isInvalid())
11565 return nullptr;
11566 return getDerived().RebuildOMPNumTasksClause(
11567 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11568 C->getModifierLoc(), C->getEndLoc());
11569}
11570
11571template <typename Derived>
11572OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11573 ExprResult E = getDerived().TransformExpr(C->getHint());
11574 if (E.isInvalid())
11575 return nullptr;
11576 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11577 C->getLParenLoc(), C->getEndLoc());
11578}
11579
11580template <typename Derived>
11581OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11582 OMPDistScheduleClause *C) {
11583 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11584 if (E.isInvalid())
11585 return nullptr;
11586 return getDerived().RebuildOMPDistScheduleClause(
11587 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11588 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11589}
11590
11591template <typename Derived>
11592OMPClause *
11593TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11594 // Rebuild Defaultmap Clause since we need to invoke the checking of
11595 // defaultmap(none:variable-category) after template initialization.
11596 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11597 C->getDefaultmapKind(),
11598 C->getBeginLoc(),
11599 C->getLParenLoc(),
11600 C->getDefaultmapModifierLoc(),
11601 C->getDefaultmapKindLoc(),
11602 C->getEndLoc());
11603}
11604
11605template <typename Derived>
11606OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11607 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11608 llvm::SmallVector<Expr *, 16> Vars;
11609 Expr *IteratorModifier = C->getIteratorModifier();
11610 if (IteratorModifier) {
11611 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11612 if (MapModRes.isInvalid())
11613 return nullptr;
11614 IteratorModifier = MapModRes.get();
11615 }
11616 CXXScopeSpec MapperIdScopeSpec;
11617 DeclarationNameInfo MapperIdInfo;
11618 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11619 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11620 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11621 return nullptr;
11622 return getDerived().RebuildOMPToClause(
11623 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11624 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11625 UnresolvedMappers);
11626}
11627
11628template <typename Derived>
11629OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11630 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11631 llvm::SmallVector<Expr *, 16> Vars;
11632 Expr *IteratorModifier = C->getIteratorModifier();
11633 if (IteratorModifier) {
11634 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11635 if (MapModRes.isInvalid())
11636 return nullptr;
11637 IteratorModifier = MapModRes.get();
11638 }
11639 CXXScopeSpec MapperIdScopeSpec;
11640 DeclarationNameInfo MapperIdInfo;
11641 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11642 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11643 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11644 return nullptr;
11645 return getDerived().RebuildOMPFromClause(
11646 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11647 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11648 UnresolvedMappers);
11649}
11650
11651template <typename Derived>
11652OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11653 OMPUseDevicePtrClause *C) {
11654 llvm::SmallVector<Expr *, 16> Vars;
11655 Vars.reserve(N: C->varlist_size());
11656 for (auto *VE : C->varlist()) {
11657 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11658 if (EVar.isInvalid())
11659 return nullptr;
11660 Vars.push_back(Elt: EVar.get());
11661 }
11662 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11663 return getDerived().RebuildOMPUseDevicePtrClause(
11664 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
11665}
11666
11667template <typename Derived>
11668OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11669 OMPUseDeviceAddrClause *C) {
11670 llvm::SmallVector<Expr *, 16> Vars;
11671 Vars.reserve(N: C->varlist_size());
11672 for (auto *VE : C->varlist()) {
11673 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11674 if (EVar.isInvalid())
11675 return nullptr;
11676 Vars.push_back(Elt: EVar.get());
11677 }
11678 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11679 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11680}
11681
11682template <typename Derived>
11683OMPClause *
11684TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11685 llvm::SmallVector<Expr *, 16> Vars;
11686 Vars.reserve(N: C->varlist_size());
11687 for (auto *VE : C->varlist()) {
11688 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11689 if (EVar.isInvalid())
11690 return nullptr;
11691 Vars.push_back(Elt: EVar.get());
11692 }
11693 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11694 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11695}
11696
11697template <typename Derived>
11698OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11699 OMPHasDeviceAddrClause *C) {
11700 llvm::SmallVector<Expr *, 16> Vars;
11701 Vars.reserve(N: C->varlist_size());
11702 for (auto *VE : C->varlist()) {
11703 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11704 if (EVar.isInvalid())
11705 return nullptr;
11706 Vars.push_back(Elt: EVar.get());
11707 }
11708 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11709 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11710}
11711
11712template <typename Derived>
11713OMPClause *
11714TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11715 llvm::SmallVector<Expr *, 16> Vars;
11716 Vars.reserve(N: C->varlist_size());
11717 for (auto *VE : C->varlist()) {
11718 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11719 if (EVar.isInvalid())
11720 return nullptr;
11721 Vars.push_back(Elt: EVar.get());
11722 }
11723 return getDerived().RebuildOMPNontemporalClause(
11724 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11725}
11726
11727template <typename Derived>
11728OMPClause *
11729TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11730 llvm::SmallVector<Expr *, 16> Vars;
11731 Vars.reserve(N: C->varlist_size());
11732 for (auto *VE : C->varlist()) {
11733 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11734 if (EVar.isInvalid())
11735 return nullptr;
11736 Vars.push_back(Elt: EVar.get());
11737 }
11738 return getDerived().RebuildOMPInclusiveClause(
11739 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11740}
11741
11742template <typename Derived>
11743OMPClause *
11744TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11745 llvm::SmallVector<Expr *, 16> Vars;
11746 Vars.reserve(N: C->varlist_size());
11747 for (auto *VE : C->varlist()) {
11748 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11749 if (EVar.isInvalid())
11750 return nullptr;
11751 Vars.push_back(Elt: EVar.get());
11752 }
11753 return getDerived().RebuildOMPExclusiveClause(
11754 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11755}
11756
11757template <typename Derived>
11758OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11759 OMPUsesAllocatorsClause *C) {
11760 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11761 Data.reserve(N: C->getNumberOfAllocators());
11762 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11763 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11764 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11765 if (Allocator.isInvalid())
11766 continue;
11767 ExprResult AllocatorTraits;
11768 if (Expr *AT = D.AllocatorTraits) {
11769 AllocatorTraits = getDerived().TransformExpr(AT);
11770 if (AllocatorTraits.isInvalid())
11771 continue;
11772 }
11773 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11774 NewD.Allocator = Allocator.get();
11775 NewD.AllocatorTraits = AllocatorTraits.get();
11776 NewD.LParenLoc = D.LParenLoc;
11777 NewD.RParenLoc = D.RParenLoc;
11778 }
11779 return getDerived().RebuildOMPUsesAllocatorsClause(
11780 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11781}
11782
11783template <typename Derived>
11784OMPClause *
11785TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11786 SmallVector<Expr *, 4> Locators;
11787 Locators.reserve(N: C->varlist_size());
11788 ExprResult ModifierRes;
11789 if (Expr *Modifier = C->getModifier()) {
11790 ModifierRes = getDerived().TransformExpr(Modifier);
11791 if (ModifierRes.isInvalid())
11792 return nullptr;
11793 }
11794 for (Expr *E : C->varlist()) {
11795 ExprResult Locator = getDerived().TransformExpr(E);
11796 if (Locator.isInvalid())
11797 continue;
11798 Locators.push_back(Elt: Locator.get());
11799 }
11800 return getDerived().RebuildOMPAffinityClause(
11801 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11802 ModifierRes.get(), Locators);
11803}
11804
11805template <typename Derived>
11806OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11807 return getDerived().RebuildOMPOrderClause(
11808 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11809 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11810}
11811
11812template <typename Derived>
11813OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11814 return getDerived().RebuildOMPBindClause(
11815 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11816 C->getLParenLoc(), C->getEndLoc());
11817}
11818
11819template <typename Derived>
11820OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11821 OMPXDynCGroupMemClause *C) {
11822 ExprResult Size = getDerived().TransformExpr(C->getSize());
11823 if (Size.isInvalid())
11824 return nullptr;
11825 return getDerived().RebuildOMPXDynCGroupMemClause(
11826 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11827}
11828
11829template <typename Derived>
11830OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
11831 OMPDynGroupprivateClause *C) {
11832 ExprResult Size = getDerived().TransformExpr(C->getSize());
11833 if (Size.isInvalid())
11834 return nullptr;
11835 return getDerived().RebuildOMPDynGroupprivateClause(
11836 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
11837 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
11838 C->getDynGroupprivateModifierLoc(),
11839 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
11840}
11841
11842template <typename Derived>
11843OMPClause *
11844TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11845 llvm::SmallVector<Expr *, 16> Vars;
11846 Vars.reserve(N: C->varlist_size());
11847 for (auto *VE : C->varlist()) {
11848 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11849 if (EVar.isInvalid())
11850 return nullptr;
11851 Vars.push_back(Elt: EVar.get());
11852 }
11853 return getDerived().RebuildOMPDoacrossClause(
11854 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11855 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11856}
11857
11858template <typename Derived>
11859OMPClause *
11860TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11861 SmallVector<const Attr *> NewAttrs;
11862 for (auto *A : C->getAttrs())
11863 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11864 return getDerived().RebuildOMPXAttributeClause(
11865 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11866}
11867
11868template <typename Derived>
11869OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11870 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11871}
11872
11873//===----------------------------------------------------------------------===//
11874// OpenACC transformation
11875//===----------------------------------------------------------------------===//
11876namespace {
11877template <typename Derived>
11878class OpenACCClauseTransform final
11879 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11880 TreeTransform<Derived> &Self;
11881 ArrayRef<const OpenACCClause *> ExistingClauses;
11882 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11883 OpenACCClause *NewClause = nullptr;
11884
11885 ExprResult VisitVar(Expr *VarRef) {
11886 ExprResult Res = Self.TransformExpr(VarRef);
11887
11888 if (!Res.isUsable())
11889 return Res;
11890
11891 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11892 ParsedClause.getClauseKind(),
11893 Res.get());
11894
11895 return Res;
11896 }
11897
11898 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11899 llvm::SmallVector<Expr *> InstantiatedVarList;
11900 for (Expr *CurVar : VarList) {
11901 ExprResult VarRef = VisitVar(VarRef: CurVar);
11902
11903 if (VarRef.isUsable())
11904 InstantiatedVarList.push_back(Elt: VarRef.get());
11905 }
11906
11907 return InstantiatedVarList;
11908 }
11909
11910public:
11911 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11912 ArrayRef<const OpenACCClause *> ExistingClauses,
11913 SemaOpenACC::OpenACCParsedClause &PC)
11914 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11915
11916 OpenACCClause *CreatedClause() const { return NewClause; }
11917
11918#define VISIT_CLAUSE(CLAUSE_NAME) \
11919 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11920#include "clang/Basic/OpenACCClauses.def"
11921};
11922
11923template <typename Derived>
11924void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11925 const OpenACCDefaultClause &C) {
11926 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11927
11928 NewClause = OpenACCDefaultClause::Create(
11929 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11930 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11931 EndLoc: ParsedClause.getEndLoc());
11932}
11933
11934template <typename Derived>
11935void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11936 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11937 assert(Cond && "If constructed with invalid Condition");
11938 Sema::ConditionResult Res = Self.TransformCondition(
11939 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11940
11941 if (Res.isInvalid() || !Res.get().second)
11942 return;
11943
11944 ParsedClause.setConditionDetails(Res.get().second);
11945
11946 NewClause = OpenACCIfClause::Create(
11947 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11948 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11949 EndLoc: ParsedClause.getEndLoc());
11950}
11951
11952template <typename Derived>
11953void OpenACCClauseTransform<Derived>::VisitSelfClause(
11954 const OpenACCSelfClause &C) {
11955
11956 // If this is an 'update' 'self' clause, this is actually a var list instead.
11957 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11958 llvm::SmallVector<Expr *> InstantiatedVarList;
11959 for (Expr *CurVar : C.getVarList()) {
11960 ExprResult Res = Self.TransformExpr(CurVar);
11961
11962 if (!Res.isUsable())
11963 continue;
11964
11965 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11966 ParsedClause.getClauseKind(),
11967 Res.get());
11968
11969 if (Res.isUsable())
11970 InstantiatedVarList.push_back(Elt: Res.get());
11971 }
11972
11973 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
11974 ModKind: OpenACCModifierKind::Invalid);
11975
11976 NewClause = OpenACCSelfClause::Create(
11977 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11978 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11979 ParsedClause.getEndLoc());
11980 } else {
11981
11982 if (C.hasConditionExpr()) {
11983 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11984 Sema::ConditionResult Res =
11985 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11986 Sema::ConditionKind::Boolean);
11987
11988 if (Res.isInvalid() || !Res.get().second)
11989 return;
11990
11991 ParsedClause.setConditionDetails(Res.get().second);
11992 }
11993
11994 NewClause = OpenACCSelfClause::Create(
11995 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11996 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11997 ParsedClause.getEndLoc());
11998 }
11999}
12000
12001template <typename Derived>
12002void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12003 const OpenACCNumGangsClause &C) {
12004 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12005
12006 for (Expr *CurIntExpr : C.getIntExprs()) {
12007 ExprResult Res = Self.TransformExpr(CurIntExpr);
12008
12009 if (!Res.isUsable())
12010 return;
12011
12012 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12013 C.getClauseKind(),
12014 C.getBeginLoc(), Res.get());
12015 if (!Res.isUsable())
12016 return;
12017
12018 InstantiatedIntExprs.push_back(Elt: Res.get());
12019 }
12020
12021 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12022 NewClause = OpenACCNumGangsClause::Create(
12023 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12024 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12025 EndLoc: ParsedClause.getEndLoc());
12026}
12027
12028template <typename Derived>
12029void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12030 const OpenACCPrivateClause &C) {
12031 llvm::SmallVector<Expr *> InstantiatedVarList;
12032 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12033
12034 for (const auto [RefExpr, InitRecipe] :
12035 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12036 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12037
12038 if (VarRef.isUsable()) {
12039 InstantiatedVarList.push_back(Elt: VarRef.get());
12040
12041 // We only have to create a new one if it is dependent, and Sema won't
12042 // make one of these unless the type is non-dependent.
12043 if (InitRecipe.isSet())
12044 InitRecipes.push_back(Elt: InitRecipe);
12045 else
12046 InitRecipes.push_back(
12047 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12048 }
12049 }
12050 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12051 ModKind: OpenACCModifierKind::Invalid);
12052
12053 NewClause = OpenACCPrivateClause::Create(
12054 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12055 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12056 EndLoc: ParsedClause.getEndLoc());
12057}
12058
12059template <typename Derived>
12060void OpenACCClauseTransform<Derived>::VisitHostClause(
12061 const OpenACCHostClause &C) {
12062 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12063 OpenACCModifierKind::Invalid);
12064
12065 NewClause = OpenACCHostClause::Create(
12066 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12067 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12068 EndLoc: ParsedClause.getEndLoc());
12069}
12070
12071template <typename Derived>
12072void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12073 const OpenACCDeviceClause &C) {
12074 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12075 OpenACCModifierKind::Invalid);
12076
12077 NewClause = OpenACCDeviceClause::Create(
12078 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12079 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12080 EndLoc: ParsedClause.getEndLoc());
12081}
12082
12083template <typename Derived>
12084void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12085 const OpenACCFirstPrivateClause &C) {
12086 llvm::SmallVector<Expr *> InstantiatedVarList;
12087 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12088
12089 for (const auto [RefExpr, InitRecipe] :
12090 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12091 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12092
12093 if (VarRef.isUsable()) {
12094 InstantiatedVarList.push_back(Elt: VarRef.get());
12095
12096 // We only have to create a new one if it is dependent, and Sema won't
12097 // make one of these unless the type is non-dependent.
12098 if (InitRecipe.isSet())
12099 InitRecipes.push_back(Elt: InitRecipe);
12100 else
12101 InitRecipes.push_back(
12102 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12103 VarRef.get()));
12104 }
12105 }
12106 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12107 ModKind: OpenACCModifierKind::Invalid);
12108
12109 NewClause = OpenACCFirstPrivateClause::Create(
12110 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12111 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12112 EndLoc: ParsedClause.getEndLoc());
12113}
12114
12115template <typename Derived>
12116void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12117 const OpenACCNoCreateClause &C) {
12118 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12119 OpenACCModifierKind::Invalid);
12120
12121 NewClause = OpenACCNoCreateClause::Create(
12122 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12123 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12124 EndLoc: ParsedClause.getEndLoc());
12125}
12126
12127template <typename Derived>
12128void OpenACCClauseTransform<Derived>::VisitPresentClause(
12129 const OpenACCPresentClause &C) {
12130 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12131 OpenACCModifierKind::Invalid);
12132
12133 NewClause = OpenACCPresentClause::Create(
12134 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12135 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12136 EndLoc: ParsedClause.getEndLoc());
12137}
12138
12139template <typename Derived>
12140void OpenACCClauseTransform<Derived>::VisitCopyClause(
12141 const OpenACCCopyClause &C) {
12142 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12143 C.getModifierList());
12144
12145 NewClause = OpenACCCopyClause::Create(
12146 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12147 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12148 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12149 EndLoc: ParsedClause.getEndLoc());
12150}
12151
12152template <typename Derived>
12153void OpenACCClauseTransform<Derived>::VisitLinkClause(
12154 const OpenACCLinkClause &C) {
12155 llvm_unreachable("link clause not valid unless a decl transform");
12156}
12157
12158template <typename Derived>
12159void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12160 const OpenACCDeviceResidentClause &C) {
12161 llvm_unreachable("device_resident clause not valid unless a decl transform");
12162}
12163template <typename Derived>
12164void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12165 const OpenACCNoHostClause &C) {
12166 llvm_unreachable("nohost clause not valid unless a decl transform");
12167}
12168template <typename Derived>
12169void OpenACCClauseTransform<Derived>::VisitBindClause(
12170 const OpenACCBindClause &C) {
12171 llvm_unreachable("bind clause not valid unless a decl transform");
12172}
12173
12174template <typename Derived>
12175void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12176 const OpenACCCopyInClause &C) {
12177 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12178 C.getModifierList());
12179
12180 NewClause = OpenACCCopyInClause::Create(
12181 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12182 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12183 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12184 EndLoc: ParsedClause.getEndLoc());
12185}
12186
12187template <typename Derived>
12188void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12189 const OpenACCCopyOutClause &C) {
12190 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12191 C.getModifierList());
12192
12193 NewClause = OpenACCCopyOutClause::Create(
12194 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12195 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12196 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12197 EndLoc: ParsedClause.getEndLoc());
12198}
12199
12200template <typename Derived>
12201void OpenACCClauseTransform<Derived>::VisitCreateClause(
12202 const OpenACCCreateClause &C) {
12203 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12204 C.getModifierList());
12205
12206 NewClause = OpenACCCreateClause::Create(
12207 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12208 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12209 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12210 EndLoc: ParsedClause.getEndLoc());
12211}
12212template <typename Derived>
12213void OpenACCClauseTransform<Derived>::VisitAttachClause(
12214 const OpenACCAttachClause &C) {
12215 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12216
12217 // Ensure each var is a pointer type.
12218 llvm::erase_if(VarList, [&](Expr *E) {
12219 return Self.getSema().OpenACC().CheckVarIsPointerType(
12220 OpenACCClauseKind::Attach, E);
12221 });
12222
12223 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12224 NewClause = OpenACCAttachClause::Create(
12225 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12226 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12227 EndLoc: ParsedClause.getEndLoc());
12228}
12229
12230template <typename Derived>
12231void OpenACCClauseTransform<Derived>::VisitDetachClause(
12232 const OpenACCDetachClause &C) {
12233 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12234
12235 // Ensure each var is a pointer type.
12236 llvm::erase_if(VarList, [&](Expr *E) {
12237 return Self.getSema().OpenACC().CheckVarIsPointerType(
12238 OpenACCClauseKind::Detach, E);
12239 });
12240
12241 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12242 NewClause = OpenACCDetachClause::Create(
12243 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12244 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12245 EndLoc: ParsedClause.getEndLoc());
12246}
12247
12248template <typename Derived>
12249void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12250 const OpenACCDeleteClause &C) {
12251 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12252 OpenACCModifierKind::Invalid);
12253 NewClause = OpenACCDeleteClause::Create(
12254 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12255 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12256 EndLoc: ParsedClause.getEndLoc());
12257}
12258
12259template <typename Derived>
12260void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12261 const OpenACCUseDeviceClause &C) {
12262 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12263 OpenACCModifierKind::Invalid);
12264 NewClause = OpenACCUseDeviceClause::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>::VisitDevicePtrClause(
12272 const OpenACCDevicePtrClause &C) {
12273 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12274
12275 // Ensure each var is a pointer type.
12276 llvm::erase_if(VarList, [&](Expr *E) {
12277 return Self.getSema().OpenACC().CheckVarIsPointerType(
12278 OpenACCClauseKind::DevicePtr, E);
12279 });
12280
12281 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12282 NewClause = OpenACCDevicePtrClause::Create(
12283 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12284 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12285 EndLoc: ParsedClause.getEndLoc());
12286}
12287
12288template <typename Derived>
12289void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12290 const OpenACCNumWorkersClause &C) {
12291 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12292 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12293
12294 ExprResult Res = Self.TransformExpr(IntExpr);
12295 if (!Res.isUsable())
12296 return;
12297
12298 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12299 C.getClauseKind(),
12300 C.getBeginLoc(), Res.get());
12301 if (!Res.isUsable())
12302 return;
12303
12304 ParsedClause.setIntExprDetails(Res.get());
12305 NewClause = OpenACCNumWorkersClause::Create(
12306 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12307 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12308 EndLoc: ParsedClause.getEndLoc());
12309}
12310
12311template <typename Derived>
12312void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12313 const OpenACCDeviceNumClause &C) {
12314 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12315 assert(IntExpr && "device_num clause constructed with invalid int expr");
12316
12317 ExprResult Res = Self.TransformExpr(IntExpr);
12318 if (!Res.isUsable())
12319 return;
12320
12321 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12322 C.getClauseKind(),
12323 C.getBeginLoc(), Res.get());
12324 if (!Res.isUsable())
12325 return;
12326
12327 ParsedClause.setIntExprDetails(Res.get());
12328 NewClause = OpenACCDeviceNumClause::Create(
12329 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12330 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12331 EndLoc: ParsedClause.getEndLoc());
12332}
12333
12334template <typename Derived>
12335void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12336 const OpenACCDefaultAsyncClause &C) {
12337 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12338 assert(IntExpr && "default_async clause constructed with invalid int expr");
12339
12340 ExprResult Res = Self.TransformExpr(IntExpr);
12341 if (!Res.isUsable())
12342 return;
12343
12344 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12345 C.getClauseKind(),
12346 C.getBeginLoc(), Res.get());
12347 if (!Res.isUsable())
12348 return;
12349
12350 ParsedClause.setIntExprDetails(Res.get());
12351 NewClause = OpenACCDefaultAsyncClause::Create(
12352 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12353 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12354 EndLoc: ParsedClause.getEndLoc());
12355}
12356
12357template <typename Derived>
12358void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12359 const OpenACCVectorLengthClause &C) {
12360 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12361 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12362
12363 ExprResult Res = Self.TransformExpr(IntExpr);
12364 if (!Res.isUsable())
12365 return;
12366
12367 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12368 C.getClauseKind(),
12369 C.getBeginLoc(), Res.get());
12370 if (!Res.isUsable())
12371 return;
12372
12373 ParsedClause.setIntExprDetails(Res.get());
12374 NewClause = OpenACCVectorLengthClause::Create(
12375 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12376 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12377 EndLoc: ParsedClause.getEndLoc());
12378}
12379
12380template <typename Derived>
12381void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12382 const OpenACCAsyncClause &C) {
12383 if (C.hasIntExpr()) {
12384 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12385 if (!Res.isUsable())
12386 return;
12387
12388 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12389 C.getClauseKind(),
12390 C.getBeginLoc(), Res.get());
12391 if (!Res.isUsable())
12392 return;
12393 ParsedClause.setIntExprDetails(Res.get());
12394 }
12395
12396 NewClause = OpenACCAsyncClause::Create(
12397 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12398 LParenLoc: ParsedClause.getLParenLoc(),
12399 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12400 : nullptr,
12401 EndLoc: ParsedClause.getEndLoc());
12402}
12403
12404template <typename Derived>
12405void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12406 const OpenACCWorkerClause &C) {
12407 if (C.hasIntExpr()) {
12408 // restrictions on this expression are all "does it exist in certain
12409 // situations" that are not possible to be dependent, so the only check we
12410 // have is that it transforms, and is an int expression.
12411 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12412 if (!Res.isUsable())
12413 return;
12414
12415 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12416 C.getClauseKind(),
12417 C.getBeginLoc(), Res.get());
12418 if (!Res.isUsable())
12419 return;
12420 ParsedClause.setIntExprDetails(Res.get());
12421 }
12422
12423 NewClause = OpenACCWorkerClause::Create(
12424 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12425 LParenLoc: ParsedClause.getLParenLoc(),
12426 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12427 : nullptr,
12428 EndLoc: ParsedClause.getEndLoc());
12429}
12430
12431template <typename Derived>
12432void OpenACCClauseTransform<Derived>::VisitVectorClause(
12433 const OpenACCVectorClause &C) {
12434 if (C.hasIntExpr()) {
12435 // restrictions on this expression are all "does it exist in certain
12436 // situations" that are not possible to be dependent, so the only check we
12437 // have is that it transforms, and is an int expression.
12438 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12439 if (!Res.isUsable())
12440 return;
12441
12442 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12443 C.getClauseKind(),
12444 C.getBeginLoc(), Res.get());
12445 if (!Res.isUsable())
12446 return;
12447 ParsedClause.setIntExprDetails(Res.get());
12448 }
12449
12450 NewClause = OpenACCVectorClause::Create(
12451 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12452 LParenLoc: ParsedClause.getLParenLoc(),
12453 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12454 : nullptr,
12455 EndLoc: ParsedClause.getEndLoc());
12456}
12457
12458template <typename Derived>
12459void OpenACCClauseTransform<Derived>::VisitWaitClause(
12460 const OpenACCWaitClause &C) {
12461 if (C.hasExprs()) {
12462 Expr *DevNumExpr = nullptr;
12463 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12464
12465 // Instantiate devnum expr if it exists.
12466 if (C.getDevNumExpr()) {
12467 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12468 if (!Res.isUsable())
12469 return;
12470 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12471 C.getClauseKind(),
12472 C.getBeginLoc(), Res.get());
12473 if (!Res.isUsable())
12474 return;
12475
12476 DevNumExpr = Res.get();
12477 }
12478
12479 // Instantiate queue ids.
12480 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12481 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12482 if (!Res.isUsable())
12483 return;
12484 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12485 C.getClauseKind(),
12486 C.getBeginLoc(), Res.get());
12487 if (!Res.isUsable())
12488 return;
12489
12490 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12491 }
12492
12493 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12494 IntExprs: std::move(InstantiatedQueueIdExprs));
12495 }
12496
12497 NewClause = OpenACCWaitClause::Create(
12498 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12499 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12500 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12501 EndLoc: ParsedClause.getEndLoc());
12502}
12503
12504template <typename Derived>
12505void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12506 const OpenACCDeviceTypeClause &C) {
12507 // Nothing to transform here, just create a new version of 'C'.
12508 NewClause = OpenACCDeviceTypeClause::Create(
12509 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12510 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12511 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12512}
12513
12514template <typename Derived>
12515void OpenACCClauseTransform<Derived>::VisitAutoClause(
12516 const OpenACCAutoClause &C) {
12517 // Nothing to do, so just create a new node.
12518 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12519 BeginLoc: ParsedClause.getBeginLoc(),
12520 EndLoc: ParsedClause.getEndLoc());
12521}
12522
12523template <typename Derived>
12524void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12525 const OpenACCIndependentClause &C) {
12526 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12527 BeginLoc: ParsedClause.getBeginLoc(),
12528 EndLoc: ParsedClause.getEndLoc());
12529}
12530
12531template <typename Derived>
12532void OpenACCClauseTransform<Derived>::VisitSeqClause(
12533 const OpenACCSeqClause &C) {
12534 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12535 BeginLoc: ParsedClause.getBeginLoc(),
12536 EndLoc: ParsedClause.getEndLoc());
12537}
12538template <typename Derived>
12539void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12540 const OpenACCFinalizeClause &C) {
12541 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12542 BeginLoc: ParsedClause.getBeginLoc(),
12543 EndLoc: ParsedClause.getEndLoc());
12544}
12545
12546template <typename Derived>
12547void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12548 const OpenACCIfPresentClause &C) {
12549 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12550 BeginLoc: ParsedClause.getBeginLoc(),
12551 EndLoc: ParsedClause.getEndLoc());
12552}
12553
12554template <typename Derived>
12555void OpenACCClauseTransform<Derived>::VisitReductionClause(
12556 const OpenACCReductionClause &C) {
12557 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12558 SmallVector<Expr *> ValidVars;
12559 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
12560
12561 for (const auto [Var, OrigRecipe] :
12562 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
12563 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12564 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12565 if (Res.isUsable()) {
12566 ValidVars.push_back(Elt: Res.get());
12567
12568 if (OrigRecipe.isSet())
12569 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
12570 else
12571 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
12572 C.getReductionOp(), Res.get()));
12573 }
12574 }
12575
12576 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12577 ExistingClauses, ParsedClause.getDirectiveKind(),
12578 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12579 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
12580}
12581
12582template <typename Derived>
12583void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12584 const OpenACCCollapseClause &C) {
12585 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12586 assert(LoopCount && "collapse clause constructed with invalid loop count");
12587
12588 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12589
12590 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12591 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12592 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12593
12594 NewLoopCount =
12595 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12596
12597 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12598 NewClause = OpenACCCollapseClause::Create(
12599 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12600 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12601 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12602}
12603
12604template <typename Derived>
12605void OpenACCClauseTransform<Derived>::VisitTileClause(
12606 const OpenACCTileClause &C) {
12607
12608 llvm::SmallVector<Expr *> TransformedExprs;
12609
12610 for (Expr *E : C.getSizeExprs()) {
12611 ExprResult NewSizeExpr = Self.TransformExpr(E);
12612
12613 if (!NewSizeExpr.isUsable())
12614 return;
12615
12616 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12617 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12618 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12619
12620 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12621
12622 if (!NewSizeExpr.isUsable())
12623 return;
12624 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12625 }
12626
12627 ParsedClause.setIntExprDetails(TransformedExprs);
12628 NewClause = OpenACCTileClause::Create(
12629 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12630 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12631 EndLoc: ParsedClause.getEndLoc());
12632}
12633template <typename Derived>
12634void OpenACCClauseTransform<Derived>::VisitGangClause(
12635 const OpenACCGangClause &C) {
12636 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12637 llvm::SmallVector<Expr *> TransformedIntExprs;
12638
12639 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12640 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12641 if (!ER.isUsable())
12642 continue;
12643
12644 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12645 ParsedClause.getDirectiveKind(),
12646 C.getExpr(I).first, ER.get());
12647 if (!ER.isUsable())
12648 continue;
12649 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12650 TransformedIntExprs.push_back(Elt: ER.get());
12651 }
12652
12653 NewClause = Self.getSema().OpenACC().CheckGangClause(
12654 ParsedClause.getDirectiveKind(), ExistingClauses,
12655 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12656 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12657}
12658} // namespace
12659template <typename Derived>
12660OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12661 ArrayRef<const OpenACCClause *> ExistingClauses,
12662 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12663
12664 SemaOpenACC::OpenACCParsedClause ParsedClause(
12665 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12666 ParsedClause.setEndLoc(OldClause->getEndLoc());
12667
12668 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12669 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12670
12671 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12672 ParsedClause};
12673 Transform.Visit(OldClause);
12674
12675 return Transform.CreatedClause();
12676}
12677
12678template <typename Derived>
12679llvm::SmallVector<OpenACCClause *>
12680TreeTransform<Derived>::TransformOpenACCClauseList(
12681 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12682 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12683 for (const auto *Clause : OldClauses) {
12684 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12685 TransformedClauses, DirKind, Clause))
12686 TransformedClauses.push_back(Elt: TransformedClause);
12687 }
12688 return TransformedClauses;
12689}
12690
12691template <typename Derived>
12692StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12693 OpenACCComputeConstruct *C) {
12694 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12695
12696 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12697 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12698 C->clauses());
12699
12700 if (getSema().OpenACC().ActOnStartStmtDirective(
12701 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12702 return StmtError();
12703
12704 // Transform Structured Block.
12705 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12706 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12707 C->clauses(), TransformedClauses);
12708 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12709 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12710 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12711
12712 return getDerived().RebuildOpenACCComputeConstruct(
12713 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12714 C->getEndLoc(), TransformedClauses, StrBlock);
12715}
12716
12717template <typename Derived>
12718StmtResult
12719TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12720
12721 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12722
12723 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12724 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12725 C->clauses());
12726
12727 if (getSema().OpenACC().ActOnStartStmtDirective(
12728 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12729 return StmtError();
12730
12731 // Transform Loop.
12732 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12733 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12734 C->clauses(), TransformedClauses);
12735 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12736 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12737 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12738
12739 return getDerived().RebuildOpenACCLoopConstruct(
12740 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12741 TransformedClauses, Loop);
12742}
12743
12744template <typename Derived>
12745StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12746 OpenACCCombinedConstruct *C) {
12747 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12748
12749 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12750 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12751 C->clauses());
12752
12753 if (getSema().OpenACC().ActOnStartStmtDirective(
12754 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12755 return StmtError();
12756
12757 // Transform Loop.
12758 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12759 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12760 C->clauses(), TransformedClauses);
12761 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12762 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12763 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12764
12765 return getDerived().RebuildOpenACCCombinedConstruct(
12766 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12767 C->getEndLoc(), TransformedClauses, Loop);
12768}
12769
12770template <typename Derived>
12771StmtResult
12772TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12773 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12774
12775 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12776 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12777 C->clauses());
12778 if (getSema().OpenACC().ActOnStartStmtDirective(
12779 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12780 return StmtError();
12781
12782 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12783 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12784 C->clauses(), TransformedClauses);
12785 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12786 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12787 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12788
12789 return getDerived().RebuildOpenACCDataConstruct(
12790 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12791 TransformedClauses, StrBlock);
12792}
12793
12794template <typename Derived>
12795StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12796 OpenACCEnterDataConstruct *C) {
12797 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12798
12799 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12800 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12801 C->clauses());
12802 if (getSema().OpenACC().ActOnStartStmtDirective(
12803 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12804 return StmtError();
12805
12806 return getDerived().RebuildOpenACCEnterDataConstruct(
12807 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12808 TransformedClauses);
12809}
12810
12811template <typename Derived>
12812StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12813 OpenACCExitDataConstruct *C) {
12814 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12815
12816 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12817 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12818 C->clauses());
12819 if (getSema().OpenACC().ActOnStartStmtDirective(
12820 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12821 return StmtError();
12822
12823 return getDerived().RebuildOpenACCExitDataConstruct(
12824 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12825 TransformedClauses);
12826}
12827
12828template <typename Derived>
12829StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12830 OpenACCHostDataConstruct *C) {
12831 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12832
12833 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12834 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12835 C->clauses());
12836 if (getSema().OpenACC().ActOnStartStmtDirective(
12837 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12838 return StmtError();
12839
12840 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12841 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12842 C->clauses(), TransformedClauses);
12843 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12844 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12845 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12846
12847 return getDerived().RebuildOpenACCHostDataConstruct(
12848 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12849 TransformedClauses, StrBlock);
12850}
12851
12852template <typename Derived>
12853StmtResult
12854TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12855 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12856
12857 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12858 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12859 C->clauses());
12860 if (getSema().OpenACC().ActOnStartStmtDirective(
12861 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12862 return StmtError();
12863
12864 return getDerived().RebuildOpenACCInitConstruct(
12865 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12866 TransformedClauses);
12867}
12868
12869template <typename Derived>
12870StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12871 OpenACCShutdownConstruct *C) {
12872 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12873
12874 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12875 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12876 C->clauses());
12877 if (getSema().OpenACC().ActOnStartStmtDirective(
12878 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12879 return StmtError();
12880
12881 return getDerived().RebuildOpenACCShutdownConstruct(
12882 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12883 TransformedClauses);
12884}
12885template <typename Derived>
12886StmtResult
12887TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12888 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12889
12890 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12891 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12892 C->clauses());
12893 if (getSema().OpenACC().ActOnStartStmtDirective(
12894 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12895 return StmtError();
12896
12897 return getDerived().RebuildOpenACCSetConstruct(
12898 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12899 TransformedClauses);
12900}
12901
12902template <typename Derived>
12903StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12904 OpenACCUpdateConstruct *C) {
12905 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12906
12907 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12908 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12909 C->clauses());
12910 if (getSema().OpenACC().ActOnStartStmtDirective(
12911 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12912 return StmtError();
12913
12914 return getDerived().RebuildOpenACCUpdateConstruct(
12915 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12916 TransformedClauses);
12917}
12918
12919template <typename Derived>
12920StmtResult
12921TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12922 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12923
12924 ExprResult DevNumExpr;
12925 if (C->hasDevNumExpr()) {
12926 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12927
12928 if (DevNumExpr.isUsable())
12929 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12930 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12931 C->getBeginLoc(), DevNumExpr.get());
12932 }
12933
12934 llvm::SmallVector<Expr *> QueueIdExprs;
12935
12936 for (Expr *QE : C->getQueueIdExprs()) {
12937 assert(QE && "Null queue id expr?");
12938 ExprResult NewEQ = getDerived().TransformExpr(QE);
12939
12940 if (!NewEQ.isUsable())
12941 break;
12942 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12943 OpenACCClauseKind::Invalid,
12944 C->getBeginLoc(), NewEQ.get());
12945 if (NewEQ.isUsable())
12946 QueueIdExprs.push_back(Elt: NewEQ.get());
12947 }
12948
12949 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12950 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12951 C->clauses());
12952
12953 if (getSema().OpenACC().ActOnStartStmtDirective(
12954 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12955 return StmtError();
12956
12957 return getDerived().RebuildOpenACCWaitConstruct(
12958 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12959 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12960 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12961}
12962template <typename Derived>
12963StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12964 OpenACCCacheConstruct *C) {
12965 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12966
12967 llvm::SmallVector<Expr *> TransformedVarList;
12968 for (Expr *Var : C->getVarList()) {
12969 assert(Var && "Null var listexpr?");
12970
12971 ExprResult NewVar = getDerived().TransformExpr(Var);
12972
12973 if (!NewVar.isUsable())
12974 break;
12975
12976 NewVar = getSema().OpenACC().ActOnVar(
12977 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12978 if (!NewVar.isUsable())
12979 break;
12980
12981 TransformedVarList.push_back(Elt: NewVar.get());
12982 }
12983
12984 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12985 C->getBeginLoc(), {}))
12986 return StmtError();
12987
12988 return getDerived().RebuildOpenACCCacheConstruct(
12989 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12990 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
12991 C->getEndLoc());
12992}
12993
12994template <typename Derived>
12995StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
12996 OpenACCAtomicConstruct *C) {
12997 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12998
12999 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13000 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13001 C->clauses());
13002
13003 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13004 C->getBeginLoc(), {}))
13005 return StmtError();
13006
13007 // Transform Associated Stmt.
13008 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13009 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13010
13011 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13012 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13013 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13014 AssocStmt);
13015
13016 return getDerived().RebuildOpenACCAtomicConstruct(
13017 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13018 C->getEndLoc(), TransformedClauses, AssocStmt);
13019}
13020
13021template <typename Derived>
13022ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13023 OpenACCAsteriskSizeExpr *E) {
13024 if (getDerived().AlwaysRebuild())
13025 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13026 // Nothing can ever change, so there is never anything to transform.
13027 return E;
13028}
13029
13030//===----------------------------------------------------------------------===//
13031// Expression transformation
13032//===----------------------------------------------------------------------===//
13033template<typename Derived>
13034ExprResult
13035TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13036 return TransformExpr(E: E->getSubExpr());
13037}
13038
13039template <typename Derived>
13040ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13041 SYCLUniqueStableNameExpr *E) {
13042 if (!E->isTypeDependent())
13043 return E;
13044
13045 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13046
13047 if (!NewT)
13048 return ExprError();
13049
13050 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13051 return E;
13052
13053 return getDerived().RebuildSYCLUniqueStableNameExpr(
13054 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13055}
13056
13057template<typename Derived>
13058ExprResult
13059TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13060 if (!E->isTypeDependent())
13061 return E;
13062
13063 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13064 E->getIdentKind());
13065}
13066
13067template<typename Derived>
13068ExprResult
13069TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13070 NestedNameSpecifierLoc QualifierLoc;
13071 if (E->getQualifierLoc()) {
13072 QualifierLoc
13073 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13074 if (!QualifierLoc)
13075 return ExprError();
13076 }
13077
13078 ValueDecl *ND
13079 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13080 E->getDecl()));
13081 if (!ND || ND->isInvalidDecl())
13082 return ExprError();
13083
13084 NamedDecl *Found = ND;
13085 if (E->getFoundDecl() != E->getDecl()) {
13086 Found = cast_or_null<NamedDecl>(
13087 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13088 if (!Found)
13089 return ExprError();
13090 }
13091
13092 DeclarationNameInfo NameInfo = E->getNameInfo();
13093 if (NameInfo.getName()) {
13094 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13095 if (!NameInfo.getName())
13096 return ExprError();
13097 }
13098
13099 if (!getDerived().AlwaysRebuild() &&
13100 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13101 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13102 Found == E->getFoundDecl() &&
13103 NameInfo.getName() == E->getDecl()->getDeclName() &&
13104 !E->hasExplicitTemplateArgs()) {
13105
13106 // Mark it referenced in the new context regardless.
13107 // FIXME: this is a bit instantiation-specific.
13108 SemaRef.MarkDeclRefReferenced(E);
13109
13110 return E;
13111 }
13112
13113 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13114 if (E->hasExplicitTemplateArgs()) {
13115 TemplateArgs = &TransArgs;
13116 TransArgs.setLAngleLoc(E->getLAngleLoc());
13117 TransArgs.setRAngleLoc(E->getRAngleLoc());
13118 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13119 E->getNumTemplateArgs(),
13120 TransArgs))
13121 return ExprError();
13122 }
13123
13124 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13125 Found, TemplateArgs);
13126}
13127
13128template<typename Derived>
13129ExprResult
13130TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13131 return E;
13132}
13133
13134template <typename Derived>
13135ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13136 FixedPointLiteral *E) {
13137 return E;
13138}
13139
13140template<typename Derived>
13141ExprResult
13142TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13143 return E;
13144}
13145
13146template<typename Derived>
13147ExprResult
13148TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13149 return E;
13150}
13151
13152template<typename Derived>
13153ExprResult
13154TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13155 return E;
13156}
13157
13158template<typename Derived>
13159ExprResult
13160TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13161 return E;
13162}
13163
13164template<typename Derived>
13165ExprResult
13166TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13167 return getDerived().TransformCallExpr(E);
13168}
13169
13170template<typename Derived>
13171ExprResult
13172TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13173 ExprResult ControllingExpr;
13174 TypeSourceInfo *ControllingType = nullptr;
13175 if (E->isExprPredicate())
13176 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13177 else
13178 ControllingType = getDerived().TransformType(E->getControllingType());
13179
13180 if (ControllingExpr.isInvalid() && !ControllingType)
13181 return ExprError();
13182
13183 SmallVector<Expr *, 4> AssocExprs;
13184 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13185 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13186 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13187 if (TSI) {
13188 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13189 if (!AssocType)
13190 return ExprError();
13191 AssocTypes.push_back(Elt: AssocType);
13192 } else {
13193 AssocTypes.push_back(Elt: nullptr);
13194 }
13195
13196 ExprResult AssocExpr =
13197 getDerived().TransformExpr(Assoc.getAssociationExpr());
13198 if (AssocExpr.isInvalid())
13199 return ExprError();
13200 AssocExprs.push_back(Elt: AssocExpr.get());
13201 }
13202
13203 if (!ControllingType)
13204 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13205 E->getDefaultLoc(),
13206 E->getRParenLoc(),
13207 ControllingExpr.get(),
13208 AssocTypes,
13209 AssocExprs);
13210 return getDerived().RebuildGenericSelectionExpr(
13211 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13212 ControllingType, AssocTypes, AssocExprs);
13213}
13214
13215template<typename Derived>
13216ExprResult
13217TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13218 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13219 if (SubExpr.isInvalid())
13220 return ExprError();
13221
13222 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13223 return E;
13224
13225 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13226 E->getRParen());
13227}
13228
13229/// The operand of a unary address-of operator has special rules: it's
13230/// allowed to refer to a non-static member of a class even if there's no 'this'
13231/// object available.
13232template<typename Derived>
13233ExprResult
13234TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13235 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13236 return getDerived().TransformDependentScopeDeclRefExpr(
13237 DRE, /*IsAddressOfOperand=*/true, nullptr);
13238 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13239 return getDerived().TransformUnresolvedLookupExpr(
13240 ULE, /*IsAddressOfOperand=*/true);
13241 else
13242 return getDerived().TransformExpr(E);
13243}
13244
13245template<typename Derived>
13246ExprResult
13247TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13248 ExprResult SubExpr;
13249 if (E->getOpcode() == UO_AddrOf)
13250 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13251 else
13252 SubExpr = TransformExpr(E: E->getSubExpr());
13253 if (SubExpr.isInvalid())
13254 return ExprError();
13255
13256 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13257 return E;
13258
13259 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13260 E->getOpcode(),
13261 SubExpr.get());
13262}
13263
13264template<typename Derived>
13265ExprResult
13266TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13267 // Transform the type.
13268 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13269 if (!Type)
13270 return ExprError();
13271
13272 // Transform all of the components into components similar to what the
13273 // parser uses.
13274 // FIXME: It would be slightly more efficient in the non-dependent case to
13275 // just map FieldDecls, rather than requiring the rebuilder to look for
13276 // the fields again. However, __builtin_offsetof is rare enough in
13277 // template code that we don't care.
13278 bool ExprChanged = false;
13279 typedef Sema::OffsetOfComponent Component;
13280 SmallVector<Component, 4> Components;
13281 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13282 const OffsetOfNode &ON = E->getComponent(Idx: I);
13283 Component Comp;
13284 Comp.isBrackets = true;
13285 Comp.LocStart = ON.getSourceRange().getBegin();
13286 Comp.LocEnd = ON.getSourceRange().getEnd();
13287 switch (ON.getKind()) {
13288 case OffsetOfNode::Array: {
13289 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13290 ExprResult Index = getDerived().TransformExpr(FromIndex);
13291 if (Index.isInvalid())
13292 return ExprError();
13293
13294 ExprChanged = ExprChanged || Index.get() != FromIndex;
13295 Comp.isBrackets = true;
13296 Comp.U.E = Index.get();
13297 break;
13298 }
13299
13300 case OffsetOfNode::Field:
13301 case OffsetOfNode::Identifier:
13302 Comp.isBrackets = false;
13303 Comp.U.IdentInfo = ON.getFieldName();
13304 if (!Comp.U.IdentInfo)
13305 continue;
13306
13307 break;
13308
13309 case OffsetOfNode::Base:
13310 // Will be recomputed during the rebuild.
13311 continue;
13312 }
13313
13314 Components.push_back(Elt: Comp);
13315 }
13316
13317 // If nothing changed, retain the existing expression.
13318 if (!getDerived().AlwaysRebuild() &&
13319 Type == E->getTypeSourceInfo() &&
13320 !ExprChanged)
13321 return E;
13322
13323 // Build a new offsetof expression.
13324 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13325 Components, E->getRParenLoc());
13326}
13327
13328template<typename Derived>
13329ExprResult
13330TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13331 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13332 "opaque value expression requires transformation");
13333 return E;
13334}
13335
13336template <typename Derived>
13337ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13338 llvm::SmallVector<Expr *, 8> Children;
13339 bool Changed = false;
13340 for (Expr *C : E->subExpressions()) {
13341 ExprResult NewC = getDerived().TransformExpr(C);
13342 if (NewC.isInvalid())
13343 return ExprError();
13344 Children.push_back(Elt: NewC.get());
13345
13346 Changed |= NewC.get() != C;
13347 }
13348 if (!getDerived().AlwaysRebuild() && !Changed)
13349 return E;
13350 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13351 Children, E->getType());
13352}
13353
13354template<typename Derived>
13355ExprResult
13356TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13357 // Rebuild the syntactic form. The original syntactic form has
13358 // opaque-value expressions in it, so strip those away and rebuild
13359 // the result. This is a really awful way of doing this, but the
13360 // better solution (rebuilding the semantic expressions and
13361 // rebinding OVEs as necessary) doesn't work; we'd need
13362 // TreeTransform to not strip away implicit conversions.
13363 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13364 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13365 if (result.isInvalid()) return ExprError();
13366
13367 // If that gives us a pseudo-object result back, the pseudo-object
13368 // expression must have been an lvalue-to-rvalue conversion which we
13369 // should reapply.
13370 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13371 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13372
13373 return result;
13374}
13375
13376template<typename Derived>
13377ExprResult
13378TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13379 UnaryExprOrTypeTraitExpr *E) {
13380 if (E->isArgumentType()) {
13381 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13382
13383 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13384 if (!NewT)
13385 return ExprError();
13386
13387 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13388 return E;
13389
13390 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13391 E->getKind(),
13392 E->getSourceRange());
13393 }
13394
13395 // C++0x [expr.sizeof]p1:
13396 // The operand is either an expression, which is an unevaluated operand
13397 // [...]
13398 EnterExpressionEvaluationContext Unevaluated(
13399 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13400 Sema::ReuseLambdaContextDecl);
13401
13402 // Try to recover if we have something like sizeof(T::X) where X is a type.
13403 // Notably, there must be *exactly* one set of parens if X is a type.
13404 TypeSourceInfo *RecoveryTSI = nullptr;
13405 ExprResult SubExpr;
13406 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13407 if (auto *DRE =
13408 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13409 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13410 PE, DRE, false, &RecoveryTSI);
13411 else
13412 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13413
13414 if (RecoveryTSI) {
13415 return getDerived().RebuildUnaryExprOrTypeTrait(
13416 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13417 } else if (SubExpr.isInvalid())
13418 return ExprError();
13419
13420 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13421 return E;
13422
13423 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13424 E->getOperatorLoc(),
13425 E->getKind(),
13426 E->getSourceRange());
13427}
13428
13429template<typename Derived>
13430ExprResult
13431TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13432 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13433 if (LHS.isInvalid())
13434 return ExprError();
13435
13436 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13437 if (RHS.isInvalid())
13438 return ExprError();
13439
13440
13441 if (!getDerived().AlwaysRebuild() &&
13442 LHS.get() == E->getLHS() &&
13443 RHS.get() == E->getRHS())
13444 return E;
13445
13446 return getDerived().RebuildArraySubscriptExpr(
13447 LHS.get(),
13448 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13449}
13450
13451template <typename Derived>
13452ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13453 MatrixSingleSubscriptExpr *E) {
13454 ExprResult Base = getDerived().TransformExpr(E->getBase());
13455 if (Base.isInvalid())
13456 return ExprError();
13457
13458 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13459 if (RowIdx.isInvalid())
13460 return ExprError();
13461
13462 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13463 RowIdx.get() == E->getRowIdx())
13464 return E;
13465
13466 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
13467 E->getRBracketLoc());
13468}
13469
13470template <typename Derived>
13471ExprResult
13472TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13473 ExprResult Base = getDerived().TransformExpr(E->getBase());
13474 if (Base.isInvalid())
13475 return ExprError();
13476
13477 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13478 if (RowIdx.isInvalid())
13479 return ExprError();
13480
13481 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13482 if (ColumnIdx.isInvalid())
13483 return ExprError();
13484
13485 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13486 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13487 return E;
13488
13489 return getDerived().RebuildMatrixSubscriptExpr(
13490 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13491}
13492
13493template <typename Derived>
13494ExprResult
13495TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13496 ExprResult Base = getDerived().TransformExpr(E->getBase());
13497 if (Base.isInvalid())
13498 return ExprError();
13499
13500 ExprResult LowerBound;
13501 if (E->getLowerBound()) {
13502 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13503 if (LowerBound.isInvalid())
13504 return ExprError();
13505 }
13506
13507 ExprResult Length;
13508 if (E->getLength()) {
13509 Length = getDerived().TransformExpr(E->getLength());
13510 if (Length.isInvalid())
13511 return ExprError();
13512 }
13513
13514 ExprResult Stride;
13515 if (E->isOMPArraySection()) {
13516 if (Expr *Str = E->getStride()) {
13517 Stride = getDerived().TransformExpr(Str);
13518 if (Stride.isInvalid())
13519 return ExprError();
13520 }
13521 }
13522
13523 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13524 LowerBound.get() == E->getLowerBound() &&
13525 Length.get() == E->getLength() &&
13526 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13527 return E;
13528
13529 return getDerived().RebuildArraySectionExpr(
13530 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13531 LowerBound.get(), E->getColonLocFirst(),
13532 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13533 Length.get(), Stride.get(), E->getRBracketLoc());
13534}
13535
13536template <typename Derived>
13537ExprResult
13538TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13539 ExprResult Base = getDerived().TransformExpr(E->getBase());
13540 if (Base.isInvalid())
13541 return ExprError();
13542
13543 SmallVector<Expr *, 4> Dims;
13544 bool ErrorFound = false;
13545 for (Expr *Dim : E->getDimensions()) {
13546 ExprResult DimRes = getDerived().TransformExpr(Dim);
13547 if (DimRes.isInvalid()) {
13548 ErrorFound = true;
13549 continue;
13550 }
13551 Dims.push_back(Elt: DimRes.get());
13552 }
13553
13554 if (ErrorFound)
13555 return ExprError();
13556 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13557 E->getRParenLoc(), Dims,
13558 E->getBracketsRanges());
13559}
13560
13561template <typename Derived>
13562ExprResult
13563TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13564 unsigned NumIterators = E->numOfIterators();
13565 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13566
13567 bool ErrorFound = false;
13568 bool NeedToRebuild = getDerived().AlwaysRebuild();
13569 for (unsigned I = 0; I < NumIterators; ++I) {
13570 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13571 Data[I].DeclIdent = D->getIdentifier();
13572 Data[I].DeclIdentLoc = D->getLocation();
13573 if (D->getLocation() == D->getBeginLoc()) {
13574 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13575 "Implicit type must be int.");
13576 } else {
13577 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13578 QualType DeclTy = getDerived().TransformType(D->getType());
13579 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13580 }
13581 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13582 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13583 ExprResult End = getDerived().TransformExpr(Range.End);
13584 ExprResult Step = getDerived().TransformExpr(Range.Step);
13585 ErrorFound = ErrorFound ||
13586 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13587 !Data[I].Type.get().isNull())) ||
13588 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13589 if (ErrorFound)
13590 continue;
13591 Data[I].Range.Begin = Begin.get();
13592 Data[I].Range.End = End.get();
13593 Data[I].Range.Step = Step.get();
13594 Data[I].AssignLoc = E->getAssignLoc(I);
13595 Data[I].ColonLoc = E->getColonLoc(I);
13596 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13597 NeedToRebuild =
13598 NeedToRebuild ||
13599 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13600 D->getType().getTypePtrOrNull()) ||
13601 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13602 Range.Step != Data[I].Range.Step;
13603 }
13604 if (ErrorFound)
13605 return ExprError();
13606 if (!NeedToRebuild)
13607 return E;
13608
13609 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13610 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13611 if (!Res.isUsable())
13612 return Res;
13613 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13614 for (unsigned I = 0; I < NumIterators; ++I)
13615 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13616 IE->getIteratorDecl(I));
13617 return Res;
13618}
13619
13620template<typename Derived>
13621ExprResult
13622TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13623 // Transform the callee.
13624 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13625 if (Callee.isInvalid())
13626 return ExprError();
13627
13628 // Transform arguments.
13629 bool ArgChanged = false;
13630 SmallVector<Expr*, 8> Args;
13631 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13632 &ArgChanged))
13633 return ExprError();
13634
13635 if (!getDerived().AlwaysRebuild() &&
13636 Callee.get() == E->getCallee() &&
13637 !ArgChanged)
13638 return SemaRef.MaybeBindToTemporary(E);
13639
13640 // FIXME: Wrong source location information for the '('.
13641 SourceLocation FakeLParenLoc
13642 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13643
13644 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13645 if (E->hasStoredFPFeatures()) {
13646 FPOptionsOverride NewOverrides = E->getFPFeatures();
13647 getSema().CurFPFeatures =
13648 NewOverrides.applyOverrides(getSema().getLangOpts());
13649 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13650 }
13651
13652 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13653 Args,
13654 E->getRParenLoc());
13655}
13656
13657template<typename Derived>
13658ExprResult
13659TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13660 ExprResult Base = getDerived().TransformExpr(E->getBase());
13661 if (Base.isInvalid())
13662 return ExprError();
13663
13664 NestedNameSpecifierLoc QualifierLoc;
13665 if (E->hasQualifier()) {
13666 QualifierLoc
13667 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13668
13669 if (!QualifierLoc)
13670 return ExprError();
13671 }
13672 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13673
13674 ValueDecl *Member
13675 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13676 E->getMemberDecl()));
13677 if (!Member)
13678 return ExprError();
13679
13680 NamedDecl *FoundDecl = E->getFoundDecl();
13681 if (FoundDecl == E->getMemberDecl()) {
13682 FoundDecl = Member;
13683 } else {
13684 FoundDecl = cast_or_null<NamedDecl>(
13685 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13686 if (!FoundDecl)
13687 return ExprError();
13688 }
13689
13690 if (!getDerived().AlwaysRebuild() &&
13691 Base.get() == E->getBase() &&
13692 QualifierLoc == E->getQualifierLoc() &&
13693 Member == E->getMemberDecl() &&
13694 FoundDecl == E->getFoundDecl() &&
13695 !E->hasExplicitTemplateArgs()) {
13696
13697 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13698 // for Openmp where the field need to be privatizized in the case.
13699 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13700 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13701 cast<ValueDecl>(Val: Member)))) {
13702 // Mark it referenced in the new context regardless.
13703 // FIXME: this is a bit instantiation-specific.
13704 SemaRef.MarkMemberReferenced(E);
13705 return E;
13706 }
13707 }
13708
13709 TemplateArgumentListInfo TransArgs;
13710 if (E->hasExplicitTemplateArgs()) {
13711 TransArgs.setLAngleLoc(E->getLAngleLoc());
13712 TransArgs.setRAngleLoc(E->getRAngleLoc());
13713 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13714 E->getNumTemplateArgs(),
13715 TransArgs))
13716 return ExprError();
13717 }
13718
13719 // FIXME: Bogus source location for the operator
13720 SourceLocation FakeOperatorLoc =
13721 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13722
13723 // FIXME: to do this check properly, we will need to preserve the
13724 // first-qualifier-in-scope here, just in case we had a dependent
13725 // base (and therefore couldn't do the check) and a
13726 // nested-name-qualifier (and therefore could do the lookup).
13727 NamedDecl *FirstQualifierInScope = nullptr;
13728 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13729 if (MemberNameInfo.getName()) {
13730 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13731 if (!MemberNameInfo.getName())
13732 return ExprError();
13733 }
13734
13735 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13736 E->isArrow(),
13737 QualifierLoc,
13738 TemplateKWLoc,
13739 MemberNameInfo,
13740 Member,
13741 FoundDecl,
13742 (E->hasExplicitTemplateArgs()
13743 ? &TransArgs : nullptr),
13744 FirstQualifierInScope);
13745}
13746
13747template<typename Derived>
13748ExprResult
13749TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13750 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13751 if (LHS.isInvalid())
13752 return ExprError();
13753
13754 ExprResult RHS =
13755 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13756 if (RHS.isInvalid())
13757 return ExprError();
13758
13759 if (!getDerived().AlwaysRebuild() &&
13760 LHS.get() == E->getLHS() &&
13761 RHS.get() == E->getRHS())
13762 return E;
13763
13764 if (E->isCompoundAssignmentOp())
13765 // FPFeatures has already been established from trailing storage
13766 return getDerived().RebuildBinaryOperator(
13767 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13768 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13769 FPOptionsOverride NewOverrides(E->getFPFeatures());
13770 getSema().CurFPFeatures =
13771 NewOverrides.applyOverrides(getSema().getLangOpts());
13772 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13773 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13774 LHS.get(), RHS.get());
13775}
13776
13777template <typename Derived>
13778ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13779 CXXRewrittenBinaryOperator *E) {
13780 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13781
13782 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13783 if (LHS.isInvalid())
13784 return ExprError();
13785
13786 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13787 if (RHS.isInvalid())
13788 return ExprError();
13789
13790 // Extract the already-resolved callee declarations so that we can restrict
13791 // ourselves to using them as the unqualified lookup results when rebuilding.
13792 UnresolvedSet<2> UnqualLookups;
13793 bool ChangedAnyLookups = false;
13794 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13795 const_cast<Expr *>(Decomp.InnerBinOp)};
13796 for (Expr *PossibleBinOp : PossibleBinOps) {
13797 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13798 if (!Op)
13799 continue;
13800 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13801 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13802 continue;
13803
13804 // Transform the callee in case we built a call to a local extern
13805 // declaration.
13806 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13807 E->getOperatorLoc(), Callee->getFoundDecl()));
13808 if (!Found)
13809 return ExprError();
13810 if (Found != Callee->getFoundDecl())
13811 ChangedAnyLookups = true;
13812 UnqualLookups.addDecl(D: Found);
13813 }
13814
13815 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13816 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13817 // Mark all functions used in the rewrite as referenced. Note that when
13818 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13819 // function calls, and/or there might be a user-defined conversion sequence
13820 // applied to the operands of the <.
13821 // FIXME: this is a bit instantiation-specific.
13822 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13823 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13824 return E;
13825 }
13826
13827 return getDerived().RebuildCXXRewrittenBinaryOperator(
13828 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13829}
13830
13831template<typename Derived>
13832ExprResult
13833TreeTransform<Derived>::TransformCompoundAssignOperator(
13834 CompoundAssignOperator *E) {
13835 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13836 FPOptionsOverride NewOverrides(E->getFPFeatures());
13837 getSema().CurFPFeatures =
13838 NewOverrides.applyOverrides(getSema().getLangOpts());
13839 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13840 return getDerived().TransformBinaryOperator(E);
13841}
13842
13843template<typename Derived>
13844ExprResult TreeTransform<Derived>::
13845TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13846 // Just rebuild the common and RHS expressions and see whether we
13847 // get any changes.
13848
13849 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13850 if (commonExpr.isInvalid())
13851 return ExprError();
13852
13853 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13854 if (rhs.isInvalid())
13855 return ExprError();
13856
13857 if (!getDerived().AlwaysRebuild() &&
13858 commonExpr.get() == e->getCommon() &&
13859 rhs.get() == e->getFalseExpr())
13860 return e;
13861
13862 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13863 e->getQuestionLoc(),
13864 nullptr,
13865 e->getColonLoc(),
13866 rhs.get());
13867}
13868
13869template<typename Derived>
13870ExprResult
13871TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13872 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13873 if (Cond.isInvalid())
13874 return ExprError();
13875
13876 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13877 if (LHS.isInvalid())
13878 return ExprError();
13879
13880 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13881 if (RHS.isInvalid())
13882 return ExprError();
13883
13884 if (!getDerived().AlwaysRebuild() &&
13885 Cond.get() == E->getCond() &&
13886 LHS.get() == E->getLHS() &&
13887 RHS.get() == E->getRHS())
13888 return E;
13889
13890 return getDerived().RebuildConditionalOperator(Cond.get(),
13891 E->getQuestionLoc(),
13892 LHS.get(),
13893 E->getColonLoc(),
13894 RHS.get());
13895}
13896
13897template<typename Derived>
13898ExprResult
13899TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13900 // Implicit casts are eliminated during transformation, since they
13901 // will be recomputed by semantic analysis after transformation.
13902 return getDerived().TransformExpr(E->getSubExprAsWritten());
13903}
13904
13905template<typename Derived>
13906ExprResult
13907TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13908 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13909 if (!Type)
13910 return ExprError();
13911
13912 ExprResult SubExpr
13913 = getDerived().TransformExpr(E->getSubExprAsWritten());
13914 if (SubExpr.isInvalid())
13915 return ExprError();
13916
13917 if (!getDerived().AlwaysRebuild() &&
13918 Type == E->getTypeInfoAsWritten() &&
13919 SubExpr.get() == E->getSubExpr())
13920 return E;
13921
13922 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13923 Type,
13924 E->getRParenLoc(),
13925 SubExpr.get());
13926}
13927
13928template<typename Derived>
13929ExprResult
13930TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13931 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13932 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13933 if (!NewT)
13934 return ExprError();
13935
13936 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13937 if (Init.isInvalid())
13938 return ExprError();
13939
13940 if (!getDerived().AlwaysRebuild() &&
13941 OldT == NewT &&
13942 Init.get() == E->getInitializer())
13943 return SemaRef.MaybeBindToTemporary(E);
13944
13945 // Note: the expression type doesn't necessarily match the
13946 // type-as-written, but that's okay, because it should always be
13947 // derivable from the initializer.
13948
13949 return getDerived().RebuildCompoundLiteralExpr(
13950 E->getLParenLoc(), NewT,
13951 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13952}
13953
13954template<typename Derived>
13955ExprResult
13956TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13957 ExprResult Base = getDerived().TransformExpr(E->getBase());
13958 if (Base.isInvalid())
13959 return ExprError();
13960
13961 if (!getDerived().AlwaysRebuild() &&
13962 Base.get() == E->getBase())
13963 return E;
13964
13965 // FIXME: Bad source location
13966 SourceLocation FakeOperatorLoc =
13967 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
13968 return getDerived().RebuildExtVectorElementExpr(
13969 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13970 E->getAccessor());
13971}
13972
13973template<typename Derived>
13974ExprResult
13975TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13976 if (InitListExpr *Syntactic = E->getSyntacticForm())
13977 E = Syntactic;
13978
13979 bool InitChanged = false;
13980
13981 EnterExpressionEvaluationContext Context(
13982 getSema(), EnterExpressionEvaluationContext::InitList);
13983
13984 SmallVector<Expr*, 4> Inits;
13985 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13986 Inits, &InitChanged))
13987 return ExprError();
13988
13989 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13990 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13991 // in some cases. We can't reuse it in general, because the syntactic and
13992 // semantic forms are linked, and we can't know that semantic form will
13993 // match even if the syntactic form does.
13994 }
13995
13996 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13997 E->getRBraceLoc());
13998}
13999
14000template<typename Derived>
14001ExprResult
14002TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14003 Designation Desig;
14004
14005 // transform the initializer value
14006 ExprResult Init = getDerived().TransformExpr(E->getInit());
14007 if (Init.isInvalid())
14008 return ExprError();
14009
14010 // transform the designators.
14011 SmallVector<Expr*, 4> ArrayExprs;
14012 bool ExprChanged = false;
14013 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14014 if (D.isFieldDesignator()) {
14015 if (D.getFieldDecl()) {
14016 FieldDecl *Field = cast_or_null<FieldDecl>(
14017 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14018 if (Field != D.getFieldDecl())
14019 // Rebuild the expression when the transformed FieldDecl is
14020 // different to the already assigned FieldDecl.
14021 ExprChanged = true;
14022 if (Field->isAnonymousStructOrUnion())
14023 continue;
14024 } else {
14025 // Ensure that the designator expression is rebuilt when there isn't
14026 // a resolved FieldDecl in the designator as we don't want to assign
14027 // a FieldDecl to a pattern designator that will be instantiated again.
14028 ExprChanged = true;
14029 }
14030 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14031 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14032 continue;
14033 }
14034
14035 if (D.isArrayDesignator()) {
14036 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14037 if (Index.isInvalid())
14038 return ExprError();
14039
14040 Desig.AddDesignator(
14041 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14042
14043 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14044 ArrayExprs.push_back(Elt: Index.get());
14045 continue;
14046 }
14047
14048 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14049 ExprResult Start
14050 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14051 if (Start.isInvalid())
14052 return ExprError();
14053
14054 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14055 if (End.isInvalid())
14056 return ExprError();
14057
14058 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14059 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14060
14061 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14062 End.get() != E->getArrayRangeEnd(D);
14063
14064 ArrayExprs.push_back(Elt: Start.get());
14065 ArrayExprs.push_back(Elt: End.get());
14066 }
14067
14068 if (!getDerived().AlwaysRebuild() &&
14069 Init.get() == E->getInit() &&
14070 !ExprChanged)
14071 return E;
14072
14073 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14074 E->getEqualOrColonLoc(),
14075 E->usesGNUSyntax(), Init.get());
14076}
14077
14078// Seems that if TransformInitListExpr() only works on the syntactic form of an
14079// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14080template<typename Derived>
14081ExprResult
14082TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14083 DesignatedInitUpdateExpr *E) {
14084 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14085 "initializer");
14086 return ExprError();
14087}
14088
14089template<typename Derived>
14090ExprResult
14091TreeTransform<Derived>::TransformNoInitExpr(
14092 NoInitExpr *E) {
14093 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14094 return ExprError();
14095}
14096
14097template<typename Derived>
14098ExprResult
14099TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14100 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14101 return ExprError();
14102}
14103
14104template<typename Derived>
14105ExprResult
14106TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14107 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14108 return ExprError();
14109}
14110
14111template<typename Derived>
14112ExprResult
14113TreeTransform<Derived>::TransformImplicitValueInitExpr(
14114 ImplicitValueInitExpr *E) {
14115 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14116
14117 // FIXME: Will we ever have proper type location here? Will we actually
14118 // need to transform the type?
14119 QualType T = getDerived().TransformType(E->getType());
14120 if (T.isNull())
14121 return ExprError();
14122
14123 if (!getDerived().AlwaysRebuild() &&
14124 T == E->getType())
14125 return E;
14126
14127 return getDerived().RebuildImplicitValueInitExpr(T);
14128}
14129
14130template<typename Derived>
14131ExprResult
14132TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14133 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14134 if (!TInfo)
14135 return ExprError();
14136
14137 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14138 if (SubExpr.isInvalid())
14139 return ExprError();
14140
14141 if (!getDerived().AlwaysRebuild() &&
14142 TInfo == E->getWrittenTypeInfo() &&
14143 SubExpr.get() == E->getSubExpr())
14144 return E;
14145
14146 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14147 TInfo, E->getRParenLoc());
14148}
14149
14150template<typename Derived>
14151ExprResult
14152TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14153 bool ArgumentChanged = false;
14154 SmallVector<Expr*, 4> Inits;
14155 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14156 ArgChanged: &ArgumentChanged))
14157 return ExprError();
14158
14159 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14160 Inits,
14161 E->getRParenLoc());
14162}
14163
14164/// Transform an address-of-label expression.
14165///
14166/// By default, the transformation of an address-of-label expression always
14167/// rebuilds the expression, so that the label identifier can be resolved to
14168/// the corresponding label statement by semantic analysis.
14169template<typename Derived>
14170ExprResult
14171TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14172 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14173 E->getLabel());
14174 if (!LD)
14175 return ExprError();
14176
14177 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14178 cast<LabelDecl>(Val: LD));
14179}
14180
14181template<typename Derived>
14182ExprResult
14183TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14184 SemaRef.ActOnStartStmtExpr();
14185 StmtResult SubStmt
14186 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14187 if (SubStmt.isInvalid()) {
14188 SemaRef.ActOnStmtExprError();
14189 return ExprError();
14190 }
14191
14192 unsigned OldDepth = E->getTemplateDepth();
14193 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14194
14195 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14196 SubStmt.get() == E->getSubStmt()) {
14197 // Calling this an 'error' is unintuitive, but it does the right thing.
14198 SemaRef.ActOnStmtExprError();
14199 return SemaRef.MaybeBindToTemporary(E);
14200 }
14201
14202 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14203 E->getRParenLoc(), NewDepth);
14204}
14205
14206template<typename Derived>
14207ExprResult
14208TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14209 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14210 if (Cond.isInvalid())
14211 return ExprError();
14212
14213 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14214 if (LHS.isInvalid())
14215 return ExprError();
14216
14217 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14218 if (RHS.isInvalid())
14219 return ExprError();
14220
14221 if (!getDerived().AlwaysRebuild() &&
14222 Cond.get() == E->getCond() &&
14223 LHS.get() == E->getLHS() &&
14224 RHS.get() == E->getRHS())
14225 return E;
14226
14227 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14228 Cond.get(), LHS.get(), RHS.get(),
14229 E->getRParenLoc());
14230}
14231
14232template<typename Derived>
14233ExprResult
14234TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14235 return E;
14236}
14237
14238template<typename Derived>
14239ExprResult
14240TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14241 switch (E->getOperator()) {
14242 case OO_New:
14243 case OO_Delete:
14244 case OO_Array_New:
14245 case OO_Array_Delete:
14246 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14247
14248 case OO_Subscript:
14249 case OO_Call: {
14250 // This is a call to an object's operator().
14251 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14252
14253 // Transform the object itself.
14254 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14255 if (Object.isInvalid())
14256 return ExprError();
14257
14258 // FIXME: Poor location information. Also, if the location for the end of
14259 // the token is within a macro expansion, getLocForEndOfToken() will return
14260 // an invalid source location. If that happens and we have an otherwise
14261 // valid end location, use the valid one instead of the invalid one.
14262 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14263 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14264 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14265 FakeLParenLoc = EndLoc;
14266
14267 // Transform the call arguments.
14268 SmallVector<Expr*, 8> Args;
14269 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14270 Args))
14271 return ExprError();
14272
14273 if (E->getOperator() == OO_Subscript)
14274 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14275 Args, E->getEndLoc());
14276
14277 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14278 E->getEndLoc());
14279 }
14280
14281#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14282 case OO_##Name: \
14283 break;
14284
14285#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14286#include "clang/Basic/OperatorKinds.def"
14287
14288 case OO_Conditional:
14289 llvm_unreachable("conditional operator is not actually overloadable");
14290
14291 case OO_None:
14292 case NUM_OVERLOADED_OPERATORS:
14293 llvm_unreachable("not an overloaded operator?");
14294 }
14295
14296 ExprResult First;
14297 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14298 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14299 else
14300 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14301 if (First.isInvalid())
14302 return ExprError();
14303
14304 ExprResult Second;
14305 if (E->getNumArgs() == 2) {
14306 Second =
14307 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14308 if (Second.isInvalid())
14309 return ExprError();
14310 }
14311
14312 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14313 FPOptionsOverride NewOverrides(E->getFPFeatures());
14314 getSema().CurFPFeatures =
14315 NewOverrides.applyOverrides(getSema().getLangOpts());
14316 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14317
14318 Expr *Callee = E->getCallee();
14319 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14320 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14321 Sema::LookupOrdinaryName);
14322 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14323 return ExprError();
14324
14325 return getDerived().RebuildCXXOperatorCallExpr(
14326 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14327 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14328 }
14329
14330 UnresolvedSet<1> Functions;
14331 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14332 Callee = ICE->getSubExprAsWritten();
14333 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14334 ValueDecl *VD = cast_or_null<ValueDecl>(
14335 getDerived().TransformDecl(DR->getLocation(), DR));
14336 if (!VD)
14337 return ExprError();
14338
14339 if (!isa<CXXMethodDecl>(Val: VD))
14340 Functions.addDecl(D: VD);
14341
14342 return getDerived().RebuildCXXOperatorCallExpr(
14343 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14344 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14345}
14346
14347template<typename Derived>
14348ExprResult
14349TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14350 return getDerived().TransformCallExpr(E);
14351}
14352
14353template <typename Derived>
14354ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14355 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14356 getSema().CurContext != E->getParentContext();
14357
14358 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14359 return E;
14360
14361 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14362 E->getBeginLoc(), E->getEndLoc(),
14363 getSema().CurContext);
14364}
14365
14366template <typename Derived>
14367ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14368 return E;
14369}
14370
14371template<typename Derived>
14372ExprResult
14373TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14374 // Transform the callee.
14375 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14376 if (Callee.isInvalid())
14377 return ExprError();
14378
14379 // Transform exec config.
14380 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14381 if (EC.isInvalid())
14382 return ExprError();
14383
14384 // Transform arguments.
14385 bool ArgChanged = false;
14386 SmallVector<Expr*, 8> Args;
14387 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14388 &ArgChanged))
14389 return ExprError();
14390
14391 if (!getDerived().AlwaysRebuild() &&
14392 Callee.get() == E->getCallee() &&
14393 !ArgChanged)
14394 return SemaRef.MaybeBindToTemporary(E);
14395
14396 // FIXME: Wrong source location information for the '('.
14397 SourceLocation FakeLParenLoc
14398 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14399 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14400 Args,
14401 E->getRParenLoc(), EC.get());
14402}
14403
14404template<typename Derived>
14405ExprResult
14406TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14407 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14408 if (!Type)
14409 return ExprError();
14410
14411 ExprResult SubExpr
14412 = getDerived().TransformExpr(E->getSubExprAsWritten());
14413 if (SubExpr.isInvalid())
14414 return ExprError();
14415
14416 if (!getDerived().AlwaysRebuild() &&
14417 Type == E->getTypeInfoAsWritten() &&
14418 SubExpr.get() == E->getSubExpr())
14419 return E;
14420 return getDerived().RebuildCXXNamedCastExpr(
14421 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14422 Type, E->getAngleBrackets().getEnd(),
14423 // FIXME. this should be '(' location
14424 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14425}
14426
14427template<typename Derived>
14428ExprResult
14429TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14430 TypeSourceInfo *TSI =
14431 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14432 if (!TSI)
14433 return ExprError();
14434
14435 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14436 if (Sub.isInvalid())
14437 return ExprError();
14438
14439 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14440 Sub.get(), BCE->getEndLoc());
14441}
14442
14443template<typename Derived>
14444ExprResult
14445TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14446 return getDerived().TransformCXXNamedCastExpr(E);
14447}
14448
14449template<typename Derived>
14450ExprResult
14451TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14452 return getDerived().TransformCXXNamedCastExpr(E);
14453}
14454
14455template<typename Derived>
14456ExprResult
14457TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14458 CXXReinterpretCastExpr *E) {
14459 return getDerived().TransformCXXNamedCastExpr(E);
14460}
14461
14462template<typename Derived>
14463ExprResult
14464TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14465 return getDerived().TransformCXXNamedCastExpr(E);
14466}
14467
14468template<typename Derived>
14469ExprResult
14470TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14471 return getDerived().TransformCXXNamedCastExpr(E);
14472}
14473
14474template<typename Derived>
14475ExprResult
14476TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14477 CXXFunctionalCastExpr *E) {
14478 TypeSourceInfo *Type =
14479 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14480 if (!Type)
14481 return ExprError();
14482
14483 ExprResult SubExpr
14484 = getDerived().TransformExpr(E->getSubExprAsWritten());
14485 if (SubExpr.isInvalid())
14486 return ExprError();
14487
14488 if (!getDerived().AlwaysRebuild() &&
14489 Type == E->getTypeInfoAsWritten() &&
14490 SubExpr.get() == E->getSubExpr())
14491 return E;
14492
14493 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14494 E->getLParenLoc(),
14495 SubExpr.get(),
14496 E->getRParenLoc(),
14497 E->isListInitialization());
14498}
14499
14500template<typename Derived>
14501ExprResult
14502TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14503 if (E->isTypeOperand()) {
14504 TypeSourceInfo *TInfo
14505 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14506 if (!TInfo)
14507 return ExprError();
14508
14509 if (!getDerived().AlwaysRebuild() &&
14510 TInfo == E->getTypeOperandSourceInfo())
14511 return E;
14512
14513 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14514 TInfo, E->getEndLoc());
14515 }
14516
14517 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14518 // type. We must not unilaterally enter unevaluated context here, as then
14519 // semantic processing can re-transform an already transformed operand.
14520 Expr *Op = E->getExprOperand();
14521 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14522 if (E->isGLValue())
14523 if (auto *RD = Op->getType()->getAsCXXRecordDecl();
14524 RD && RD->isPolymorphic())
14525 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14526
14527 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14528 Sema::ReuseLambdaContextDecl);
14529
14530 ExprResult SubExpr = getDerived().TransformExpr(Op);
14531 if (SubExpr.isInvalid())
14532 return ExprError();
14533
14534 if (!getDerived().AlwaysRebuild() &&
14535 SubExpr.get() == E->getExprOperand())
14536 return E;
14537
14538 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14539 SubExpr.get(), E->getEndLoc());
14540}
14541
14542template<typename Derived>
14543ExprResult
14544TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14545 if (E->isTypeOperand()) {
14546 TypeSourceInfo *TInfo
14547 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14548 if (!TInfo)
14549 return ExprError();
14550
14551 if (!getDerived().AlwaysRebuild() &&
14552 TInfo == E->getTypeOperandSourceInfo())
14553 return E;
14554
14555 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14556 TInfo, E->getEndLoc());
14557 }
14558
14559 EnterExpressionEvaluationContext Unevaluated(
14560 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14561
14562 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14563 if (SubExpr.isInvalid())
14564 return ExprError();
14565
14566 if (!getDerived().AlwaysRebuild() &&
14567 SubExpr.get() == E->getExprOperand())
14568 return E;
14569
14570 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14571 SubExpr.get(), E->getEndLoc());
14572}
14573
14574template<typename Derived>
14575ExprResult
14576TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14577 return E;
14578}
14579
14580template<typename Derived>
14581ExprResult
14582TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14583 CXXNullPtrLiteralExpr *E) {
14584 return E;
14585}
14586
14587template<typename Derived>
14588ExprResult
14589TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14590
14591 // In lambdas, the qualifiers of the type depends of where in
14592 // the call operator `this` appear, and we do not have a good way to
14593 // rebuild this information, so we transform the type.
14594 //
14595 // In other contexts, the type of `this` may be overrided
14596 // for type deduction, so we need to recompute it.
14597 //
14598 // Always recompute the type if we're in the body of a lambda, and
14599 // 'this' is dependent on a lambda's explicit object parameter; we
14600 // also need to always rebuild the expression in this case to clear
14601 // the flag.
14602 QualType T = [&]() {
14603 auto &S = getSema();
14604 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14605 return S.getCurrentThisType();
14606 if (S.getCurLambda())
14607 return getDerived().TransformType(E->getType());
14608 return S.getCurrentThisType();
14609 }();
14610
14611 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
14612 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
14613 // Mark it referenced in the new context regardless.
14614 // FIXME: this is a bit instantiation-specific.
14615 getSema().MarkThisReferenced(E);
14616 return E;
14617 }
14618
14619 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14620}
14621
14622template<typename Derived>
14623ExprResult
14624TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14625 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14626 if (SubExpr.isInvalid())
14627 return ExprError();
14628
14629 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14630
14631 if (!getDerived().AlwaysRebuild() &&
14632 SubExpr.get() == E->getSubExpr())
14633 return E;
14634
14635 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14636 E->isThrownVariableInScope());
14637}
14638
14639template<typename Derived>
14640ExprResult
14641TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14642 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14643 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14644 if (!Param)
14645 return ExprError();
14646
14647 ExprResult InitRes;
14648 if (E->hasRewrittenInit()) {
14649 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14650 if (InitRes.isInvalid())
14651 return ExprError();
14652 }
14653
14654 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14655 E->getUsedContext() == SemaRef.CurContext &&
14656 InitRes.get() == E->getRewrittenExpr())
14657 return E;
14658
14659 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14660 InitRes.get());
14661}
14662
14663template<typename Derived>
14664ExprResult
14665TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14666 FieldDecl *Field = cast_or_null<FieldDecl>(
14667 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14668 if (!Field)
14669 return ExprError();
14670
14671 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14672 E->getUsedContext() == SemaRef.CurContext)
14673 return E;
14674
14675 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14676}
14677
14678template<typename Derived>
14679ExprResult
14680TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14681 CXXScalarValueInitExpr *E) {
14682 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14683 if (!T)
14684 return ExprError();
14685
14686 if (!getDerived().AlwaysRebuild() &&
14687 T == E->getTypeSourceInfo())
14688 return E;
14689
14690 return getDerived().RebuildCXXScalarValueInitExpr(T,
14691 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14692 E->getRParenLoc());
14693}
14694
14695template<typename Derived>
14696ExprResult
14697TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14698 // Transform the type that we're allocating
14699 TypeSourceInfo *AllocTypeInfo =
14700 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14701 if (!AllocTypeInfo)
14702 return ExprError();
14703
14704 // Transform the size of the array we're allocating (if any).
14705 std::optional<Expr *> ArraySize;
14706 if (E->isArray()) {
14707 ExprResult NewArraySize;
14708 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14709 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14710 if (NewArraySize.isInvalid())
14711 return ExprError();
14712 }
14713 ArraySize = NewArraySize.get();
14714 }
14715
14716 // Transform the placement arguments (if any).
14717 bool ArgumentChanged = false;
14718 SmallVector<Expr*, 8> PlacementArgs;
14719 if (getDerived().TransformExprs(E->getPlacementArgs(),
14720 E->getNumPlacementArgs(), true,
14721 PlacementArgs, &ArgumentChanged))
14722 return ExprError();
14723
14724 // Transform the initializer (if any).
14725 Expr *OldInit = E->getInitializer();
14726 ExprResult NewInit;
14727 if (OldInit)
14728 NewInit = getDerived().TransformInitializer(OldInit, true);
14729 if (NewInit.isInvalid())
14730 return ExprError();
14731
14732 // Transform new operator and delete operator.
14733 FunctionDecl *OperatorNew = nullptr;
14734 if (E->getOperatorNew()) {
14735 OperatorNew = cast_or_null<FunctionDecl>(
14736 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14737 if (!OperatorNew)
14738 return ExprError();
14739 }
14740
14741 FunctionDecl *OperatorDelete = nullptr;
14742 if (E->getOperatorDelete()) {
14743 OperatorDelete = cast_or_null<FunctionDecl>(
14744 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14745 if (!OperatorDelete)
14746 return ExprError();
14747 }
14748
14749 if (!getDerived().AlwaysRebuild() &&
14750 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14751 ArraySize == E->getArraySize() &&
14752 NewInit.get() == OldInit &&
14753 OperatorNew == E->getOperatorNew() &&
14754 OperatorDelete == E->getOperatorDelete() &&
14755 !ArgumentChanged) {
14756 // Mark any declarations we need as referenced.
14757 // FIXME: instantiation-specific.
14758 if (OperatorNew)
14759 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14760 if (OperatorDelete)
14761 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14762
14763 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14764 QualType ElementType
14765 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14766 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
14767 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
14768 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14769 }
14770 }
14771
14772 return E;
14773 }
14774
14775 QualType AllocType = AllocTypeInfo->getType();
14776 if (!ArraySize) {
14777 // If no array size was specified, but the new expression was
14778 // instantiated with an array type (e.g., "new T" where T is
14779 // instantiated with "int[4]"), extract the outer bound from the
14780 // array type as our array size. We do this with constant and
14781 // dependently-sized array types.
14782 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14783 if (!ArrayT) {
14784 // Do nothing
14785 } else if (const ConstantArrayType *ConsArrayT
14786 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14787 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14788 type: SemaRef.Context.getSizeType(),
14789 /*FIXME:*/ l: E->getBeginLoc());
14790 AllocType = ConsArrayT->getElementType();
14791 } else if (const DependentSizedArrayType *DepArrayT
14792 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14793 if (DepArrayT->getSizeExpr()) {
14794 ArraySize = DepArrayT->getSizeExpr();
14795 AllocType = DepArrayT->getElementType();
14796 }
14797 }
14798 }
14799
14800 return getDerived().RebuildCXXNewExpr(
14801 E->getBeginLoc(), E->isGlobalNew(),
14802 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14803 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14804 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14805}
14806
14807template<typename Derived>
14808ExprResult
14809TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14810 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14811 if (Operand.isInvalid())
14812 return ExprError();
14813
14814 // Transform the delete operator, if known.
14815 FunctionDecl *OperatorDelete = nullptr;
14816 if (E->getOperatorDelete()) {
14817 OperatorDelete = cast_or_null<FunctionDecl>(
14818 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14819 if (!OperatorDelete)
14820 return ExprError();
14821 }
14822
14823 if (!getDerived().AlwaysRebuild() &&
14824 Operand.get() == E->getArgument() &&
14825 OperatorDelete == E->getOperatorDelete()) {
14826 // Mark any declarations we need as referenced.
14827 // FIXME: instantiation-specific.
14828 if (OperatorDelete)
14829 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14830
14831 if (!E->getArgument()->isTypeDependent()) {
14832 QualType Destroyed = SemaRef.Context.getBaseElementType(
14833 QT: E->getDestroyedType());
14834 if (auto *Record = Destroyed->getAsCXXRecordDecl())
14835 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14836 Func: SemaRef.LookupDestructor(Class: Record));
14837 }
14838
14839 return E;
14840 }
14841
14842 return getDerived().RebuildCXXDeleteExpr(
14843 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14844}
14845
14846template<typename Derived>
14847ExprResult
14848TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14849 CXXPseudoDestructorExpr *E) {
14850 ExprResult Base = getDerived().TransformExpr(E->getBase());
14851 if (Base.isInvalid())
14852 return ExprError();
14853
14854 ParsedType ObjectTypePtr;
14855 bool MayBePseudoDestructor = false;
14856 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14857 OpLoc: E->getOperatorLoc(),
14858 OpKind: E->isArrow()? tok::arrow : tok::period,
14859 ObjectType&: ObjectTypePtr,
14860 MayBePseudoDestructor);
14861 if (Base.isInvalid())
14862 return ExprError();
14863
14864 QualType ObjectType = ObjectTypePtr.get();
14865 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14866 if (QualifierLoc) {
14867 QualifierLoc
14868 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14869 if (!QualifierLoc)
14870 return ExprError();
14871 }
14872 CXXScopeSpec SS;
14873 SS.Adopt(Other: QualifierLoc);
14874
14875 PseudoDestructorTypeStorage Destroyed;
14876 if (E->getDestroyedTypeInfo()) {
14877 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
14878 E->getDestroyedTypeInfo(), ObjectType,
14879 /*FirstQualifierInScope=*/nullptr);
14880 if (!DestroyedTypeInfo)
14881 return ExprError();
14882 Destroyed = DestroyedTypeInfo;
14883 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14884 // We aren't likely to be able to resolve the identifier down to a type
14885 // now anyway, so just retain the identifier.
14886 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14887 E->getDestroyedTypeLoc());
14888 } else {
14889 // Look for a destructor known with the given name.
14890 ParsedType T = SemaRef.getDestructorName(
14891 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14892 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14893 if (!T)
14894 return ExprError();
14895
14896 Destroyed
14897 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14898 Loc: E->getDestroyedTypeLoc());
14899 }
14900
14901 TypeSourceInfo *ScopeTypeInfo = nullptr;
14902 if (E->getScopeTypeInfo()) {
14903 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14904 E->getScopeTypeInfo(), ObjectType, nullptr);
14905 if (!ScopeTypeInfo)
14906 return ExprError();
14907 }
14908
14909 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14910 E->getOperatorLoc(),
14911 E->isArrow(),
14912 SS,
14913 ScopeTypeInfo,
14914 E->getColonColonLoc(),
14915 E->getTildeLoc(),
14916 Destroyed);
14917}
14918
14919template <typename Derived>
14920bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14921 bool RequiresADL,
14922 LookupResult &R) {
14923 // Transform all the decls.
14924 bool AllEmptyPacks = true;
14925 for (auto *OldD : Old->decls()) {
14926 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14927 if (!InstD) {
14928 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14929 // This can happen because of dependent hiding.
14930 if (isa<UsingShadowDecl>(Val: OldD))
14931 continue;
14932 else {
14933 R.clear();
14934 return true;
14935 }
14936 }
14937
14938 // Expand using pack declarations.
14939 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
14940 ArrayRef<NamedDecl*> Decls = SingleDecl;
14941 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
14942 Decls = UPD->expansions();
14943
14944 // Expand using declarations.
14945 for (auto *D : Decls) {
14946 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
14947 for (auto *SD : UD->shadows())
14948 R.addDecl(D: SD);
14949 } else {
14950 R.addDecl(D);
14951 }
14952 }
14953
14954 AllEmptyPacks &= Decls.empty();
14955 }
14956
14957 // C++ [temp.res]/8.4.2:
14958 // The program is ill-formed, no diagnostic required, if [...] lookup for
14959 // a name in the template definition found a using-declaration, but the
14960 // lookup in the corresponding scope in the instantiation odoes not find
14961 // any declarations because the using-declaration was a pack expansion and
14962 // the corresponding pack is empty
14963 if (AllEmptyPacks && !RequiresADL) {
14964 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14965 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
14966 return true;
14967 }
14968
14969 // Resolve a kind, but don't do any further analysis. If it's
14970 // ambiguous, the callee needs to deal with it.
14971 R.resolveKind();
14972
14973 if (Old->hasTemplateKeyword() && !R.empty()) {
14974 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14975 getSema().FilterAcceptableTemplateNames(R,
14976 /*AllowFunctionTemplates=*/true,
14977 /*AllowDependent=*/true);
14978 if (R.empty()) {
14979 // If a 'template' keyword was used, a lookup that finds only non-template
14980 // names is an error.
14981 getSema().Diag(R.getNameLoc(),
14982 diag::err_template_kw_refers_to_non_template)
14983 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14984 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14985 getSema().Diag(FoundDecl->getLocation(),
14986 diag::note_template_kw_refers_to_non_template)
14987 << R.getLookupName();
14988 return true;
14989 }
14990 }
14991
14992 return false;
14993}
14994
14995template <typename Derived>
14996ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14997 UnresolvedLookupExpr *Old) {
14998 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14999}
15000
15001template <typename Derived>
15002ExprResult
15003TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15004 bool IsAddressOfOperand) {
15005 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15006 Sema::LookupOrdinaryName);
15007
15008 // Transform the declaration set.
15009 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15010 return ExprError();
15011
15012 // Rebuild the nested-name qualifier, if present.
15013 CXXScopeSpec SS;
15014 if (Old->getQualifierLoc()) {
15015 NestedNameSpecifierLoc QualifierLoc
15016 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15017 if (!QualifierLoc)
15018 return ExprError();
15019
15020 SS.Adopt(Other: QualifierLoc);
15021 }
15022
15023 if (Old->getNamingClass()) {
15024 CXXRecordDecl *NamingClass
15025 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15026 Old->getNameLoc(),
15027 Old->getNamingClass()));
15028 if (!NamingClass) {
15029 R.clear();
15030 return ExprError();
15031 }
15032
15033 R.setNamingClass(NamingClass);
15034 }
15035
15036 // Rebuild the template arguments, if any.
15037 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15038 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15039 if (Old->hasExplicitTemplateArgs() &&
15040 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15041 Old->getNumTemplateArgs(),
15042 TransArgs)) {
15043 R.clear();
15044 return ExprError();
15045 }
15046
15047 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15048 // a non-static data member is named in an unevaluated operand, or when
15049 // a member is named in a dependent class scope function template explicit
15050 // specialization that is neither declared static nor with an explicit object
15051 // parameter.
15052 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15053 return SemaRef.BuildPossibleImplicitMemberExpr(
15054 SS, TemplateKWLoc, R,
15055 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15056 /*S=*/S: nullptr);
15057
15058 // If we have neither explicit template arguments, nor the template keyword,
15059 // it's a normal declaration name or member reference.
15060 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15061 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15062
15063 // If we have template arguments, then rebuild the template-id expression.
15064 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15065 Old->requiresADL(), &TransArgs);
15066}
15067
15068template<typename Derived>
15069ExprResult
15070TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15071 bool ArgChanged = false;
15072 SmallVector<TypeSourceInfo *, 4> Args;
15073 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15074 TypeSourceInfo *From = E->getArg(I);
15075 TypeLoc FromTL = From->getTypeLoc();
15076 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15077 TypeLocBuilder TLB;
15078 TLB.reserve(Requested: FromTL.getFullDataSize());
15079 QualType To = getDerived().TransformType(TLB, FromTL);
15080 if (To.isNull())
15081 return ExprError();
15082
15083 if (To == From->getType())
15084 Args.push_back(Elt: From);
15085 else {
15086 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15087 ArgChanged = true;
15088 }
15089 continue;
15090 }
15091
15092 ArgChanged = true;
15093
15094 // We have a pack expansion. Instantiate it.
15095 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15096 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15097 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15098 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15099
15100 // Determine whether the set of unexpanded parameter packs can and should
15101 // be expanded.
15102 bool Expand = true;
15103 bool RetainExpansion = false;
15104 UnsignedOrNone OrigNumExpansions =
15105 ExpansionTL.getTypePtr()->getNumExpansions();
15106 UnsignedOrNone NumExpansions = OrigNumExpansions;
15107 if (getDerived().TryExpandParameterPacks(
15108 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15109 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15110 RetainExpansion, NumExpansions))
15111 return ExprError();
15112
15113 if (!Expand) {
15114 // The transform has determined that we should perform a simple
15115 // transformation on the pack expansion, producing another pack
15116 // expansion.
15117 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15118
15119 TypeLocBuilder TLB;
15120 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15121
15122 QualType To = getDerived().TransformType(TLB, PatternTL);
15123 if (To.isNull())
15124 return ExprError();
15125
15126 To = getDerived().RebuildPackExpansionType(To,
15127 PatternTL.getSourceRange(),
15128 ExpansionTL.getEllipsisLoc(),
15129 NumExpansions);
15130 if (To.isNull())
15131 return ExprError();
15132
15133 PackExpansionTypeLoc ToExpansionTL
15134 = TLB.push<PackExpansionTypeLoc>(T: To);
15135 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15136 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15137 continue;
15138 }
15139
15140 // Expand the pack expansion by substituting for each argument in the
15141 // pack(s).
15142 for (unsigned I = 0; I != *NumExpansions; ++I) {
15143 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15144 TypeLocBuilder TLB;
15145 TLB.reserve(Requested: PatternTL.getFullDataSize());
15146 QualType To = getDerived().TransformType(TLB, PatternTL);
15147 if (To.isNull())
15148 return ExprError();
15149
15150 if (To->containsUnexpandedParameterPack()) {
15151 To = getDerived().RebuildPackExpansionType(To,
15152 PatternTL.getSourceRange(),
15153 ExpansionTL.getEllipsisLoc(),
15154 NumExpansions);
15155 if (To.isNull())
15156 return ExprError();
15157
15158 PackExpansionTypeLoc ToExpansionTL
15159 = TLB.push<PackExpansionTypeLoc>(T: To);
15160 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15161 }
15162
15163 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15164 }
15165
15166 if (!RetainExpansion)
15167 continue;
15168
15169 // If we're supposed to retain a pack expansion, do so by temporarily
15170 // forgetting the partially-substituted parameter pack.
15171 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15172
15173 TypeLocBuilder TLB;
15174 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15175
15176 QualType To = getDerived().TransformType(TLB, PatternTL);
15177 if (To.isNull())
15178 return ExprError();
15179
15180 To = getDerived().RebuildPackExpansionType(To,
15181 PatternTL.getSourceRange(),
15182 ExpansionTL.getEllipsisLoc(),
15183 NumExpansions);
15184 if (To.isNull())
15185 return ExprError();
15186
15187 PackExpansionTypeLoc ToExpansionTL
15188 = TLB.push<PackExpansionTypeLoc>(T: To);
15189 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15190 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15191 }
15192
15193 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15194 return E;
15195
15196 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15197 E->getEndLoc());
15198}
15199
15200template<typename Derived>
15201ExprResult
15202TreeTransform<Derived>::TransformConceptSpecializationExpr(
15203 ConceptSpecializationExpr *E) {
15204 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15205 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15206 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15207 Old->NumTemplateArgs, TransArgs))
15208 return ExprError();
15209
15210 return getDerived().RebuildConceptSpecializationExpr(
15211 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15212 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
15213 &TransArgs);
15214}
15215
15216template<typename Derived>
15217ExprResult
15218TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15219 SmallVector<ParmVarDecl*, 4> TransParams;
15220 SmallVector<QualType, 4> TransParamTypes;
15221 Sema::ExtParameterInfoBuilder ExtParamInfos;
15222
15223 // C++2a [expr.prim.req]p2
15224 // Expressions appearing within a requirement-body are unevaluated operands.
15225 EnterExpressionEvaluationContext Ctx(
15226 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15227 Sema::ReuseLambdaContextDecl);
15228
15229 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15230 C&: getSema().Context, DC: getSema().CurContext,
15231 StartLoc: E->getBody()->getBeginLoc());
15232
15233 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15234
15235 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15236 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15237 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15238
15239 for (ParmVarDecl *Param : TransParams)
15240 if (Param)
15241 Param->setDeclContext(Body);
15242
15243 // On failure to transform, TransformRequiresTypeParams returns an expression
15244 // in the event that the transformation of the type params failed in some way.
15245 // It is expected that this will result in a 'not satisfied' Requires clause
15246 // when instantiating.
15247 if (!TypeParamResult.isUnset())
15248 return TypeParamResult;
15249
15250 SmallVector<concepts::Requirement *, 4> TransReqs;
15251 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15252 TransReqs))
15253 return ExprError();
15254
15255 for (concepts::Requirement *Req : TransReqs) {
15256 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15257 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15258 ER->getReturnTypeRequirement()
15259 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15260 ->setDeclContext(Body);
15261 }
15262 }
15263 }
15264
15265 return getDerived().RebuildRequiresExpr(
15266 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15267 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15268}
15269
15270template<typename Derived>
15271bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15272 ArrayRef<concepts::Requirement *> Reqs,
15273 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15274 for (concepts::Requirement *Req : Reqs) {
15275 concepts::Requirement *TransReq = nullptr;
15276 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15277 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15278 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15279 TransReq = getDerived().TransformExprRequirement(ExprReq);
15280 else
15281 TransReq = getDerived().TransformNestedRequirement(
15282 cast<concepts::NestedRequirement>(Val: Req));
15283 if (!TransReq)
15284 return true;
15285 Transformed.push_back(Elt: TransReq);
15286 }
15287 return false;
15288}
15289
15290template<typename Derived>
15291concepts::TypeRequirement *
15292TreeTransform<Derived>::TransformTypeRequirement(
15293 concepts::TypeRequirement *Req) {
15294 if (Req->isSubstitutionFailure()) {
15295 if (getDerived().AlwaysRebuild())
15296 return getDerived().RebuildTypeRequirement(
15297 Req->getSubstitutionDiagnostic());
15298 return Req;
15299 }
15300 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15301 if (!TransType)
15302 return nullptr;
15303 return getDerived().RebuildTypeRequirement(TransType);
15304}
15305
15306template<typename Derived>
15307concepts::ExprRequirement *
15308TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15309 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15310 if (Req->isExprSubstitutionFailure())
15311 TransExpr = Req->getExprSubstitutionDiagnostic();
15312 else {
15313 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15314 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15315 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15316 if (TransExprRes.isInvalid())
15317 return nullptr;
15318 TransExpr = TransExprRes.get();
15319 }
15320
15321 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15322 const auto &RetReq = Req->getReturnTypeRequirement();
15323 if (RetReq.isEmpty())
15324 TransRetReq.emplace();
15325 else if (RetReq.isSubstitutionFailure())
15326 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15327 else if (RetReq.isTypeConstraint()) {
15328 TemplateParameterList *OrigTPL =
15329 RetReq.getTypeConstraintTemplateParameterList();
15330 TemplateParameterList *TPL =
15331 getDerived().TransformTemplateParameterList(OrigTPL);
15332 if (!TPL)
15333 return nullptr;
15334 TransRetReq.emplace(args&: TPL);
15335 }
15336 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15337 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15338 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15339 Req->getNoexceptLoc(),
15340 std::move(*TransRetReq));
15341 return getDerived().RebuildExprRequirement(
15342 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15343 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15344}
15345
15346template<typename Derived>
15347concepts::NestedRequirement *
15348TreeTransform<Derived>::TransformNestedRequirement(
15349 concepts::NestedRequirement *Req) {
15350 if (Req->hasInvalidConstraint()) {
15351 if (getDerived().AlwaysRebuild())
15352 return getDerived().RebuildNestedRequirement(
15353 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15354 return Req;
15355 }
15356 ExprResult TransConstraint =
15357 getDerived().TransformExpr(Req->getConstraintExpr());
15358 if (TransConstraint.isInvalid())
15359 return nullptr;
15360 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15361}
15362
15363template<typename Derived>
15364ExprResult
15365TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15366 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15367 if (!T)
15368 return ExprError();
15369
15370 if (!getDerived().AlwaysRebuild() &&
15371 T == E->getQueriedTypeSourceInfo())
15372 return E;
15373
15374 ExprResult SubExpr;
15375 {
15376 EnterExpressionEvaluationContext Unevaluated(
15377 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15378 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15379 if (SubExpr.isInvalid())
15380 return ExprError();
15381 }
15382
15383 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15384 SubExpr.get(), E->getEndLoc());
15385}
15386
15387template<typename Derived>
15388ExprResult
15389TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15390 ExprResult SubExpr;
15391 {
15392 EnterExpressionEvaluationContext Unevaluated(
15393 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15394 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15395 if (SubExpr.isInvalid())
15396 return ExprError();
15397
15398 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15399 return E;
15400 }
15401
15402 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15403 SubExpr.get(), E->getEndLoc());
15404}
15405
15406template <typename Derived>
15407ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15408 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15409 TypeSourceInfo **RecoveryTSI) {
15410 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15411 DRE, AddrTaken, RecoveryTSI);
15412
15413 // Propagate both errors and recovered types, which return ExprEmpty.
15414 if (!NewDRE.isUsable())
15415 return NewDRE;
15416
15417 // We got an expr, wrap it up in parens.
15418 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15419 return PE;
15420 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15421 PE->getRParen());
15422}
15423
15424template <typename Derived>
15425ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15426 DependentScopeDeclRefExpr *E) {
15427 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15428 nullptr);
15429}
15430
15431template <typename Derived>
15432ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15433 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15434 TypeSourceInfo **RecoveryTSI) {
15435 assert(E->getQualifierLoc());
15436 NestedNameSpecifierLoc QualifierLoc =
15437 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15438 if (!QualifierLoc)
15439 return ExprError();
15440 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15441
15442 // TODO: If this is a conversion-function-id, verify that the
15443 // destination type name (if present) resolves the same way after
15444 // instantiation as it did in the local scope.
15445
15446 DeclarationNameInfo NameInfo =
15447 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15448 if (!NameInfo.getName())
15449 return ExprError();
15450
15451 if (!E->hasExplicitTemplateArgs()) {
15452 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15453 // Note: it is sufficient to compare the Name component of NameInfo:
15454 // if name has not changed, DNLoc has not changed either.
15455 NameInfo.getName() == E->getDeclName())
15456 return E;
15457
15458 return getDerived().RebuildDependentScopeDeclRefExpr(
15459 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15460 IsAddressOfOperand, RecoveryTSI);
15461 }
15462
15463 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15464 if (getDerived().TransformTemplateArguments(
15465 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15466 return ExprError();
15467
15468 return getDerived().RebuildDependentScopeDeclRefExpr(
15469 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15470 RecoveryTSI);
15471}
15472
15473template<typename Derived>
15474ExprResult
15475TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15476 // CXXConstructExprs other than for list-initialization and
15477 // CXXTemporaryObjectExpr are always implicit, so when we have
15478 // a 1-argument construction we just transform that argument.
15479 if (getDerived().AllowSkippingCXXConstructExpr() &&
15480 ((E->getNumArgs() == 1 ||
15481 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15482 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15483 !E->isListInitialization()))
15484 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15485 /*DirectInit*/ false);
15486
15487 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15488
15489 QualType T = getDerived().TransformType(E->getType());
15490 if (T.isNull())
15491 return ExprError();
15492
15493 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15494 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15495 if (!Constructor)
15496 return ExprError();
15497
15498 bool ArgumentChanged = false;
15499 SmallVector<Expr*, 8> Args;
15500 {
15501 EnterExpressionEvaluationContext Context(
15502 getSema(), EnterExpressionEvaluationContext::InitList,
15503 E->isListInitialization());
15504 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15505 &ArgumentChanged))
15506 return ExprError();
15507 }
15508
15509 if (!getDerived().AlwaysRebuild() &&
15510 T == E->getType() &&
15511 Constructor == E->getConstructor() &&
15512 !ArgumentChanged) {
15513 // Mark the constructor as referenced.
15514 // FIXME: Instantiation-specific
15515 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15516 return E;
15517 }
15518
15519 return getDerived().RebuildCXXConstructExpr(
15520 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15521 E->hadMultipleCandidates(), E->isListInitialization(),
15522 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15523 E->getConstructionKind(), E->getParenOrBraceRange());
15524}
15525
15526template<typename Derived>
15527ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15528 CXXInheritedCtorInitExpr *E) {
15529 QualType T = getDerived().TransformType(E->getType());
15530 if (T.isNull())
15531 return ExprError();
15532
15533 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15534 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15535 if (!Constructor)
15536 return ExprError();
15537
15538 if (!getDerived().AlwaysRebuild() &&
15539 T == E->getType() &&
15540 Constructor == E->getConstructor()) {
15541 // Mark the constructor as referenced.
15542 // FIXME: Instantiation-specific
15543 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15544 return E;
15545 }
15546
15547 return getDerived().RebuildCXXInheritedCtorInitExpr(
15548 T, E->getLocation(), Constructor,
15549 E->constructsVBase(), E->inheritedFromVBase());
15550}
15551
15552/// Transform a C++ temporary-binding expression.
15553///
15554/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15555/// transform the subexpression and return that.
15556template<typename Derived>
15557ExprResult
15558TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15559 if (auto *Dtor = E->getTemporary()->getDestructor())
15560 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15561 Func: const_cast<CXXDestructorDecl *>(Dtor));
15562 return getDerived().TransformExpr(E->getSubExpr());
15563}
15564
15565/// Transform a C++ expression that contains cleanups that should
15566/// be run after the expression is evaluated.
15567///
15568/// Since ExprWithCleanups nodes are implicitly generated, we
15569/// just transform the subexpression and return that.
15570template<typename Derived>
15571ExprResult
15572TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15573 return getDerived().TransformExpr(E->getSubExpr());
15574}
15575
15576template<typename Derived>
15577ExprResult
15578TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15579 CXXTemporaryObjectExpr *E) {
15580 TypeSourceInfo *T =
15581 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15582 if (!T)
15583 return ExprError();
15584
15585 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15586 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15587 if (!Constructor)
15588 return ExprError();
15589
15590 bool ArgumentChanged = false;
15591 SmallVector<Expr*, 8> Args;
15592 Args.reserve(N: E->getNumArgs());
15593 {
15594 EnterExpressionEvaluationContext Context(
15595 getSema(), EnterExpressionEvaluationContext::InitList,
15596 E->isListInitialization());
15597 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15598 ArgChanged: &ArgumentChanged))
15599 return ExprError();
15600
15601 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15602 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15603 if (Res.isInvalid())
15604 return ExprError();
15605 Args = {Res.get()};
15606 }
15607 }
15608
15609 if (!getDerived().AlwaysRebuild() &&
15610 T == E->getTypeSourceInfo() &&
15611 Constructor == E->getConstructor() &&
15612 !ArgumentChanged) {
15613 // FIXME: Instantiation-specific
15614 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15615 return SemaRef.MaybeBindToTemporary(E);
15616 }
15617
15618 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15619 return getDerived().RebuildCXXTemporaryObjectExpr(
15620 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15621}
15622
15623template<typename Derived>
15624ExprResult
15625TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15626 // Transform any init-capture expressions before entering the scope of the
15627 // lambda body, because they are not semantically within that scope.
15628 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15629 struct TransformedInitCapture {
15630 // The location of the ... if the result is retaining a pack expansion.
15631 SourceLocation EllipsisLoc;
15632 // Zero or more expansions of the init-capture.
15633 SmallVector<InitCaptureInfoTy, 4> Expansions;
15634 };
15635 SmallVector<TransformedInitCapture, 4> InitCaptures;
15636 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15637 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15638 CEnd = E->capture_end();
15639 C != CEnd; ++C) {
15640 if (!E->isInitCapture(Capture: C))
15641 continue;
15642
15643 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15644 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15645
15646 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15647 UnsignedOrNone NumExpansions) {
15648 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15649 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15650
15651 if (NewExprInitResult.isInvalid()) {
15652 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15653 return;
15654 }
15655 Expr *NewExprInit = NewExprInitResult.get();
15656
15657 QualType NewInitCaptureType =
15658 getSema().buildLambdaInitCaptureInitialization(
15659 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15660 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15661 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15662 VarDecl::CInit,
15663 NewExprInit);
15664 Result.Expansions.push_back(
15665 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15666 };
15667
15668 // If this is an init-capture pack, consider expanding the pack now.
15669 if (OldVD->isParameterPack()) {
15670 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15671 ->getTypeLoc()
15672 .castAs<PackExpansionTypeLoc>();
15673 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15674 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15675
15676 // Determine whether the set of unexpanded parameter packs can and should
15677 // be expanded.
15678 bool Expand = true;
15679 bool RetainExpansion = false;
15680 UnsignedOrNone OrigNumExpansions =
15681 ExpansionTL.getTypePtr()->getNumExpansions();
15682 UnsignedOrNone NumExpansions = OrigNumExpansions;
15683 if (getDerived().TryExpandParameterPacks(
15684 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
15685 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15686 RetainExpansion, NumExpansions))
15687 return ExprError();
15688 assert(!RetainExpansion && "Should not need to retain expansion after a "
15689 "capture since it cannot be extended");
15690 if (Expand) {
15691 for (unsigned I = 0; I != *NumExpansions; ++I) {
15692 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15693 SubstInitCapture(SourceLocation(), std::nullopt);
15694 }
15695 } else {
15696 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15697 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15698 }
15699 } else {
15700 SubstInitCapture(SourceLocation(), std::nullopt);
15701 }
15702 }
15703
15704 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15705 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15706
15707 // Create the local class that will describe the lambda.
15708
15709 // FIXME: DependencyKind below is wrong when substituting inside a templated
15710 // context that isn't a DeclContext (such as a variable template), or when
15711 // substituting an unevaluated lambda inside of a function's parameter's type
15712 // - as parameter types are not instantiated from within a function's DC. We
15713 // use evaluation contexts to distinguish the function parameter case.
15714 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15715 CXXRecordDecl::LDK_Unknown;
15716 DeclContext *DC = getSema().CurContext;
15717 // A RequiresExprBodyDecl is not interesting for dependencies.
15718 // For the following case,
15719 //
15720 // template <typename>
15721 // concept C = requires { [] {}; };
15722 //
15723 // template <class F>
15724 // struct Widget;
15725 //
15726 // template <C F>
15727 // struct Widget<F> {};
15728 //
15729 // While we are substituting Widget<F>, the parent of DC would be
15730 // the template specialization itself. Thus, the lambda expression
15731 // will be deemed as dependent even if there are no dependent template
15732 // arguments.
15733 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15734 while (DC->isRequiresExprBody())
15735 DC = DC->getParent();
15736 if ((getSema().isUnevaluatedContext() ||
15737 getSema().isConstantEvaluatedContext()) &&
15738 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
15739 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
15740 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15741 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15742
15743 CXXRecordDecl *OldClass = E->getLambdaClass();
15744 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15745 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15746 E->getCaptureDefault());
15747 getDerived().transformedLocalDecl(OldClass, {Class});
15748
15749 CXXMethodDecl *NewCallOperator =
15750 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15751
15752 // Enter the scope of the lambda.
15753 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15754 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15755 E->hasExplicitParameters(), E->isMutable());
15756
15757 // Introduce the context of the call operator.
15758 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15759 /*NewThisContext*/false);
15760
15761 bool Invalid = false;
15762
15763 // Transform captures.
15764 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15765 CEnd = E->capture_end();
15766 C != CEnd; ++C) {
15767 // When we hit the first implicit capture, tell Sema that we've finished
15768 // the list of explicit captures.
15769 if (C->isImplicit())
15770 break;
15771
15772 // Capturing 'this' is trivial.
15773 if (C->capturesThis()) {
15774 // If this is a lambda that is part of a default member initialiser
15775 // and which we're instantiating outside the class that 'this' is
15776 // supposed to refer to, adjust the type of 'this' accordingly.
15777 //
15778 // Otherwise, leave the type of 'this' as-is.
15779 Sema::CXXThisScopeRAII ThisScope(
15780 getSema(),
15781 dyn_cast_if_present<CXXRecordDecl>(
15782 getSema().getFunctionLevelDeclContext()),
15783 Qualifiers());
15784 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15785 /*BuildAndDiagnose*/ true, nullptr,
15786 C->getCaptureKind() == LCK_StarThis);
15787 continue;
15788 }
15789 // Captured expression will be recaptured during captured variables
15790 // rebuilding.
15791 if (C->capturesVLAType())
15792 continue;
15793
15794 // Rebuild init-captures, including the implied field declaration.
15795 if (E->isInitCapture(Capture: C)) {
15796 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15797
15798 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15799 llvm::SmallVector<Decl*, 4> NewVDs;
15800
15801 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15802 ExprResult Init = Info.first;
15803 QualType InitQualType = Info.second;
15804 if (Init.isInvalid() || InitQualType.isNull()) {
15805 Invalid = true;
15806 break;
15807 }
15808 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15809 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15810 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15811 getSema().CurContext);
15812 if (!NewVD) {
15813 Invalid = true;
15814 break;
15815 }
15816 NewVDs.push_back(Elt: NewVD);
15817 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15818 // Cases we want to tackle:
15819 // ([C(Pack)] {}, ...)
15820 // But rule out cases e.g.
15821 // [...C = Pack()] {}
15822 if (NewC.EllipsisLoc.isInvalid())
15823 LSI->ContainsUnexpandedParameterPack |=
15824 Init.get()->containsUnexpandedParameterPack();
15825 }
15826
15827 if (Invalid)
15828 break;
15829
15830 getDerived().transformedLocalDecl(OldVD, NewVDs);
15831 continue;
15832 }
15833
15834 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15835
15836 // Determine the capture kind for Sema.
15837 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15838 : C->getCaptureKind() == LCK_ByCopy
15839 ? TryCaptureKind::ExplicitByVal
15840 : TryCaptureKind::ExplicitByRef;
15841 SourceLocation EllipsisLoc;
15842 if (C->isPackExpansion()) {
15843 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15844 bool ShouldExpand = false;
15845 bool RetainExpansion = false;
15846 UnsignedOrNone NumExpansions = std::nullopt;
15847 if (getDerived().TryExpandParameterPacks(
15848 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
15849 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
15850 RetainExpansion, NumExpansions)) {
15851 Invalid = true;
15852 continue;
15853 }
15854
15855 if (ShouldExpand) {
15856 // The transform has determined that we should perform an expansion;
15857 // transform and capture each of the arguments.
15858 // expansion of the pattern. Do so.
15859 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
15860 for (unsigned I = 0; I != *NumExpansions; ++I) {
15861 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15862 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15863 getDerived().TransformDecl(C->getLocation(), Pack));
15864 if (!CapturedVar) {
15865 Invalid = true;
15866 continue;
15867 }
15868
15869 // Capture the transformed variable.
15870 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15871 }
15872
15873 // FIXME: Retain a pack expansion if RetainExpansion is true.
15874
15875 continue;
15876 }
15877
15878 EllipsisLoc = C->getEllipsisLoc();
15879 }
15880
15881 // Transform the captured variable.
15882 auto *CapturedVar = cast_or_null<ValueDecl>(
15883 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15884 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15885 Invalid = true;
15886 continue;
15887 }
15888
15889 // This is not an init-capture; however it contains an unexpanded pack e.g.
15890 // ([Pack] {}(), ...)
15891 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15892 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15893
15894 // Capture the transformed variable.
15895 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15896 EllipsisLoc);
15897 }
15898 getSema().finishLambdaExplicitCaptures(LSI);
15899
15900 // Transform the template parameters, and add them to the current
15901 // instantiation scope. The null case is handled correctly.
15902 auto TPL = getDerived().TransformTemplateParameterList(
15903 E->getTemplateParameterList());
15904 LSI->GLTemplateParameterList = TPL;
15905 if (TPL) {
15906 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15907 TPL);
15908 LSI->ContainsUnexpandedParameterPack |=
15909 TPL->containsUnexpandedParameterPack();
15910 }
15911
15912 TypeLocBuilder NewCallOpTLBuilder;
15913 TypeLoc OldCallOpTypeLoc =
15914 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15915 QualType NewCallOpType =
15916 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15917 if (NewCallOpType.isNull())
15918 return ExprError();
15919 LSI->ContainsUnexpandedParameterPack |=
15920 NewCallOpType->containsUnexpandedParameterPack();
15921 TypeSourceInfo *NewCallOpTSI =
15922 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
15923
15924 // The type may be an AttributedType or some other kind of sugar;
15925 // get the actual underlying FunctionProtoType.
15926 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15927 assert(FPTL && "Not a FunctionProtoType?");
15928
15929 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15930 if (!TRC.ArgPackSubstIndex)
15931 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15932
15933 getSema().CompleteLambdaCallOperator(
15934 NewCallOperator, E->getCallOperator()->getLocation(),
15935 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15936 E->getCallOperator()->getConstexprKind(),
15937 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15938 E->hasExplicitResultType());
15939
15940 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15941 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15942
15943 {
15944 // Number the lambda for linkage purposes if necessary.
15945 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15946
15947 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15948 if (getDerived().ReplacingOriginal()) {
15949 Numbering = OldClass->getLambdaNumbering();
15950 }
15951
15952 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15953 }
15954
15955 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15956 // evaluation context even if we're not transforming the function body.
15957 getSema().PushExpressionEvaluationContextForFunction(
15958 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
15959 E->getCallOperator());
15960
15961 StmtResult Body;
15962 {
15963 Sema::NonSFINAEContext _(getSema());
15964 Sema::CodeSynthesisContext C;
15965 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15966 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15967 getSema().pushCodeSynthesisContext(C);
15968
15969 // Instantiate the body of the lambda expression.
15970 Body = Invalid ? StmtError()
15971 : getDerived().TransformLambdaBody(E, E->getBody());
15972
15973 getSema().popCodeSynthesisContext();
15974 }
15975
15976 // ActOnLambda* will pop the function scope for us.
15977 FuncScopeCleanup.disable();
15978
15979 if (Body.isInvalid()) {
15980 SavedContext.pop();
15981 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15982 /*IsInstantiation=*/true);
15983 return ExprError();
15984 }
15985
15986 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15987 /*IsInstantiation=*/true,
15988 /*RetainFunctionScopeInfo=*/true);
15989 SavedContext.pop();
15990
15991 // Recompute the dependency of the lambda so that we can defer the lambda call
15992 // construction until after we have all the necessary template arguments. For
15993 // example, given
15994 //
15995 // template <class> struct S {
15996 // template <class U>
15997 // using Type = decltype([](U){}(42.0));
15998 // };
15999 // void foo() {
16000 // using T = S<int>::Type<float>;
16001 // ^~~~~~
16002 // }
16003 //
16004 // We would end up here from instantiating S<int> when ensuring its
16005 // completeness. That would transform the lambda call expression regardless of
16006 // the absence of the corresponding argument for U.
16007 //
16008 // Going ahead with unsubstituted type U makes things worse: we would soon
16009 // compare the argument type (which is float) against the parameter U
16010 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16011 // error suggesting unmatched types 'U' and 'float'!
16012 //
16013 // That said, everything will be fine if we defer that semantic checking.
16014 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16015 // dependent. Since the CallExpr's dependency boils down to the lambda's
16016 // dependency in this case, we can harness that by recomputing the dependency
16017 // from the instantiation arguments.
16018 //
16019 // FIXME: Creating the type of a lambda requires us to have a dependency
16020 // value, which happens before its substitution. We update its dependency
16021 // *after* the substitution in case we can't decide the dependency
16022 // so early, e.g. because we want to see if any of the *substituted*
16023 // parameters are dependent.
16024 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16025 Class->setLambdaDependencyKind(DependencyKind);
16026
16027 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16028 Body.get()->getEndLoc(), LSI);
16029}
16030
16031template<typename Derived>
16032StmtResult
16033TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16034 return TransformStmt(S);
16035}
16036
16037template<typename Derived>
16038StmtResult
16039TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16040 // Transform captures.
16041 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16042 CEnd = E->capture_end();
16043 C != CEnd; ++C) {
16044 // When we hit the first implicit capture, tell Sema that we've finished
16045 // the list of explicit captures.
16046 if (!C->isImplicit())
16047 continue;
16048
16049 // Capturing 'this' is trivial.
16050 if (C->capturesThis()) {
16051 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16052 /*BuildAndDiagnose*/ true, nullptr,
16053 C->getCaptureKind() == LCK_StarThis);
16054 continue;
16055 }
16056 // Captured expression will be recaptured during captured variables
16057 // rebuilding.
16058 if (C->capturesVLAType())
16059 continue;
16060
16061 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16062 assert(!E->isInitCapture(C) && "implicit init-capture?");
16063
16064 // Transform the captured variable.
16065 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16066 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16067 if (!CapturedVar || CapturedVar->isInvalidDecl())
16068 return StmtError();
16069
16070 // Capture the transformed variable.
16071 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16072 }
16073
16074 return S;
16075}
16076
16077template<typename Derived>
16078ExprResult
16079TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16080 CXXUnresolvedConstructExpr *E) {
16081 TypeSourceInfo *T =
16082 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16083 if (!T)
16084 return ExprError();
16085
16086 bool ArgumentChanged = false;
16087 SmallVector<Expr*, 8> Args;
16088 Args.reserve(N: E->getNumArgs());
16089 {
16090 EnterExpressionEvaluationContext Context(
16091 getSema(), EnterExpressionEvaluationContext::InitList,
16092 E->isListInitialization());
16093 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16094 &ArgumentChanged))
16095 return ExprError();
16096 }
16097
16098 if (!getDerived().AlwaysRebuild() &&
16099 T == E->getTypeSourceInfo() &&
16100 !ArgumentChanged)
16101 return E;
16102
16103 // FIXME: we're faking the locations of the commas
16104 return getDerived().RebuildCXXUnresolvedConstructExpr(
16105 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16106}
16107
16108template<typename Derived>
16109ExprResult
16110TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16111 CXXDependentScopeMemberExpr *E) {
16112 // Transform the base of the expression.
16113 ExprResult Base((Expr*) nullptr);
16114 Expr *OldBase;
16115 QualType BaseType;
16116 QualType ObjectType;
16117 if (!E->isImplicitAccess()) {
16118 OldBase = E->getBase();
16119 Base = getDerived().TransformExpr(OldBase);
16120 if (Base.isInvalid())
16121 return ExprError();
16122
16123 // Start the member reference and compute the object's type.
16124 ParsedType ObjectTy;
16125 bool MayBePseudoDestructor = false;
16126 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16127 OpLoc: E->getOperatorLoc(),
16128 OpKind: E->isArrow()? tok::arrow : tok::period,
16129 ObjectType&: ObjectTy,
16130 MayBePseudoDestructor);
16131 if (Base.isInvalid())
16132 return ExprError();
16133
16134 ObjectType = ObjectTy.get();
16135 BaseType = ((Expr*) Base.get())->getType();
16136 } else {
16137 OldBase = nullptr;
16138 BaseType = getDerived().TransformType(E->getBaseType());
16139 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16140 }
16141
16142 // Transform the first part of the nested-name-specifier that qualifies
16143 // the member name.
16144 NamedDecl *FirstQualifierInScope
16145 = getDerived().TransformFirstQualifierInScope(
16146 E->getFirstQualifierFoundInScope(),
16147 E->getQualifierLoc().getBeginLoc());
16148
16149 NestedNameSpecifierLoc QualifierLoc;
16150 if (E->getQualifier()) {
16151 QualifierLoc
16152 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16153 ObjectType,
16154 FirstQualifierInScope);
16155 if (!QualifierLoc)
16156 return ExprError();
16157 }
16158
16159 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16160
16161 // TODO: If this is a conversion-function-id, verify that the
16162 // destination type name (if present) resolves the same way after
16163 // instantiation as it did in the local scope.
16164
16165 DeclarationNameInfo NameInfo
16166 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16167 if (!NameInfo.getName())
16168 return ExprError();
16169
16170 if (!E->hasExplicitTemplateArgs()) {
16171 // This is a reference to a member without an explicitly-specified
16172 // template argument list. Optimize for this common case.
16173 if (!getDerived().AlwaysRebuild() &&
16174 Base.get() == OldBase &&
16175 BaseType == E->getBaseType() &&
16176 QualifierLoc == E->getQualifierLoc() &&
16177 NameInfo.getName() == E->getMember() &&
16178 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16179 return E;
16180
16181 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16182 BaseType,
16183 E->isArrow(),
16184 E->getOperatorLoc(),
16185 QualifierLoc,
16186 TemplateKWLoc,
16187 FirstQualifierInScope,
16188 NameInfo,
16189 /*TemplateArgs*/nullptr);
16190 }
16191
16192 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16193 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16194 E->getNumTemplateArgs(),
16195 TransArgs))
16196 return ExprError();
16197
16198 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16199 BaseType,
16200 E->isArrow(),
16201 E->getOperatorLoc(),
16202 QualifierLoc,
16203 TemplateKWLoc,
16204 FirstQualifierInScope,
16205 NameInfo,
16206 &TransArgs);
16207}
16208
16209template <typename Derived>
16210ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16211 UnresolvedMemberExpr *Old) {
16212 // Transform the base of the expression.
16213 ExprResult Base((Expr *)nullptr);
16214 QualType BaseType;
16215 if (!Old->isImplicitAccess()) {
16216 Base = getDerived().TransformExpr(Old->getBase());
16217 if (Base.isInvalid())
16218 return ExprError();
16219 Base =
16220 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16221 if (Base.isInvalid())
16222 return ExprError();
16223 BaseType = Base.get()->getType();
16224 } else {
16225 BaseType = getDerived().TransformType(Old->getBaseType());
16226 }
16227
16228 NestedNameSpecifierLoc QualifierLoc;
16229 if (Old->getQualifierLoc()) {
16230 QualifierLoc =
16231 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16232 if (!QualifierLoc)
16233 return ExprError();
16234 }
16235
16236 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16237
16238 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16239
16240 // Transform the declaration set.
16241 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16242 return ExprError();
16243
16244 // Determine the naming class.
16245 if (Old->getNamingClass()) {
16246 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16247 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16248 if (!NamingClass)
16249 return ExprError();
16250
16251 R.setNamingClass(NamingClass);
16252 }
16253
16254 TemplateArgumentListInfo TransArgs;
16255 if (Old->hasExplicitTemplateArgs()) {
16256 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16257 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16258 if (getDerived().TransformTemplateArguments(
16259 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16260 return ExprError();
16261 }
16262
16263 // FIXME: to do this check properly, we will need to preserve the
16264 // first-qualifier-in-scope here, just in case we had a dependent
16265 // base (and therefore couldn't do the check) and a
16266 // nested-name-qualifier (and therefore could do the lookup).
16267 NamedDecl *FirstQualifierInScope = nullptr;
16268
16269 return getDerived().RebuildUnresolvedMemberExpr(
16270 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16271 TemplateKWLoc, FirstQualifierInScope, R,
16272 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16273}
16274
16275template<typename Derived>
16276ExprResult
16277TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16278 EnterExpressionEvaluationContext Unevaluated(
16279 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16280 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16281 if (SubExpr.isInvalid())
16282 return ExprError();
16283
16284 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16285 return E;
16286
16287 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16288}
16289
16290template<typename Derived>
16291ExprResult
16292TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16293 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16294 if (Pattern.isInvalid())
16295 return ExprError();
16296
16297 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16298 return E;
16299
16300 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16301 E->getNumExpansions());
16302}
16303
16304template <typename Derived>
16305UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16306 ArrayRef<TemplateArgument> PackArgs) {
16307 UnsignedOrNone Result = 0u;
16308 for (const TemplateArgument &Arg : PackArgs) {
16309 if (!Arg.isPackExpansion()) {
16310 Result = *Result + 1;
16311 continue;
16312 }
16313
16314 TemplateArgumentLoc ArgLoc;
16315 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16316
16317 // Find the pattern of the pack expansion.
16318 SourceLocation Ellipsis;
16319 UnsignedOrNone OrigNumExpansions = std::nullopt;
16320 TemplateArgumentLoc Pattern =
16321 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16322 OrigNumExpansions);
16323
16324 // Substitute under the pack expansion. Do not expand the pack (yet).
16325 TemplateArgumentLoc OutPattern;
16326 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16327 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16328 /*Uneval*/ true))
16329 return 1u;
16330
16331 // See if we can determine the number of arguments from the result.
16332 UnsignedOrNone NumExpansions =
16333 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16334 if (!NumExpansions) {
16335 // No: we must be in an alias template expansion, and we're going to
16336 // need to actually expand the packs.
16337 Result = std::nullopt;
16338 break;
16339 }
16340
16341 Result = *Result + *NumExpansions;
16342 }
16343 return Result;
16344}
16345
16346template<typename Derived>
16347ExprResult
16348TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16349 // If E is not value-dependent, then nothing will change when we transform it.
16350 // Note: This is an instantiation-centric view.
16351 if (!E->isValueDependent())
16352 return E;
16353
16354 EnterExpressionEvaluationContext Unevaluated(
16355 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16356
16357 ArrayRef<TemplateArgument> PackArgs;
16358 TemplateArgument ArgStorage;
16359
16360 // Find the argument list to transform.
16361 if (E->isPartiallySubstituted()) {
16362 PackArgs = E->getPartialArguments();
16363 } else if (E->isValueDependent()) {
16364 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16365 bool ShouldExpand = false;
16366 bool RetainExpansion = false;
16367 UnsignedOrNone NumExpansions = std::nullopt;
16368 if (getDerived().TryExpandParameterPacks(
16369 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16370 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16371 RetainExpansion, NumExpansions))
16372 return ExprError();
16373
16374 // If we need to expand the pack, build a template argument from it and
16375 // expand that.
16376 if (ShouldExpand) {
16377 auto *Pack = E->getPack();
16378 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16379 ArgStorage = getSema().Context.getPackExpansionType(
16380 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16381 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16382 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16383 } else {
16384 auto *VD = cast<ValueDecl>(Val: Pack);
16385 ExprResult DRE = getSema().BuildDeclRefExpr(
16386 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16387 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16388 E->getPackLoc());
16389 if (DRE.isInvalid())
16390 return ExprError();
16391 ArgStorage = TemplateArgument(
16392 new (getSema().Context)
16393 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16394 /*IsCanonical=*/false);
16395 }
16396 PackArgs = ArgStorage;
16397 }
16398 }
16399
16400 // If we're not expanding the pack, just transform the decl.
16401 if (!PackArgs.size()) {
16402 auto *Pack = cast_or_null<NamedDecl>(
16403 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16404 if (!Pack)
16405 return ExprError();
16406 return getDerived().RebuildSizeOfPackExpr(
16407 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16408 std::nullopt, {});
16409 }
16410
16411 // Try to compute the result without performing a partial substitution.
16412 UnsignedOrNone Result =
16413 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16414
16415 // Common case: we could determine the number of expansions without
16416 // substituting.
16417 if (Result)
16418 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16419 E->getPackLoc(),
16420 E->getRParenLoc(), *Result, {});
16421
16422 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16423 E->getPackLoc());
16424 {
16425 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16426 typedef TemplateArgumentLocInventIterator<
16427 Derived, const TemplateArgument*> PackLocIterator;
16428 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16429 PackLocIterator(*this, PackArgs.end()),
16430 TransformedPackArgs, /*Uneval*/true))
16431 return ExprError();
16432 }
16433
16434 // Check whether we managed to fully-expand the pack.
16435 // FIXME: Is it possible for us to do so and not hit the early exit path?
16436 SmallVector<TemplateArgument, 8> Args;
16437 bool PartialSubstitution = false;
16438 for (auto &Loc : TransformedPackArgs.arguments()) {
16439 Args.push_back(Elt: Loc.getArgument());
16440 if (Loc.getArgument().isPackExpansion())
16441 PartialSubstitution = true;
16442 }
16443
16444 if (PartialSubstitution)
16445 return getDerived().RebuildSizeOfPackExpr(
16446 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16447 std::nullopt, Args);
16448
16449 return getDerived().RebuildSizeOfPackExpr(
16450 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16451 /*Length=*/static_cast<unsigned>(Args.size()),
16452 /*PartialArgs=*/{});
16453}
16454
16455template <typename Derived>
16456ExprResult
16457TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16458 if (!E->isValueDependent())
16459 return E;
16460
16461 // Transform the index
16462 ExprResult IndexExpr;
16463 {
16464 EnterExpressionEvaluationContext ConstantContext(
16465 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16466 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16467 if (IndexExpr.isInvalid())
16468 return ExprError();
16469 }
16470
16471 SmallVector<Expr *, 5> ExpandedExprs;
16472 bool FullySubstituted = true;
16473 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16474 Expr *Pattern = E->getPackIdExpression();
16475 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16476 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16477 Unexpanded);
16478 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16479
16480 // Determine whether the set of unexpanded parameter packs can and should
16481 // be expanded.
16482 bool ShouldExpand = true;
16483 bool RetainExpansion = false;
16484 UnsignedOrNone OrigNumExpansions = std::nullopt,
16485 NumExpansions = std::nullopt;
16486 if (getDerived().TryExpandParameterPacks(
16487 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16488 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16489 RetainExpansion, NumExpansions))
16490 return true;
16491 if (!ShouldExpand) {
16492 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16493 ExprResult Pack = getDerived().TransformExpr(Pattern);
16494 if (Pack.isInvalid())
16495 return ExprError();
16496 return getDerived().RebuildPackIndexingExpr(
16497 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16498 {}, /*FullySubstituted=*/false);
16499 }
16500 for (unsigned I = 0; I != *NumExpansions; ++I) {
16501 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16502 ExprResult Out = getDerived().TransformExpr(Pattern);
16503 if (Out.isInvalid())
16504 return true;
16505 if (Out.get()->containsUnexpandedParameterPack()) {
16506 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16507 OrigNumExpansions);
16508 if (Out.isInvalid())
16509 return true;
16510 FullySubstituted = false;
16511 }
16512 ExpandedExprs.push_back(Elt: Out.get());
16513 }
16514 // If we're supposed to retain a pack expansion, do so by temporarily
16515 // forgetting the partially-substituted parameter pack.
16516 if (RetainExpansion) {
16517 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16518
16519 ExprResult Out = getDerived().TransformExpr(Pattern);
16520 if (Out.isInvalid())
16521 return true;
16522
16523 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16524 OrigNumExpansions);
16525 if (Out.isInvalid())
16526 return true;
16527 FullySubstituted = false;
16528 ExpandedExprs.push_back(Elt: Out.get());
16529 }
16530 } else if (!E->expandsToEmptyPack()) {
16531 if (getDerived().TransformExprs(E->getExpressions().data(),
16532 E->getExpressions().size(), false,
16533 ExpandedExprs))
16534 return ExprError();
16535 }
16536
16537 return getDerived().RebuildPackIndexingExpr(
16538 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16539 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16540}
16541
16542template <typename Derived>
16543ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16544 SubstNonTypeTemplateParmPackExpr *E) {
16545 if (!getSema().ArgPackSubstIndex)
16546 // We aren't expanding the parameter pack, so just return ourselves.
16547 return E;
16548
16549 TemplateArgument Pack = E->getArgumentPack();
16550 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
16551 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16552 E->getAssociatedDecl(), E->getParameterPack(),
16553 E->getParameterPackLocation(), Arg, SemaRef.getPackIndex(Pack),
16554 E->getFinal());
16555}
16556
16557template <typename Derived>
16558ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16559 SubstNonTypeTemplateParmExpr *E) {
16560 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
16561 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
16562 if (Replacement.isInvalid())
16563 return true;
16564
16565 Decl *AssociatedDecl =
16566 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
16567 if (!AssociatedDecl)
16568 return true;
16569
16570 if (Replacement.get() == OrigReplacement &&
16571 AssociatedDecl == E->getAssociatedDecl())
16572 return E;
16573
16574 auto getParamAndType = [E](Decl *AssociatedDecl)
16575 -> std::tuple<NonTypeTemplateParmDecl *, QualType> {
16576 auto [PDecl, Arg] =
16577 getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex());
16578 auto *Param = cast<NonTypeTemplateParmDecl>(Val: PDecl);
16579 if (Arg.isNull())
16580 return {Param, Param->getType()};
16581 if (UnsignedOrNone PackIndex = E->getPackIndex())
16582 Arg = Arg.getPackAsArray()[*PackIndex];
16583 return {Param, Arg.getNonTypeTemplateArgumentType()};
16584 };
16585
16586 // If the replacement expression did not change, and the parameter type
16587 // did not change, we can skip the semantic action because it would
16588 // produce the same result anyway.
16589 if (auto [Param, ParamType] = getParamAndType(AssociatedDecl);
16590 !SemaRef.Context.hasSameType(
16591 ParamType, std::get<1>(getParamAndType(E->getAssociatedDecl()))) ||
16592 Replacement.get() != OrigReplacement) {
16593 // When transforming the replacement expression previously, all Sema
16594 // specific annotations, such as implicit casts, are discarded. Calling the
16595 // corresponding sema action is necessary to recover those. Otherwise,
16596 // equivalency of the result would be lost.
16597 TemplateArgument SugaredConverted, CanonicalConverted;
16598 Replacement = SemaRef.CheckTemplateArgument(
16599 Param, ParamType, Replacement.get(), SugaredConverted,
16600 CanonicalConverted,
16601 /*StrictCheck=*/false, Sema::CTAK_Specified);
16602 if (Replacement.isInvalid())
16603 return true;
16604 } else {
16605 // Otherwise, the same expression would have been produced.
16606 Replacement = E->getReplacement();
16607 }
16608
16609 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16610 AssociatedDecl, E->getParameter(), E->getNameLoc(),
16611 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
16612 E->getPackIndex(), E->getFinal());
16613}
16614
16615template<typename Derived>
16616ExprResult
16617TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16618 // Default behavior is to do nothing with this transformation.
16619 return E;
16620}
16621
16622template<typename Derived>
16623ExprResult
16624TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16625 MaterializeTemporaryExpr *E) {
16626 return getDerived().TransformExpr(E->getSubExpr());
16627}
16628
16629template<typename Derived>
16630ExprResult
16631TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16632 UnresolvedLookupExpr *Callee = nullptr;
16633 if (Expr *OldCallee = E->getCallee()) {
16634 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16635 if (CalleeResult.isInvalid())
16636 return ExprError();
16637 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16638 }
16639
16640 Expr *Pattern = E->getPattern();
16641
16642 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16643 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16644 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16645
16646 // Determine whether the set of unexpanded parameter packs can and should
16647 // be expanded.
16648 bool Expand = true;
16649 bool RetainExpansion = false;
16650 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16651 NumExpansions = OrigNumExpansions;
16652 if (getDerived().TryExpandParameterPacks(
16653 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16654 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16655 NumExpansions))
16656 return true;
16657
16658 if (!Expand) {
16659 // Do not expand any packs here, just transform and rebuild a fold
16660 // expression.
16661 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16662
16663 ExprResult LHS =
16664 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16665 if (LHS.isInvalid())
16666 return true;
16667
16668 ExprResult RHS =
16669 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16670 if (RHS.isInvalid())
16671 return true;
16672
16673 if (!getDerived().AlwaysRebuild() &&
16674 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16675 return E;
16676
16677 return getDerived().RebuildCXXFoldExpr(
16678 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16679 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16680 }
16681
16682 // Formally a fold expression expands to nested parenthesized expressions.
16683 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16684 // them.
16685 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16686 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16687 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16688 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16689 << E->getSourceRange();
16690 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16691 return ExprError();
16692 }
16693
16694 // The transform has determined that we should perform an elementwise
16695 // expansion of the pattern. Do so.
16696 ExprResult Result = getDerived().TransformExpr(E->getInit());
16697 if (Result.isInvalid())
16698 return true;
16699 bool LeftFold = E->isLeftFold();
16700
16701 // If we're retaining an expansion for a right fold, it is the innermost
16702 // component and takes the init (if any).
16703 if (!LeftFold && RetainExpansion) {
16704 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16705
16706 ExprResult Out = getDerived().TransformExpr(Pattern);
16707 if (Out.isInvalid())
16708 return true;
16709
16710 Result = getDerived().RebuildCXXFoldExpr(
16711 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16712 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16713 if (Result.isInvalid())
16714 return true;
16715 }
16716
16717 bool WarnedOnComparison = false;
16718 for (unsigned I = 0; I != *NumExpansions; ++I) {
16719 Sema::ArgPackSubstIndexRAII SubstIndex(
16720 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16721 ExprResult Out = getDerived().TransformExpr(Pattern);
16722 if (Out.isInvalid())
16723 return true;
16724
16725 if (Out.get()->containsUnexpandedParameterPack()) {
16726 // We still have a pack; retain a pack expansion for this slice.
16727 Result = getDerived().RebuildCXXFoldExpr(
16728 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16729 E->getOperator(), E->getEllipsisLoc(),
16730 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16731 OrigNumExpansions);
16732 } else if (Result.isUsable()) {
16733 // We've got down to a single element; build a binary operator.
16734 Expr *LHS = LeftFold ? Result.get() : Out.get();
16735 Expr *RHS = LeftFold ? Out.get() : Result.get();
16736 if (Callee) {
16737 UnresolvedSet<16> Functions;
16738 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16739 Result = getDerived().RebuildCXXOperatorCallExpr(
16740 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16741 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16742 Functions, LHS, RHS);
16743 } else {
16744 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16745 E->getOperator(), LHS, RHS,
16746 /*ForFoldExpresion=*/true);
16747 if (!WarnedOnComparison && Result.isUsable()) {
16748 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16749 BO && BO->isComparisonOp()) {
16750 WarnedOnComparison = true;
16751 SemaRef.Diag(Loc: BO->getBeginLoc(),
16752 DiagID: diag::warn_comparison_in_fold_expression)
16753 << BO->getOpcodeStr();
16754 }
16755 }
16756 }
16757 } else
16758 Result = Out;
16759
16760 if (Result.isInvalid())
16761 return true;
16762 }
16763
16764 // If we're retaining an expansion for a left fold, it is the outermost
16765 // component and takes the complete expansion so far as its init (if any).
16766 if (LeftFold && RetainExpansion) {
16767 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16768
16769 ExprResult Out = getDerived().TransformExpr(Pattern);
16770 if (Out.isInvalid())
16771 return true;
16772
16773 Result = getDerived().RebuildCXXFoldExpr(
16774 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16775 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16776 if (Result.isInvalid())
16777 return true;
16778 }
16779
16780 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16781 PE->setIsProducedByFoldExpansion();
16782
16783 // If we had no init and an empty pack, and we're not retaining an expansion,
16784 // then produce a fallback value or error.
16785 if (Result.isUnset())
16786 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16787 E->getOperator());
16788 return Result;
16789}
16790
16791template <typename Derived>
16792ExprResult
16793TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16794 SmallVector<Expr *, 4> TransformedInits;
16795 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16796
16797 QualType T = getDerived().TransformType(E->getType());
16798
16799 bool ArgChanged = false;
16800
16801 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16802 TransformedInits, &ArgChanged))
16803 return ExprError();
16804
16805 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16806 return E;
16807
16808 return getDerived().RebuildCXXParenListInitExpr(
16809 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16810 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16811}
16812
16813template<typename Derived>
16814ExprResult
16815TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16816 CXXStdInitializerListExpr *E) {
16817 return getDerived().TransformExpr(E->getSubExpr());
16818}
16819
16820template<typename Derived>
16821ExprResult
16822TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16823 return SemaRef.MaybeBindToTemporary(E);
16824}
16825
16826template<typename Derived>
16827ExprResult
16828TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16829 return E;
16830}
16831
16832template<typename Derived>
16833ExprResult
16834TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16835 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16836 if (SubExpr.isInvalid())
16837 return ExprError();
16838
16839 if (!getDerived().AlwaysRebuild() &&
16840 SubExpr.get() == E->getSubExpr())
16841 return E;
16842
16843 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16844}
16845
16846template<typename Derived>
16847ExprResult
16848TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16849 // Transform each of the elements.
16850 SmallVector<Expr *, 8> Elements;
16851 bool ArgChanged = false;
16852 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16853 /*IsCall=*/false, Elements, &ArgChanged))
16854 return ExprError();
16855
16856 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16857 return SemaRef.MaybeBindToTemporary(E);
16858
16859 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16860 Elements.data(),
16861 Elements.size());
16862}
16863
16864template<typename Derived>
16865ExprResult
16866TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16867 ObjCDictionaryLiteral *E) {
16868 // Transform each of the elements.
16869 SmallVector<ObjCDictionaryElement, 8> Elements;
16870 bool ArgChanged = false;
16871 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16872 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
16873
16874 if (OrigElement.isPackExpansion()) {
16875 // This key/value element is a pack expansion.
16876 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16877 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16878 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16879 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16880
16881 // Determine whether the set of unexpanded parameter packs can
16882 // and should be expanded.
16883 bool Expand = true;
16884 bool RetainExpansion = false;
16885 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16886 UnsignedOrNone NumExpansions = OrigNumExpansions;
16887 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16888 OrigElement.Value->getEndLoc());
16889 if (getDerived().TryExpandParameterPacks(
16890 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
16891 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16892 NumExpansions))
16893 return ExprError();
16894
16895 if (!Expand) {
16896 // The transform has determined that we should perform a simple
16897 // transformation on the pack expansion, producing another pack
16898 // expansion.
16899 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16900 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16901 if (Key.isInvalid())
16902 return ExprError();
16903
16904 if (Key.get() != OrigElement.Key)
16905 ArgChanged = true;
16906
16907 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16908 if (Value.isInvalid())
16909 return ExprError();
16910
16911 if (Value.get() != OrigElement.Value)
16912 ArgChanged = true;
16913
16914 ObjCDictionaryElement Expansion = {
16915 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
16916 };
16917 Elements.push_back(Elt: Expansion);
16918 continue;
16919 }
16920
16921 // Record right away that the argument was changed. This needs
16922 // to happen even if the array expands to nothing.
16923 ArgChanged = true;
16924
16925 // The transform has determined that we should perform an elementwise
16926 // expansion of the pattern. Do so.
16927 for (unsigned I = 0; I != *NumExpansions; ++I) {
16928 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16929 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16930 if (Key.isInvalid())
16931 return ExprError();
16932
16933 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16934 if (Value.isInvalid())
16935 return ExprError();
16936
16937 ObjCDictionaryElement Element = {
16938 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
16939 };
16940
16941 // If any unexpanded parameter packs remain, we still have a
16942 // pack expansion.
16943 // FIXME: Can this really happen?
16944 if (Key.get()->containsUnexpandedParameterPack() ||
16945 Value.get()->containsUnexpandedParameterPack())
16946 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16947
16948 Elements.push_back(Elt: Element);
16949 }
16950
16951 // FIXME: Retain a pack expansion if RetainExpansion is true.
16952
16953 // We've finished with this pack expansion.
16954 continue;
16955 }
16956
16957 // Transform and check key.
16958 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16959 if (Key.isInvalid())
16960 return ExprError();
16961
16962 if (Key.get() != OrigElement.Key)
16963 ArgChanged = true;
16964
16965 // Transform and check value.
16966 ExprResult Value
16967 = getDerived().TransformExpr(OrigElement.Value);
16968 if (Value.isInvalid())
16969 return ExprError();
16970
16971 if (Value.get() != OrigElement.Value)
16972 ArgChanged = true;
16973
16974 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
16975 .NumExpansions: std::nullopt};
16976 Elements.push_back(Elt: Element);
16977 }
16978
16979 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16980 return SemaRef.MaybeBindToTemporary(E);
16981
16982 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16983 Elements);
16984}
16985
16986template<typename Derived>
16987ExprResult
16988TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16989 TypeSourceInfo *EncodedTypeInfo
16990 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16991 if (!EncodedTypeInfo)
16992 return ExprError();
16993
16994 if (!getDerived().AlwaysRebuild() &&
16995 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16996 return E;
16997
16998 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16999 EncodedTypeInfo,
17000 E->getRParenLoc());
17001}
17002
17003template<typename Derived>
17004ExprResult TreeTransform<Derived>::
17005TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17006 // This is a kind of implicit conversion, and it needs to get dropped
17007 // and recomputed for the same general reasons that ImplicitCastExprs
17008 // do, as well a more specific one: this expression is only valid when
17009 // it appears *immediately* as an argument expression.
17010 return getDerived().TransformExpr(E->getSubExpr());
17011}
17012
17013template<typename Derived>
17014ExprResult TreeTransform<Derived>::
17015TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17016 TypeSourceInfo *TSInfo
17017 = getDerived().TransformType(E->getTypeInfoAsWritten());
17018 if (!TSInfo)
17019 return ExprError();
17020
17021 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17022 if (Result.isInvalid())
17023 return ExprError();
17024
17025 if (!getDerived().AlwaysRebuild() &&
17026 TSInfo == E->getTypeInfoAsWritten() &&
17027 Result.get() == E->getSubExpr())
17028 return E;
17029
17030 return SemaRef.ObjC().BuildObjCBridgedCast(
17031 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17032 SubExpr: Result.get());
17033}
17034
17035template <typename Derived>
17036ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17037 ObjCAvailabilityCheckExpr *E) {
17038 return E;
17039}
17040
17041template<typename Derived>
17042ExprResult
17043TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17044 // Transform arguments.
17045 bool ArgChanged = false;
17046 SmallVector<Expr*, 8> Args;
17047 Args.reserve(N: E->getNumArgs());
17048 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17049 &ArgChanged))
17050 return ExprError();
17051
17052 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17053 // Class message: transform the receiver type.
17054 TypeSourceInfo *ReceiverTypeInfo
17055 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17056 if (!ReceiverTypeInfo)
17057 return ExprError();
17058
17059 // If nothing changed, just retain the existing message send.
17060 if (!getDerived().AlwaysRebuild() &&
17061 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17062 return SemaRef.MaybeBindToTemporary(E);
17063
17064 // Build a new class message send.
17065 SmallVector<SourceLocation, 16> SelLocs;
17066 E->getSelectorLocs(SelLocs);
17067 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17068 E->getSelector(),
17069 SelLocs,
17070 E->getMethodDecl(),
17071 E->getLeftLoc(),
17072 Args,
17073 E->getRightLoc());
17074 }
17075 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17076 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17077 if (!E->getMethodDecl())
17078 return ExprError();
17079
17080 // Build a new class message send to 'super'.
17081 SmallVector<SourceLocation, 16> SelLocs;
17082 E->getSelectorLocs(SelLocs);
17083 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17084 E->getSelector(),
17085 SelLocs,
17086 E->getReceiverType(),
17087 E->getMethodDecl(),
17088 E->getLeftLoc(),
17089 Args,
17090 E->getRightLoc());
17091 }
17092
17093 // Instance message: transform the receiver
17094 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17095 "Only class and instance messages may be instantiated");
17096 ExprResult Receiver
17097 = getDerived().TransformExpr(E->getInstanceReceiver());
17098 if (Receiver.isInvalid())
17099 return ExprError();
17100
17101 // If nothing changed, just retain the existing message send.
17102 if (!getDerived().AlwaysRebuild() &&
17103 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17104 return SemaRef.MaybeBindToTemporary(E);
17105
17106 // Build a new instance message send.
17107 SmallVector<SourceLocation, 16> SelLocs;
17108 E->getSelectorLocs(SelLocs);
17109 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17110 E->getSelector(),
17111 SelLocs,
17112 E->getMethodDecl(),
17113 E->getLeftLoc(),
17114 Args,
17115 E->getRightLoc());
17116}
17117
17118template<typename Derived>
17119ExprResult
17120TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17121 return E;
17122}
17123
17124template<typename Derived>
17125ExprResult
17126TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17127 return E;
17128}
17129
17130template<typename Derived>
17131ExprResult
17132TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17133 // Transform the base expression.
17134 ExprResult Base = getDerived().TransformExpr(E->getBase());
17135 if (Base.isInvalid())
17136 return ExprError();
17137
17138 // We don't need to transform the ivar; it will never change.
17139
17140 // If nothing changed, just retain the existing expression.
17141 if (!getDerived().AlwaysRebuild() &&
17142 Base.get() == E->getBase())
17143 return E;
17144
17145 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17146 E->getLocation(),
17147 E->isArrow(), E->isFreeIvar());
17148}
17149
17150template<typename Derived>
17151ExprResult
17152TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17153 // 'super' and types never change. Property never changes. Just
17154 // retain the existing expression.
17155 if (!E->isObjectReceiver())
17156 return E;
17157
17158 // Transform the base expression.
17159 ExprResult Base = getDerived().TransformExpr(E->getBase());
17160 if (Base.isInvalid())
17161 return ExprError();
17162
17163 // We don't need to transform the property; it will never change.
17164
17165 // If nothing changed, just retain the existing expression.
17166 if (!getDerived().AlwaysRebuild() &&
17167 Base.get() == E->getBase())
17168 return E;
17169
17170 if (E->isExplicitProperty())
17171 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17172 E->getExplicitProperty(),
17173 E->getLocation());
17174
17175 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17176 SemaRef.Context.PseudoObjectTy,
17177 E->getImplicitPropertyGetter(),
17178 E->getImplicitPropertySetter(),
17179 E->getLocation());
17180}
17181
17182template<typename Derived>
17183ExprResult
17184TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17185 // Transform the base expression.
17186 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17187 if (Base.isInvalid())
17188 return ExprError();
17189
17190 // Transform the key expression.
17191 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17192 if (Key.isInvalid())
17193 return ExprError();
17194
17195 // If nothing changed, just retain the existing expression.
17196 if (!getDerived().AlwaysRebuild() &&
17197 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17198 return E;
17199
17200 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17201 Base.get(), Key.get(),
17202 E->getAtIndexMethodDecl(),
17203 E->setAtIndexMethodDecl());
17204}
17205
17206template<typename Derived>
17207ExprResult
17208TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17209 // Transform the base expression.
17210 ExprResult Base = getDerived().TransformExpr(E->getBase());
17211 if (Base.isInvalid())
17212 return ExprError();
17213
17214 // If nothing changed, just retain the existing expression.
17215 if (!getDerived().AlwaysRebuild() &&
17216 Base.get() == E->getBase())
17217 return E;
17218
17219 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17220 E->getOpLoc(),
17221 E->isArrow());
17222}
17223
17224template<typename Derived>
17225ExprResult
17226TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17227 bool ArgumentChanged = false;
17228 SmallVector<Expr*, 8> SubExprs;
17229 SubExprs.reserve(N: E->getNumSubExprs());
17230 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17231 SubExprs, &ArgumentChanged))
17232 return ExprError();
17233
17234 if (!getDerived().AlwaysRebuild() &&
17235 !ArgumentChanged)
17236 return E;
17237
17238 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17239 SubExprs,
17240 E->getRParenLoc());
17241}
17242
17243template<typename Derived>
17244ExprResult
17245TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17246 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17247 if (SrcExpr.isInvalid())
17248 return ExprError();
17249
17250 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17251 if (!Type)
17252 return ExprError();
17253
17254 if (!getDerived().AlwaysRebuild() &&
17255 Type == E->getTypeSourceInfo() &&
17256 SrcExpr.get() == E->getSrcExpr())
17257 return E;
17258
17259 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17260 SrcExpr.get(), Type,
17261 E->getRParenLoc());
17262}
17263
17264template<typename Derived>
17265ExprResult
17266TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17267 BlockDecl *oldBlock = E->getBlockDecl();
17268
17269 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17270 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17271
17272 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17273 blockScope->TheDecl->setBlockMissingReturnType(
17274 oldBlock->blockMissingReturnType());
17275
17276 SmallVector<ParmVarDecl*, 4> params;
17277 SmallVector<QualType, 4> paramTypes;
17278
17279 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17280
17281 // Parameter substitution.
17282 Sema::ExtParameterInfoBuilder extParamInfos;
17283 if (getDerived().TransformFunctionTypeParams(
17284 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17285 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17286 extParamInfos)) {
17287 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17288 return ExprError();
17289 }
17290
17291 QualType exprResultType =
17292 getDerived().TransformType(exprFunctionType->getReturnType());
17293
17294 auto epi = exprFunctionType->getExtProtoInfo();
17295 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17296
17297 QualType functionType =
17298 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17299 blockScope->FunctionType = functionType;
17300
17301 // Set the parameters on the block decl.
17302 if (!params.empty())
17303 blockScope->TheDecl->setParams(params);
17304
17305 if (!oldBlock->blockMissingReturnType()) {
17306 blockScope->HasImplicitReturnType = false;
17307 blockScope->ReturnType = exprResultType;
17308 }
17309
17310 // Transform the body
17311 StmtResult body = getDerived().TransformStmt(E->getBody());
17312 if (body.isInvalid()) {
17313 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17314 return ExprError();
17315 }
17316
17317#ifndef NDEBUG
17318 // In builds with assertions, make sure that we captured everything we
17319 // captured before.
17320 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17321 for (const auto &I : oldBlock->captures()) {
17322 VarDecl *oldCapture = I.getVariable();
17323
17324 // Ignore parameter packs.
17325 if (oldCapture->isParameterPack())
17326 continue;
17327
17328 VarDecl *newCapture =
17329 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17330 oldCapture));
17331 assert(blockScope->CaptureMap.count(newCapture));
17332 }
17333
17334 // The this pointer may not be captured by the instantiated block, even when
17335 // it's captured by the original block, if the expression causing the
17336 // capture is in the discarded branch of a constexpr if statement.
17337 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17338 "this pointer isn't captured in the old block");
17339 }
17340#endif
17341
17342 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17343 /*Scope=*/CurScope: nullptr);
17344}
17345
17346template<typename Derived>
17347ExprResult
17348TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17349 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17350 if (SrcExpr.isInvalid())
17351 return ExprError();
17352
17353 QualType Type = getDerived().TransformType(E->getType());
17354
17355 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17356 RParenLoc: E->getRParenLoc());
17357}
17358
17359template<typename Derived>
17360ExprResult
17361TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17362 bool ArgumentChanged = false;
17363 SmallVector<Expr*, 8> SubExprs;
17364 SubExprs.reserve(N: E->getNumSubExprs());
17365 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17366 SubExprs, &ArgumentChanged))
17367 return ExprError();
17368
17369 if (!getDerived().AlwaysRebuild() &&
17370 !ArgumentChanged)
17371 return E;
17372
17373 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17374 E->getOp(), E->getRParenLoc());
17375}
17376
17377//===----------------------------------------------------------------------===//
17378// Type reconstruction
17379//===----------------------------------------------------------------------===//
17380
17381template<typename Derived>
17382QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17383 SourceLocation Star) {
17384 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17385 Entity: getDerived().getBaseEntity());
17386}
17387
17388template<typename Derived>
17389QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17390 SourceLocation Star) {
17391 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17392 Entity: getDerived().getBaseEntity());
17393}
17394
17395template<typename Derived>
17396QualType
17397TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17398 bool WrittenAsLValue,
17399 SourceLocation Sigil) {
17400 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17401 Loc: Sigil, Entity: getDerived().getBaseEntity());
17402}
17403
17404template <typename Derived>
17405QualType TreeTransform<Derived>::RebuildMemberPointerType(
17406 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17407 SourceLocation Sigil) {
17408 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17409 Entity: getDerived().getBaseEntity());
17410}
17411
17412template<typename Derived>
17413QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17414 const ObjCTypeParamDecl *Decl,
17415 SourceLocation ProtocolLAngleLoc,
17416 ArrayRef<ObjCProtocolDecl *> Protocols,
17417 ArrayRef<SourceLocation> ProtocolLocs,
17418 SourceLocation ProtocolRAngleLoc) {
17419 return SemaRef.ObjC().BuildObjCTypeParamType(
17420 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17421 /*FailOnError=*/FailOnError: true);
17422}
17423
17424template<typename Derived>
17425QualType TreeTransform<Derived>::RebuildObjCObjectType(
17426 QualType BaseType,
17427 SourceLocation Loc,
17428 SourceLocation TypeArgsLAngleLoc,
17429 ArrayRef<TypeSourceInfo *> TypeArgs,
17430 SourceLocation TypeArgsRAngleLoc,
17431 SourceLocation ProtocolLAngleLoc,
17432 ArrayRef<ObjCProtocolDecl *> Protocols,
17433 ArrayRef<SourceLocation> ProtocolLocs,
17434 SourceLocation ProtocolRAngleLoc) {
17435 return SemaRef.ObjC().BuildObjCObjectType(
17436 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17437 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17438 /*FailOnError=*/FailOnError: true,
17439 /*Rebuilding=*/Rebuilding: true);
17440}
17441
17442template<typename Derived>
17443QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17444 QualType PointeeType,
17445 SourceLocation Star) {
17446 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17447}
17448
17449template <typename Derived>
17450QualType TreeTransform<Derived>::RebuildArrayType(
17451 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17452 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17453 if (SizeExpr || !Size)
17454 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17455 Quals: IndexTypeQuals, Brackets: BracketsRange,
17456 Entity: getDerived().getBaseEntity());
17457
17458 QualType Types[] = {
17459 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17460 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17461 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17462 };
17463 QualType SizeType;
17464 for (const auto &T : Types)
17465 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17466 SizeType = T;
17467 break;
17468 }
17469
17470 // Note that we can return a VariableArrayType here in the case where
17471 // the element type was a dependent VariableArrayType.
17472 IntegerLiteral *ArraySize
17473 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17474 /*FIXME*/l: BracketsRange.getBegin());
17475 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17476 Quals: IndexTypeQuals, Brackets: BracketsRange,
17477 Entity: getDerived().getBaseEntity());
17478}
17479
17480template <typename Derived>
17481QualType TreeTransform<Derived>::RebuildConstantArrayType(
17482 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17483 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17484 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17485 IndexTypeQuals, BracketsRange);
17486}
17487
17488template <typename Derived>
17489QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17490 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17491 SourceRange BracketsRange) {
17492 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17493 IndexTypeQuals, BracketsRange);
17494}
17495
17496template <typename Derived>
17497QualType TreeTransform<Derived>::RebuildVariableArrayType(
17498 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17499 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17500 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17501 SizeExpr,
17502 IndexTypeQuals, BracketsRange);
17503}
17504
17505template <typename Derived>
17506QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17507 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17508 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17509 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17510 SizeExpr,
17511 IndexTypeQuals, BracketsRange);
17512}
17513
17514template <typename Derived>
17515QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17516 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17517 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17518 AttrLoc: AttributeLoc);
17519}
17520
17521template <typename Derived>
17522QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17523 unsigned NumElements,
17524 VectorKind VecKind) {
17525 // FIXME: semantic checking!
17526 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17527}
17528
17529template <typename Derived>
17530QualType TreeTransform<Derived>::RebuildDependentVectorType(
17531 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17532 VectorKind VecKind) {
17533 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17534}
17535
17536template<typename Derived>
17537QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17538 unsigned NumElements,
17539 SourceLocation AttributeLoc) {
17540 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17541 NumElements, true);
17542 IntegerLiteral *VectorSize
17543 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17544 l: AttributeLoc);
17545 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17546}
17547
17548template<typename Derived>
17549QualType
17550TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17551 Expr *SizeExpr,
17552 SourceLocation AttributeLoc) {
17553 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17554}
17555
17556template <typename Derived>
17557QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17558 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17559 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17560 NumColumns);
17561}
17562
17563template <typename Derived>
17564QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17565 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17566 SourceLocation AttributeLoc) {
17567 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17568 AttrLoc: AttributeLoc);
17569}
17570
17571template <typename Derived>
17572QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17573 QualType T, MutableArrayRef<QualType> ParamTypes,
17574 const FunctionProtoType::ExtProtoInfo &EPI) {
17575 return SemaRef.BuildFunctionType(T, ParamTypes,
17576 Loc: getDerived().getBaseLocation(),
17577 Entity: getDerived().getBaseEntity(),
17578 EPI);
17579}
17580
17581template<typename Derived>
17582QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17583 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17584}
17585
17586template <typename Derived>
17587QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
17588 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
17589 SourceLocation NameLoc, Decl *D) {
17590 assert(D && "no decl found");
17591 if (D->isInvalidDecl()) return QualType();
17592
17593 // FIXME: Doesn't account for ObjCInterfaceDecl!
17594 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17595 // A valid resolved using typename pack expansion decl can have multiple
17596 // UsingDecls, but they must each have exactly one type, and it must be
17597 // the same type in every case. But we must have at least one expansion!
17598 if (UPD->expansions().empty()) {
17599 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
17600 << UPD->isCXXClassMember() << UPD;
17601 return QualType();
17602 }
17603
17604 // We might still have some unresolved types. Try to pick a resolved type
17605 // if we can. The final instantiation will check that the remaining
17606 // unresolved types instantiate to the type we pick.
17607 QualType FallbackT;
17608 QualType T;
17609 for (auto *E : UPD->expansions()) {
17610 QualType ThisT =
17611 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
17612 if (ThisT.isNull())
17613 continue;
17614 if (ThisT->getAs<UnresolvedUsingType>())
17615 FallbackT = ThisT;
17616 else if (T.isNull())
17617 T = ThisT;
17618 else
17619 assert(getSema().Context.hasSameType(ThisT, T) &&
17620 "mismatched resolved types in using pack expansion");
17621 }
17622 return T.isNull() ? FallbackT : T;
17623 }
17624 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17625 assert(Using->hasTypename() &&
17626 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17627
17628 // A valid resolved using typename decl points to exactly one type decl.
17629 assert(++Using->shadow_begin() == Using->shadow_end());
17630
17631 UsingShadowDecl *Shadow = *Using->shadow_begin();
17632 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
17633 return QualType();
17634 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
17635 }
17636 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17637 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17638 return SemaRef.Context.getUnresolvedUsingType(
17639 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
17640}
17641
17642template <typename Derived>
17643QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17644 TypeOfKind Kind) {
17645 return SemaRef.BuildTypeofExprType(E, Kind);
17646}
17647
17648template<typename Derived>
17649QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17650 TypeOfKind Kind) {
17651 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17652}
17653
17654template <typename Derived>
17655QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17656 return SemaRef.BuildDecltypeType(E);
17657}
17658
17659template <typename Derived>
17660QualType TreeTransform<Derived>::RebuildPackIndexingType(
17661 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17662 SourceLocation EllipsisLoc, bool FullySubstituted,
17663 ArrayRef<QualType> Expansions) {
17664 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17665 FullySubstituted, Expansions);
17666}
17667
17668template<typename Derived>
17669QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17670 UnaryTransformType::UTTKind UKind,
17671 SourceLocation Loc) {
17672 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17673}
17674
17675template <typename Derived>
17676QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17677 ElaboratedTypeKeyword Keyword, TemplateName Template,
17678 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
17679 return SemaRef.CheckTemplateIdType(
17680 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
17681 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
17682}
17683
17684template<typename Derived>
17685QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17686 SourceLocation KWLoc) {
17687 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17688}
17689
17690template<typename Derived>
17691QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17692 SourceLocation KWLoc,
17693 bool isReadPipe) {
17694 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17695 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17696}
17697
17698template <typename Derived>
17699QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17700 unsigned NumBits,
17701 SourceLocation Loc) {
17702 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17703 NumBits, true);
17704 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17705 type: SemaRef.Context.IntTy, l: Loc);
17706 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17707}
17708
17709template <typename Derived>
17710QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17711 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17712 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17713}
17714
17715template <typename Derived>
17716TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17717 bool TemplateKW,
17718 TemplateName Name) {
17719 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17720 Template: Name);
17721}
17722
17723template <typename Derived>
17724TemplateName TreeTransform<Derived>::RebuildTemplateName(
17725 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
17726 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
17727 UnqualifiedId TemplateName;
17728 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17729 Sema::TemplateTy Template;
17730 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17731 TemplateName, ParsedType::make(P: ObjectType),
17732 /*EnteringContext=*/false, Template,
17733 AllowInjectedClassName);
17734 return Template.get();
17735}
17736
17737template<typename Derived>
17738TemplateName
17739TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17740 SourceLocation TemplateKWLoc,
17741 OverloadedOperatorKind Operator,
17742 SourceLocation NameLoc,
17743 QualType ObjectType,
17744 bool AllowInjectedClassName) {
17745 UnqualifiedId Name;
17746 // FIXME: Bogus location information.
17747 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17748 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17749 Sema::TemplateTy Template;
17750 getSema().ActOnTemplateName(
17751 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17752 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17753 return Template.get();
17754}
17755
17756template <typename Derived>
17757ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17758 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17759 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17760 Expr *Second) {
17761 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17762
17763 if (First->getObjectKind() == OK_ObjCProperty) {
17764 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17765 if (BinaryOperator::isAssignmentOp(Opc))
17766 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17767 Opcode: Opc, LHS: First, RHS: Second);
17768 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17769 if (Result.isInvalid())
17770 return ExprError();
17771 First = Result.get();
17772 }
17773
17774 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17775 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17776 if (Result.isInvalid())
17777 return ExprError();
17778 Second = Result.get();
17779 }
17780
17781 // Determine whether this should be a builtin operation.
17782 if (Op == OO_Subscript) {
17783 if (!First->getType()->isOverloadableType() &&
17784 !Second->getType()->isOverloadableType())
17785 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17786 OpLoc);
17787 } else if (Op == OO_Arrow) {
17788 // It is possible that the type refers to a RecoveryExpr created earlier
17789 // in the tree transformation.
17790 if (First->getType()->isDependentType())
17791 return ExprError();
17792 // -> is never a builtin operation.
17793 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17794 } else if (Second == nullptr || isPostIncDec) {
17795 if (!First->getType()->isOverloadableType() ||
17796 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17797 // The argument is not of overloadable type, or this is an expression
17798 // of the form &Class::member, so try to create a built-in unary
17799 // operation.
17800 UnaryOperatorKind Opc
17801 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17802
17803 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17804 }
17805 } else {
17806 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17807 !First->getType()->isOverloadableType() &&
17808 !Second->getType()->isOverloadableType()) {
17809 // Neither of the arguments is type-dependent or has an overloadable
17810 // type, so try to create a built-in binary operation.
17811 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17812 ExprResult Result
17813 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17814 if (Result.isInvalid())
17815 return ExprError();
17816
17817 return Result;
17818 }
17819 }
17820
17821 // Create the overloaded operator invocation for unary operators.
17822 if (!Second || isPostIncDec) {
17823 UnaryOperatorKind Opc
17824 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17825 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
17826 RequiresADL);
17827 }
17828
17829 // Create the overloaded operator invocation for binary operators.
17830 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17831 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
17832 LHS: First, RHS: Second, RequiresADL);
17833 if (Result.isInvalid())
17834 return ExprError();
17835
17836 return Result;
17837}
17838
17839template<typename Derived>
17840ExprResult
17841TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17842 SourceLocation OperatorLoc,
17843 bool isArrow,
17844 CXXScopeSpec &SS,
17845 TypeSourceInfo *ScopeType,
17846 SourceLocation CCLoc,
17847 SourceLocation TildeLoc,
17848 PseudoDestructorTypeStorage Destroyed) {
17849 QualType CanonicalBaseType = Base->getType().getCanonicalType();
17850 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17851 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
17852 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
17853 !cast<PointerType>(Val&: CanonicalBaseType)
17854 ->getPointeeType()
17855 ->getAsCanonical<RecordType>())) {
17856 // This pseudo-destructor expression is still a pseudo-destructor.
17857 return SemaRef.BuildPseudoDestructorExpr(
17858 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
17859 CCLoc, TildeLoc, DestroyedType: Destroyed);
17860 }
17861
17862 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17863 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17864 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
17865 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17866 NameInfo.setNamedTypeInfo(DestroyedType);
17867
17868 // The scope type is now known to be a valid nested name specifier
17869 // component. Tack it on to the nested name specifier.
17870 if (ScopeType) {
17871 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
17872 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17873 diag::err_expected_class_or_namespace)
17874 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17875 return ExprError();
17876 }
17877 SS.clear();
17878 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
17879 }
17880
17881 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17882 return getSema().BuildMemberReferenceExpr(
17883 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
17884 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
17885 /*TemplateArgs*/ nullptr,
17886 /*S*/ nullptr);
17887}
17888
17889template<typename Derived>
17890StmtResult
17891TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17892 SourceLocation Loc = S->getBeginLoc();
17893 CapturedDecl *CD = S->getCapturedDecl();
17894 unsigned NumParams = CD->getNumParams();
17895 unsigned ContextParamPos = CD->getContextParamPosition();
17896 SmallVector<Sema::CapturedParamNameType, 4> Params;
17897 for (unsigned I = 0; I < NumParams; ++I) {
17898 if (I != ContextParamPos) {
17899 Params.push_back(
17900 Elt: std::make_pair(
17901 CD->getParam(i: I)->getName(),
17902 getDerived().TransformType(CD->getParam(i: I)->getType())));
17903 } else {
17904 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
17905 }
17906 }
17907 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17908 S->getCapturedRegionKind(), Params);
17909 StmtResult Body;
17910 {
17911 Sema::CompoundScopeRAII CompoundScope(getSema());
17912 Body = getDerived().TransformStmt(S->getCapturedStmt());
17913 }
17914
17915 if (Body.isInvalid()) {
17916 getSema().ActOnCapturedRegionError();
17917 return StmtError();
17918 }
17919
17920 return getSema().ActOnCapturedRegionEnd(Body.get());
17921}
17922
17923template <typename Derived>
17924StmtResult
17925TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17926 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17927 // function definition or instantiation of a function template specialization
17928 // and will therefore never appear in a dependent context.
17929 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17930 "context");
17931}
17932
17933template <typename Derived>
17934ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17935 // We can transform the base expression and allow argument resolution to fill
17936 // in the rest.
17937 return getDerived().TransformExpr(E->getArgLValue());
17938}
17939
17940} // end namespace clang
17941
17942#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
17943