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(DeducedKind DK, QualType DeducedAsType,
1142 AutoTypeKeyword Keyword,
1143 ConceptDecl *TypeConstraintConcept,
1144 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1145 return SemaRef.Context.getAutoType(
1146 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1147 }
1148
1149 /// By default, builds a new DeducedTemplateSpecializationType with the given
1150 /// deduced type.
1151 QualType RebuildDeducedTemplateSpecializationType(
1152 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1153 TemplateName Template) {
1154 return SemaRef.Context.getDeducedTemplateSpecializationType(
1155 DK, DeducedAsType, Keyword, Template);
1156 }
1157
1158 /// Build a new template specialization type.
1159 ///
1160 /// By default, performs semantic analysis when building the template
1161 /// specialization type. Subclasses may override this routine to provide
1162 /// different behavior.
1163 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1164 TemplateName Template,
1165 SourceLocation TemplateLoc,
1166 TemplateArgumentListInfo &Args);
1167
1168 /// Build a new parenthesized type.
1169 ///
1170 /// By default, builds a new ParenType type from the inner type.
1171 /// Subclasses may override this routine to provide different behavior.
1172 QualType RebuildParenType(QualType InnerType) {
1173 return SemaRef.BuildParenType(T: InnerType);
1174 }
1175
1176 /// Build a new typename type that refers to an identifier.
1177 ///
1178 /// By default, performs semantic analysis when building the typename type
1179 /// (or elaborated type). Subclasses may override this routine to provide
1180 /// different behavior.
1181 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1182 SourceLocation KeywordLoc,
1183 NestedNameSpecifierLoc QualifierLoc,
1184 const IdentifierInfo *Id,
1185 SourceLocation IdLoc,
1186 bool DeducedTSTContext) {
1187 CXXScopeSpec SS;
1188 SS.Adopt(Other: QualifierLoc);
1189
1190 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1191 // If the name is still dependent, just build a new dependent name type.
1192 if (!SemaRef.computeDeclContext(SS))
1193 return SemaRef.Context.getDependentNameType(Keyword,
1194 NNS: QualifierLoc.getNestedNameSpecifier(),
1195 Name: Id);
1196 }
1197
1198 if (Keyword == ElaboratedTypeKeyword::None ||
1199 Keyword == ElaboratedTypeKeyword::Typename) {
1200 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1201 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1202 }
1203
1204 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1205
1206 // We had a dependent elaborated-type-specifier that has been transformed
1207 // into a non-dependent elaborated-type-specifier. Find the tag we're
1208 // referring to.
1209 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1210 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1211 if (!DC)
1212 return QualType();
1213
1214 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1215 return QualType();
1216
1217 TagDecl *Tag = nullptr;
1218 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1219 switch (Result.getResultKind()) {
1220 case LookupResultKind::NotFound:
1221 case LookupResultKind::NotFoundInCurrentInstantiation:
1222 break;
1223
1224 case LookupResultKind::Found:
1225 Tag = Result.getAsSingle<TagDecl>();
1226 break;
1227
1228 case LookupResultKind::FoundOverloaded:
1229 case LookupResultKind::FoundUnresolvedValue:
1230 llvm_unreachable("Tag lookup cannot find non-tags");
1231
1232 case LookupResultKind::Ambiguous:
1233 // Let the LookupResult structure handle ambiguities.
1234 return QualType();
1235 }
1236
1237 if (!Tag) {
1238 // Check where the name exists but isn't a tag type and use that to emit
1239 // better diagnostics.
1240 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1241 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1242 switch (Result.getResultKind()) {
1243 case LookupResultKind::Found:
1244 case LookupResultKind::FoundOverloaded:
1245 case LookupResultKind::FoundUnresolvedValue: {
1246 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1247 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1248 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1249 << SomeDecl << NTK << Kind;
1250 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1251 break;
1252 }
1253 default:
1254 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1255 << Kind << Id << DC << QualifierLoc.getSourceRange();
1256 break;
1257 }
1258 return QualType();
1259 }
1260 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1261 NewTagLoc: IdLoc, Name: Id)) {
1262 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1263 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1264 return QualType();
1265 }
1266 return getDerived().RebuildTagType(
1267 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1268 }
1269
1270 /// Build a new pack expansion type.
1271 ///
1272 /// By default, builds a new PackExpansionType type from the given pattern.
1273 /// Subclasses may override this routine to provide different behavior.
1274 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1275 SourceLocation EllipsisLoc,
1276 UnsignedOrNone NumExpansions) {
1277 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1278 NumExpansions);
1279 }
1280
1281 /// Build a new atomic type given its value type.
1282 ///
1283 /// By default, performs semantic analysis when building the atomic type.
1284 /// Subclasses may override this routine to provide different behavior.
1285 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1286
1287 /// Build a new pipe type given its value type.
1288 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1289 bool isReadPipe);
1290
1291 /// Build a bit-precise int given its value type.
1292 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1293 SourceLocation Loc);
1294
1295 /// Build a dependent bit-precise int given its value type.
1296 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1297 SourceLocation Loc);
1298
1299 /// Build a new template name given a nested name specifier, a flag
1300 /// indicating whether the "template" keyword was provided, and the template
1301 /// that the template name refers to.
1302 ///
1303 /// By default, builds the new template name directly. Subclasses may override
1304 /// this routine to provide different behavior.
1305 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1306 TemplateName Name);
1307
1308 /// Build a new template name given a nested name specifier and the
1309 /// name that is referred to as a template.
1310 ///
1311 /// By default, performs semantic analysis to determine whether the name can
1312 /// be resolved to a specific template, then builds the appropriate kind of
1313 /// template name. Subclasses may override this routine to provide different
1314 /// behavior.
1315 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1316 SourceLocation TemplateKWLoc,
1317 const IdentifierInfo &Name,
1318 SourceLocation NameLoc, QualType ObjectType,
1319 bool AllowInjectedClassName);
1320
1321 /// Build a new template name given a nested name specifier and the
1322 /// overloaded operator name that is referred to as a template.
1323 ///
1324 /// By default, performs semantic analysis to determine whether the name can
1325 /// be resolved to a specific template, then builds the appropriate kind of
1326 /// template name. Subclasses may override this routine to provide different
1327 /// behavior.
1328 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1329 SourceLocation TemplateKWLoc,
1330 OverloadedOperatorKind Operator,
1331 SourceLocation NameLoc, QualType ObjectType,
1332 bool AllowInjectedClassName);
1333
1334 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1335 SourceLocation TemplateKWLoc,
1336 IdentifierOrOverloadedOperator IO,
1337 SourceLocation NameLoc, QualType ObjectType,
1338 bool AllowInjectedClassName);
1339
1340 /// Build a new template name given a template template parameter pack
1341 /// and the
1342 ///
1343 /// By default, performs semantic analysis to determine whether the name can
1344 /// be resolved to a specific template, then builds the appropriate kind of
1345 /// template name. Subclasses may override this routine to provide different
1346 /// behavior.
1347 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1348 Decl *AssociatedDecl, unsigned Index,
1349 bool Final) {
1350 return getSema().Context.getSubstTemplateTemplateParmPack(
1351 ArgPack, AssociatedDecl, Index, Final);
1352 }
1353
1354 /// Build a new compound statement.
1355 ///
1356 /// By default, performs semantic analysis to build the new statement.
1357 /// Subclasses may override this routine to provide different behavior.
1358 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1359 MultiStmtArg Statements,
1360 SourceLocation RBraceLoc,
1361 bool IsStmtExpr) {
1362 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1363 IsStmtExpr);
1364 }
1365
1366 /// Build a new case statement.
1367 ///
1368 /// By default, performs semantic analysis to build the new statement.
1369 /// Subclasses may override this routine to provide different behavior.
1370 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1371 Expr *LHS,
1372 SourceLocation EllipsisLoc,
1373 Expr *RHS,
1374 SourceLocation ColonLoc) {
1375 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1376 ColonLoc);
1377 }
1378
1379 /// Attach the body to a new case statement.
1380 ///
1381 /// By default, performs semantic analysis to build the new statement.
1382 /// Subclasses may override this routine to provide different behavior.
1383 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1384 getSema().ActOnCaseStmtBody(S, Body);
1385 return S;
1386 }
1387
1388 /// Build a new default statement.
1389 ///
1390 /// By default, performs semantic analysis to build the new statement.
1391 /// Subclasses may override this routine to provide different behavior.
1392 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1393 SourceLocation ColonLoc,
1394 Stmt *SubStmt) {
1395 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1396 /*CurScope=*/nullptr);
1397 }
1398
1399 /// Build a new label statement.
1400 ///
1401 /// By default, performs semantic analysis to build the new statement.
1402 /// Subclasses may override this routine to provide different behavior.
1403 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1404 SourceLocation ColonLoc, Stmt *SubStmt) {
1405 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1406 }
1407
1408 /// Build a new attributed statement.
1409 ///
1410 /// By default, performs semantic analysis to build the new statement.
1411 /// Subclasses may override this routine to provide different behavior.
1412 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1413 ArrayRef<const Attr *> Attrs,
1414 Stmt *SubStmt) {
1415 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1416 return StmtError();
1417 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1418 }
1419
1420 /// Build a new "if" statement.
1421 ///
1422 /// By default, performs semantic analysis to build the new statement.
1423 /// Subclasses may override this routine to provide different behavior.
1424 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1425 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1426 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1427 SourceLocation ElseLoc, Stmt *Else) {
1428 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1429 Then, ElseLoc, Else);
1430 }
1431
1432 /// Start building a new switch statement.
1433 ///
1434 /// By default, performs semantic analysis to build the new statement.
1435 /// Subclasses may override this routine to provide different behavior.
1436 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1437 SourceLocation LParenLoc, Stmt *Init,
1438 Sema::ConditionResult Cond,
1439 SourceLocation RParenLoc) {
1440 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1441 RParenLoc);
1442 }
1443
1444 /// Attach the body to the switch statement.
1445 ///
1446 /// By default, performs semantic analysis to build the new statement.
1447 /// Subclasses may override this routine to provide different behavior.
1448 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1449 Stmt *Switch, Stmt *Body) {
1450 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1451 }
1452
1453 /// Build a new while statement.
1454 ///
1455 /// By default, performs semantic analysis to build the new statement.
1456 /// Subclasses may override this routine to provide different behavior.
1457 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1458 Sema::ConditionResult Cond,
1459 SourceLocation RParenLoc, Stmt *Body) {
1460 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1461 }
1462
1463 /// Build a new do-while statement.
1464 ///
1465 /// By default, performs semantic analysis to build the new statement.
1466 /// Subclasses may override this routine to provide different behavior.
1467 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1468 SourceLocation WhileLoc, SourceLocation LParenLoc,
1469 Expr *Cond, SourceLocation RParenLoc) {
1470 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1471 Cond, RParenLoc);
1472 }
1473
1474 /// Build a new for statement.
1475 ///
1476 /// By default, performs semantic analysis to build the new statement.
1477 /// Subclasses may override this routine to provide different behavior.
1478 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1479 Stmt *Init, Sema::ConditionResult Cond,
1480 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1481 Stmt *Body) {
1482 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1483 Inc, RParenLoc, Body);
1484 }
1485
1486 /// Build a new goto statement.
1487 ///
1488 /// By default, performs semantic analysis to build the new statement.
1489 /// Subclasses may override this routine to provide different behavior.
1490 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1491 LabelDecl *Label) {
1492 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1493 }
1494
1495 /// Build a new indirect goto statement.
1496 ///
1497 /// By default, performs semantic analysis to build the new statement.
1498 /// Subclasses may override this routine to provide different behavior.
1499 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1500 SourceLocation StarLoc,
1501 Expr *Target) {
1502 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1503 }
1504
1505 /// Build a new return statement.
1506 ///
1507 /// By default, performs semantic analysis to build the new statement.
1508 /// Subclasses may override this routine to provide different behavior.
1509 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1510 return getSema().BuildReturnStmt(ReturnLoc, Result);
1511 }
1512
1513 /// Build a new declaration statement.
1514 ///
1515 /// By default, performs semantic analysis to build the new statement.
1516 /// Subclasses may override this routine to provide different behavior.
1517 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1518 SourceLocation StartLoc, SourceLocation EndLoc) {
1519 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1520 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1521 }
1522
1523 /// Build a new inline asm statement.
1524 ///
1525 /// By default, performs semantic analysis to build the new statement.
1526 /// Subclasses may override this routine to provide different behavior.
1527 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1528 bool IsVolatile, unsigned NumOutputs,
1529 unsigned NumInputs, IdentifierInfo **Names,
1530 MultiExprArg Constraints, MultiExprArg Exprs,
1531 Expr *AsmString, MultiExprArg Clobbers,
1532 unsigned NumLabels,
1533 SourceLocation RParenLoc) {
1534 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1535 NumInputs, Names, Constraints, Exprs,
1536 AsmString, Clobbers, NumLabels, RParenLoc);
1537 }
1538
1539 /// Build a new MS style inline asm statement.
1540 ///
1541 /// By default, performs semantic analysis to build the new statement.
1542 /// Subclasses may override this routine to provide different behavior.
1543 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1544 ArrayRef<Token> AsmToks,
1545 StringRef AsmString,
1546 unsigned NumOutputs, unsigned NumInputs,
1547 ArrayRef<StringRef> Constraints,
1548 ArrayRef<StringRef> Clobbers,
1549 ArrayRef<Expr*> Exprs,
1550 SourceLocation EndLoc) {
1551 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1552 NumOutputs, NumInputs,
1553 Constraints, Clobbers, Exprs, EndLoc);
1554 }
1555
1556 /// Build a new co_return statement.
1557 ///
1558 /// By default, performs semantic analysis to build the new statement.
1559 /// Subclasses may override this routine to provide different behavior.
1560 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1561 bool IsImplicit) {
1562 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1563 }
1564
1565 /// Build a new co_await expression.
1566 ///
1567 /// By default, performs semantic analysis to build the new expression.
1568 /// Subclasses may override this routine to provide different behavior.
1569 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1570 UnresolvedLookupExpr *OpCoawaitLookup,
1571 bool IsImplicit) {
1572 // This function rebuilds a coawait-expr given its operator.
1573 // For an explicit coawait-expr, the rebuild involves the full set
1574 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1575 // including calling await_transform().
1576 // For an implicit coawait-expr, we need to rebuild the "operator
1577 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1578 // This mirrors how the implicit CoawaitExpr is originally created
1579 // in Sema::ActOnCoroutineBodyStart().
1580 if (IsImplicit) {
1581 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1582 CoawaitLoc, Operand, OpCoawaitLookup);
1583 if (Suspend.isInvalid())
1584 return ExprError();
1585 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1586 Suspend.get(), true);
1587 }
1588
1589 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1590 OpCoawaitLookup);
1591 }
1592
1593 /// Build a new co_await expression.
1594 ///
1595 /// By default, performs semantic analysis to build the new expression.
1596 /// Subclasses may override this routine to provide different behavior.
1597 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1598 Expr *Result,
1599 UnresolvedLookupExpr *Lookup) {
1600 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1601 }
1602
1603 /// Build a new co_yield expression.
1604 ///
1605 /// By default, performs semantic analysis to build the new expression.
1606 /// Subclasses may override this routine to provide different behavior.
1607 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1608 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1609 }
1610
1611 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1612 return getSema().BuildCoroutineBodyStmt(Args);
1613 }
1614
1615 /// Build a new Objective-C \@try statement.
1616 ///
1617 /// By default, performs semantic analysis to build the new statement.
1618 /// Subclasses may override this routine to provide different behavior.
1619 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1620 Stmt *TryBody,
1621 MultiStmtArg CatchStmts,
1622 Stmt *Finally) {
1623 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1624 Finally);
1625 }
1626
1627 /// Rebuild an Objective-C exception declaration.
1628 ///
1629 /// By default, performs semantic analysis to build the new declaration.
1630 /// Subclasses may override this routine to provide different behavior.
1631 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1632 TypeSourceInfo *TInfo, QualType T) {
1633 return getSema().ObjC().BuildObjCExceptionDecl(
1634 TInfo, T, ExceptionDecl->getInnerLocStart(),
1635 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1636 }
1637
1638 /// Build a new Objective-C \@catch statement.
1639 ///
1640 /// By default, performs semantic analysis to build the new statement.
1641 /// Subclasses may override this routine to provide different behavior.
1642 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1643 SourceLocation RParenLoc,
1644 VarDecl *Var,
1645 Stmt *Body) {
1646 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1647 }
1648
1649 /// Build a new Objective-C \@finally statement.
1650 ///
1651 /// By default, performs semantic analysis to build the new statement.
1652 /// Subclasses may override this routine to provide different behavior.
1653 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1654 Stmt *Body) {
1655 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1656 }
1657
1658 /// Build a new Objective-C \@throw statement.
1659 ///
1660 /// By default, performs semantic analysis to build the new statement.
1661 /// Subclasses may override this routine to provide different behavior.
1662 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1663 Expr *Operand) {
1664 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1665 }
1666
1667 /// Build a new OpenMP Canonical loop.
1668 ///
1669 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1670 /// OMPCanonicalLoop.
1671 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1672 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1673 }
1674
1675 /// Build a new OpenMP executable directive.
1676 ///
1677 /// By default, performs semantic analysis to build the new statement.
1678 /// Subclasses may override this routine to provide different behavior.
1679 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1680 DeclarationNameInfo DirName,
1681 OpenMPDirectiveKind CancelRegion,
1682 ArrayRef<OMPClause *> Clauses,
1683 Stmt *AStmt, SourceLocation StartLoc,
1684 SourceLocation EndLoc) {
1685
1686 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1687 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1688 }
1689
1690 /// Build a new OpenMP informational directive.
1691 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1692 DeclarationNameInfo DirName,
1693 ArrayRef<OMPClause *> Clauses,
1694 Stmt *AStmt,
1695 SourceLocation StartLoc,
1696 SourceLocation EndLoc) {
1697
1698 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1699 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1700 }
1701
1702 /// Build a new OpenMP 'if' clause.
1703 ///
1704 /// By default, performs semantic analysis to build the new OpenMP clause.
1705 /// Subclasses may override this routine to provide different behavior.
1706 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1707 Expr *Condition, SourceLocation StartLoc,
1708 SourceLocation LParenLoc,
1709 SourceLocation NameModifierLoc,
1710 SourceLocation ColonLoc,
1711 SourceLocation EndLoc) {
1712 return getSema().OpenMP().ActOnOpenMPIfClause(
1713 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1714 EndLoc);
1715 }
1716
1717 /// Build a new OpenMP 'final' clause.
1718 ///
1719 /// By default, performs semantic analysis to build the new OpenMP clause.
1720 /// Subclasses may override this routine to provide different behavior.
1721 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1722 SourceLocation LParenLoc,
1723 SourceLocation EndLoc) {
1724 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1725 LParenLoc, EndLoc);
1726 }
1727
1728 /// Build a new OpenMP 'num_threads' clause.
1729 ///
1730 /// By default, performs semantic analysis to build the new OpenMP clause.
1731 /// Subclasses may override this routine to provide different behavior.
1732 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1733 Expr *NumThreads,
1734 SourceLocation StartLoc,
1735 SourceLocation LParenLoc,
1736 SourceLocation ModifierLoc,
1737 SourceLocation EndLoc) {
1738 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1739 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1740 }
1741
1742 /// Build a new OpenMP 'safelen' clause.
1743 ///
1744 /// By default, performs semantic analysis to build the new OpenMP clause.
1745 /// Subclasses may override this routine to provide different behavior.
1746 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1747 SourceLocation LParenLoc,
1748 SourceLocation EndLoc) {
1749 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1750 EndLoc);
1751 }
1752
1753 /// Build a new OpenMP 'simdlen' clause.
1754 ///
1755 /// By default, performs semantic analysis to build the new OpenMP clause.
1756 /// Subclasses may override this routine to provide different behavior.
1757 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1758 SourceLocation LParenLoc,
1759 SourceLocation EndLoc) {
1760 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1761 EndLoc);
1762 }
1763
1764 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1765 SourceLocation StartLoc,
1766 SourceLocation LParenLoc,
1767 SourceLocation EndLoc) {
1768 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1769 EndLoc);
1770 }
1771
1772 /// Build a new OpenMP 'permutation' clause.
1773 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1774 SourceLocation StartLoc,
1775 SourceLocation LParenLoc,
1776 SourceLocation EndLoc) {
1777 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1778 LParenLoc, EndLoc);
1779 }
1780
1781 /// Build a new OpenMP 'full' clause.
1782 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1783 SourceLocation EndLoc) {
1784 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1785 }
1786
1787 /// Build a new OpenMP 'partial' clause.
1788 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1789 SourceLocation LParenLoc,
1790 SourceLocation EndLoc) {
1791 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1792 LParenLoc, EndLoc);
1793 }
1794
1795 OMPClause *
1796 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1797 SourceLocation LParenLoc, SourceLocation FirstLoc,
1798 SourceLocation CountLoc, SourceLocation EndLoc) {
1799 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1800 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1801 }
1802
1803 /// Build a new OpenMP 'allocator' clause.
1804 ///
1805 /// By default, performs semantic analysis to build the new OpenMP clause.
1806 /// Subclasses may override this routine to provide different behavior.
1807 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1808 SourceLocation LParenLoc,
1809 SourceLocation EndLoc) {
1810 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1811 EndLoc);
1812 }
1813
1814 /// Build a new OpenMP 'collapse' clause.
1815 ///
1816 /// By default, performs semantic analysis to build the new OpenMP clause.
1817 /// Subclasses may override this routine to provide different behavior.
1818 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1819 SourceLocation LParenLoc,
1820 SourceLocation EndLoc) {
1821 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1822 LParenLoc, EndLoc);
1823 }
1824
1825 /// Build a new OpenMP 'default' clause.
1826 ///
1827 /// By default, performs semantic analysis to build the new OpenMP clause.
1828 /// Subclasses may override this routine to provide different behavior.
1829 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1830 OpenMPDefaultClauseVariableCategory VCKind,
1831 SourceLocation VCLoc,
1832 SourceLocation StartLoc,
1833 SourceLocation LParenLoc,
1834 SourceLocation EndLoc) {
1835 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1836 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1837 }
1838
1839 /// Build a new OpenMP 'proc_bind' clause.
1840 ///
1841 /// By default, performs semantic analysis to build the new OpenMP clause.
1842 /// Subclasses may override this routine to provide different behavior.
1843 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1844 SourceLocation KindKwLoc,
1845 SourceLocation StartLoc,
1846 SourceLocation LParenLoc,
1847 SourceLocation EndLoc) {
1848 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1849 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1850 }
1851 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1852 SourceLocation StartLoc,
1853 SourceLocation LParenLoc,
1854 SourceLocation EndLoc) {
1855 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1856 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1857 }
1858
1859 /// Build a new OpenMP 'schedule' clause.
1860 ///
1861 /// By default, performs semantic analysis to build the new OpenMP clause.
1862 /// Subclasses may override this routine to provide different behavior.
1863 OMPClause *RebuildOMPScheduleClause(
1864 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1865 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1866 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1867 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1868 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1869 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1870 CommaLoc, EndLoc);
1871 }
1872
1873 /// Build a new OpenMP 'ordered' clause.
1874 ///
1875 /// By default, performs semantic analysis to build the new OpenMP clause.
1876 /// Subclasses may override this routine to provide different behavior.
1877 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1878 SourceLocation EndLoc,
1879 SourceLocation LParenLoc, Expr *Num) {
1880 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1881 LParenLoc, Num);
1882 }
1883
1884 /// Build a new OpenMP 'nowait' clause.
1885 ///
1886 /// By default, performs semantic analysis to build the new OpenMP clause.
1887 /// Subclasses may override this routine to provide different behavior.
1888 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1889 SourceLocation LParenLoc,
1890 SourceLocation EndLoc) {
1891 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1892 LParenLoc, Condition);
1893 }
1894
1895 /// Build a new OpenMP 'private' clause.
1896 ///
1897 /// By default, performs semantic analysis to build the new OpenMP clause.
1898 /// Subclasses may override this routine to provide different behavior.
1899 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1900 SourceLocation StartLoc,
1901 SourceLocation LParenLoc,
1902 SourceLocation EndLoc) {
1903 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1904 LParenLoc, EndLoc);
1905 }
1906
1907 /// Build a new OpenMP 'firstprivate' clause.
1908 ///
1909 /// By default, performs semantic analysis to build the new OpenMP clause.
1910 /// Subclasses may override this routine to provide different behavior.
1911 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1912 SourceLocation StartLoc,
1913 SourceLocation LParenLoc,
1914 SourceLocation EndLoc) {
1915 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1916 LParenLoc, EndLoc);
1917 }
1918
1919 /// Build a new OpenMP 'lastprivate' clause.
1920 ///
1921 /// By default, performs semantic analysis to build the new OpenMP clause.
1922 /// Subclasses may override this routine to provide different behavior.
1923 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1924 OpenMPLastprivateModifier LPKind,
1925 SourceLocation LPKindLoc,
1926 SourceLocation ColonLoc,
1927 SourceLocation StartLoc,
1928 SourceLocation LParenLoc,
1929 SourceLocation EndLoc) {
1930 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1931 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1932 }
1933
1934 /// Build a new OpenMP 'shared' clause.
1935 ///
1936 /// By default, performs semantic analysis to build the new OpenMP clause.
1937 /// Subclasses may override this routine to provide different behavior.
1938 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1939 SourceLocation StartLoc,
1940 SourceLocation LParenLoc,
1941 SourceLocation EndLoc) {
1942 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1943 LParenLoc, EndLoc);
1944 }
1945
1946 /// Build a new OpenMP 'reduction' clause.
1947 ///
1948 /// By default, performs semantic analysis to build the new statement.
1949 /// Subclasses may override this routine to provide different behavior.
1950 OMPClause *RebuildOMPReductionClause(
1951 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1952 OpenMPOriginalSharingModifier OriginalSharingModifier,
1953 SourceLocation StartLoc, SourceLocation LParenLoc,
1954 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1955 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1956 const DeclarationNameInfo &ReductionId,
1957 ArrayRef<Expr *> UnresolvedReductions) {
1958 return getSema().OpenMP().ActOnOpenMPReductionClause(
1959 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1960 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1961 UnresolvedReductions);
1962 }
1963
1964 /// Build a new OpenMP 'task_reduction' clause.
1965 ///
1966 /// By default, performs semantic analysis to build the new statement.
1967 /// Subclasses may override this routine to provide different behavior.
1968 OMPClause *RebuildOMPTaskReductionClause(
1969 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1970 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1971 CXXScopeSpec &ReductionIdScopeSpec,
1972 const DeclarationNameInfo &ReductionId,
1973 ArrayRef<Expr *> UnresolvedReductions) {
1974 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1975 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1976 ReductionId, UnresolvedReductions);
1977 }
1978
1979 /// Build a new OpenMP 'in_reduction' clause.
1980 ///
1981 /// By default, performs semantic analysis to build the new statement.
1982 /// Subclasses may override this routine to provide different behavior.
1983 OMPClause *
1984 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1985 SourceLocation LParenLoc, SourceLocation ColonLoc,
1986 SourceLocation EndLoc,
1987 CXXScopeSpec &ReductionIdScopeSpec,
1988 const DeclarationNameInfo &ReductionId,
1989 ArrayRef<Expr *> UnresolvedReductions) {
1990 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1991 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1992 ReductionId, UnresolvedReductions);
1993 }
1994
1995 /// Build a new OpenMP 'linear' clause.
1996 ///
1997 /// By default, performs semantic analysis to build the new OpenMP clause.
1998 /// Subclasses may override this routine to provide different behavior.
1999 OMPClause *RebuildOMPLinearClause(
2000 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2001 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2002 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2003 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2004 return getSema().OpenMP().ActOnOpenMPLinearClause(
2005 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2006 StepModifierLoc, EndLoc);
2007 }
2008
2009 /// Build a new OpenMP 'aligned' clause.
2010 ///
2011 /// By default, performs semantic analysis to build the new OpenMP clause.
2012 /// Subclasses may override this routine to provide different behavior.
2013 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2014 SourceLocation StartLoc,
2015 SourceLocation LParenLoc,
2016 SourceLocation ColonLoc,
2017 SourceLocation EndLoc) {
2018 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2019 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2020 }
2021
2022 /// Build a new OpenMP 'copyin' clause.
2023 ///
2024 /// By default, performs semantic analysis to build the new OpenMP clause.
2025 /// Subclasses may override this routine to provide different behavior.
2026 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2027 SourceLocation StartLoc,
2028 SourceLocation LParenLoc,
2029 SourceLocation EndLoc) {
2030 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2031 LParenLoc, EndLoc);
2032 }
2033
2034 /// Build a new OpenMP 'copyprivate' clause.
2035 ///
2036 /// By default, performs semantic analysis to build the new OpenMP clause.
2037 /// Subclasses may override this routine to provide different behavior.
2038 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2039 SourceLocation StartLoc,
2040 SourceLocation LParenLoc,
2041 SourceLocation EndLoc) {
2042 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2043 LParenLoc, EndLoc);
2044 }
2045
2046 /// Build a new OpenMP 'flush' pseudo clause.
2047 ///
2048 /// By default, performs semantic analysis to build the new OpenMP clause.
2049 /// Subclasses may override this routine to provide different behavior.
2050 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2051 SourceLocation StartLoc,
2052 SourceLocation LParenLoc,
2053 SourceLocation EndLoc) {
2054 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2055 LParenLoc, EndLoc);
2056 }
2057
2058 /// Build a new OpenMP 'depobj' pseudo clause.
2059 ///
2060 /// By default, performs semantic analysis to build the new OpenMP clause.
2061 /// Subclasses may override this routine to provide different behavior.
2062 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2063 SourceLocation LParenLoc,
2064 SourceLocation EndLoc) {
2065 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2066 LParenLoc, EndLoc);
2067 }
2068
2069 /// Build a new OpenMP 'depend' pseudo clause.
2070 ///
2071 /// By default, performs semantic analysis to build the new OpenMP clause.
2072 /// Subclasses may override this routine to provide different behavior.
2073 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2074 Expr *DepModifier, ArrayRef<Expr *> VarList,
2075 SourceLocation StartLoc,
2076 SourceLocation LParenLoc,
2077 SourceLocation EndLoc) {
2078 return getSema().OpenMP().ActOnOpenMPDependClause(
2079 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2080 }
2081
2082 /// Build a new OpenMP 'device' clause.
2083 ///
2084 /// By default, performs semantic analysis to build the new statement.
2085 /// Subclasses may override this routine to provide different behavior.
2086 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2087 Expr *Device, SourceLocation StartLoc,
2088 SourceLocation LParenLoc,
2089 SourceLocation ModifierLoc,
2090 SourceLocation EndLoc) {
2091 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2092 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2093 }
2094
2095 /// Build a new OpenMP 'map' clause.
2096 ///
2097 /// By default, performs semantic analysis to build the new OpenMP clause.
2098 /// Subclasses may override this routine to provide different behavior.
2099 OMPClause *RebuildOMPMapClause(
2100 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2101 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2102 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2103 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2104 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2105 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2106 return getSema().OpenMP().ActOnOpenMPMapClause(
2107 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2108 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2109 ColonLoc, VarList, Locs,
2110 /*NoDiagnose=*/false, UnresolvedMappers);
2111 }
2112
2113 /// Build a new OpenMP 'allocate' clause.
2114 ///
2115 /// By default, performs semantic analysis to build the new OpenMP clause.
2116 /// Subclasses may override this routine to provide different behavior.
2117 OMPClause *
2118 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2119 OpenMPAllocateClauseModifier FirstModifier,
2120 SourceLocation FirstModifierLoc,
2121 OpenMPAllocateClauseModifier SecondModifier,
2122 SourceLocation SecondModifierLoc,
2123 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2124 SourceLocation LParenLoc, SourceLocation ColonLoc,
2125 SourceLocation EndLoc) {
2126 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2127 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2128 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2129 }
2130
2131 /// Build a new OpenMP 'num_teams' clause.
2132 ///
2133 /// By default, performs semantic analysis to build the new statement.
2134 /// Subclasses may override this routine to provide different behavior.
2135 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2136 SourceLocation StartLoc,
2137 SourceLocation LParenLoc,
2138 SourceLocation EndLoc) {
2139 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2140 LParenLoc, EndLoc);
2141 }
2142
2143 /// Build a new OpenMP 'thread_limit' clause.
2144 ///
2145 /// By default, performs semantic analysis to build the new statement.
2146 /// Subclasses may override this routine to provide different behavior.
2147 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2148 SourceLocation StartLoc,
2149 SourceLocation LParenLoc,
2150 SourceLocation EndLoc) {
2151 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2152 LParenLoc, EndLoc);
2153 }
2154
2155 /// Build a new OpenMP 'priority' clause.
2156 ///
2157 /// By default, performs semantic analysis to build the new statement.
2158 /// Subclasses may override this routine to provide different behavior.
2159 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2160 SourceLocation LParenLoc,
2161 SourceLocation EndLoc) {
2162 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2163 LParenLoc, EndLoc);
2164 }
2165
2166 /// Build a new OpenMP 'grainsize' clause.
2167 ///
2168 /// By default, performs semantic analysis to build the new statement.
2169 /// Subclasses may override this routine to provide different behavior.
2170 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2171 Expr *Device, SourceLocation StartLoc,
2172 SourceLocation LParenLoc,
2173 SourceLocation ModifierLoc,
2174 SourceLocation EndLoc) {
2175 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2176 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2177 }
2178
2179 /// Build a new OpenMP 'num_tasks' clause.
2180 ///
2181 /// By default, performs semantic analysis to build the new statement.
2182 /// Subclasses may override this routine to provide different behavior.
2183 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2184 Expr *NumTasks, SourceLocation StartLoc,
2185 SourceLocation LParenLoc,
2186 SourceLocation ModifierLoc,
2187 SourceLocation EndLoc) {
2188 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2189 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2190 }
2191
2192 /// Build a new OpenMP 'hint' clause.
2193 ///
2194 /// By default, performs semantic analysis to build the new statement.
2195 /// Subclasses may override this routine to provide different behavior.
2196 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2197 SourceLocation LParenLoc,
2198 SourceLocation EndLoc) {
2199 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2200 EndLoc);
2201 }
2202
2203 /// Build a new OpenMP 'detach' clause.
2204 ///
2205 /// By default, performs semantic analysis to build the new statement.
2206 /// Subclasses may override this routine to provide different behavior.
2207 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2208 SourceLocation LParenLoc,
2209 SourceLocation EndLoc) {
2210 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2211 EndLoc);
2212 }
2213
2214 /// Build a new OpenMP 'dist_schedule' clause.
2215 ///
2216 /// By default, performs semantic analysis to build the new OpenMP clause.
2217 /// Subclasses may override this routine to provide different behavior.
2218 OMPClause *
2219 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2220 Expr *ChunkSize, SourceLocation StartLoc,
2221 SourceLocation LParenLoc, SourceLocation KindLoc,
2222 SourceLocation CommaLoc, SourceLocation EndLoc) {
2223 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2224 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2225 }
2226
2227 /// Build a new OpenMP 'to' clause.
2228 ///
2229 /// By default, performs semantic analysis to build the new statement.
2230 /// Subclasses may override this routine to provide different behavior.
2231 OMPClause *
2232 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2233 ArrayRef<SourceLocation> MotionModifiersLoc,
2234 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2235 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2236 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2237 ArrayRef<Expr *> UnresolvedMappers) {
2238 return getSema().OpenMP().ActOnOpenMPToClause(
2239 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2240 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2241 UnresolvedMappers);
2242 }
2243
2244 /// Build a new OpenMP 'from' clause.
2245 ///
2246 /// By default, performs semantic analysis to build the new statement.
2247 /// Subclasses may override this routine to provide different behavior.
2248 OMPClause *
2249 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2250 ArrayRef<SourceLocation> MotionModifiersLoc,
2251 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2252 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2253 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2254 ArrayRef<Expr *> UnresolvedMappers) {
2255 return getSema().OpenMP().ActOnOpenMPFromClause(
2256 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2257 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2258 UnresolvedMappers);
2259 }
2260
2261 /// Build a new OpenMP 'use_device_ptr' clause.
2262 ///
2263 /// By default, performs semantic analysis to build the new OpenMP clause.
2264 /// Subclasses may override this routine to provide different behavior.
2265 OMPClause *RebuildOMPUseDevicePtrClause(
2266 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2267 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2268 SourceLocation FallbackModifierLoc) {
2269 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2270 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2271 }
2272
2273 /// Build a new OpenMP 'use_device_addr' clause.
2274 ///
2275 /// By default, performs semantic analysis to build the new OpenMP clause.
2276 /// Subclasses may override this routine to provide different behavior.
2277 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2278 const OMPVarListLocTy &Locs) {
2279 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2280 }
2281
2282 /// Build a new OpenMP 'is_device_ptr' clause.
2283 ///
2284 /// By default, performs semantic analysis to build the new OpenMP clause.
2285 /// Subclasses may override this routine to provide different behavior.
2286 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2287 const OMPVarListLocTy &Locs) {
2288 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2289 }
2290
2291 /// Build a new OpenMP 'has_device_addr' clause.
2292 ///
2293 /// By default, performs semantic analysis to build the new OpenMP clause.
2294 /// Subclasses may override this routine to provide different behavior.
2295 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2296 const OMPVarListLocTy &Locs) {
2297 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2298 }
2299
2300 /// Build a new OpenMP 'defaultmap' clause.
2301 ///
2302 /// By default, performs semantic analysis to build the new OpenMP clause.
2303 /// Subclasses may override this routine to provide different behavior.
2304 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2305 OpenMPDefaultmapClauseKind Kind,
2306 SourceLocation StartLoc,
2307 SourceLocation LParenLoc,
2308 SourceLocation MLoc,
2309 SourceLocation KindLoc,
2310 SourceLocation EndLoc) {
2311 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2312 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2313 }
2314
2315 /// Build a new OpenMP 'nontemporal' clause.
2316 ///
2317 /// By default, performs semantic analysis to build the new OpenMP clause.
2318 /// Subclasses may override this routine to provide different behavior.
2319 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2320 SourceLocation StartLoc,
2321 SourceLocation LParenLoc,
2322 SourceLocation EndLoc) {
2323 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2324 LParenLoc, EndLoc);
2325 }
2326
2327 /// Build a new OpenMP 'inclusive' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
2331 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2332 SourceLocation StartLoc,
2333 SourceLocation LParenLoc,
2334 SourceLocation EndLoc) {
2335 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2336 LParenLoc, EndLoc);
2337 }
2338
2339 /// Build a new OpenMP 'exclusive' clause.
2340 ///
2341 /// By default, performs semantic analysis to build the new OpenMP clause.
2342 /// Subclasses may override this routine to provide different behavior.
2343 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2344 SourceLocation StartLoc,
2345 SourceLocation LParenLoc,
2346 SourceLocation EndLoc) {
2347 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2348 LParenLoc, EndLoc);
2349 }
2350
2351 /// Build a new OpenMP 'uses_allocators' clause.
2352 ///
2353 /// By default, performs semantic analysis to build the new OpenMP clause.
2354 /// Subclasses may override this routine to provide different behavior.
2355 OMPClause *RebuildOMPUsesAllocatorsClause(
2356 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2357 SourceLocation LParenLoc, SourceLocation EndLoc) {
2358 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2359 StartLoc, LParenLoc, EndLoc, Data);
2360 }
2361
2362 /// Build a new OpenMP 'affinity' clause.
2363 ///
2364 /// By default, performs semantic analysis to build the new OpenMP clause.
2365 /// Subclasses may override this routine to provide different behavior.
2366 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2367 SourceLocation LParenLoc,
2368 SourceLocation ColonLoc,
2369 SourceLocation EndLoc, Expr *Modifier,
2370 ArrayRef<Expr *> Locators) {
2371 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2372 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2373 }
2374
2375 /// Build a new OpenMP 'order' clause.
2376 ///
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
2379 OMPClause *RebuildOMPOrderClause(
2380 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2381 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2382 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2383 return getSema().OpenMP().ActOnOpenMPOrderClause(
2384 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2385 }
2386
2387 /// Build a new OpenMP 'init' clause.
2388 ///
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
2391 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2392 SourceLocation StartLoc,
2393 SourceLocation LParenLoc,
2394 SourceLocation VarLoc,
2395 SourceLocation EndLoc) {
2396 return getSema().OpenMP().ActOnOpenMPInitClause(
2397 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2398 }
2399
2400 /// Build a new OpenMP 'use' clause.
2401 ///
2402 /// By default, performs semantic analysis to build the new OpenMP clause.
2403 /// Subclasses may override this routine to provide different behavior.
2404 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2405 SourceLocation LParenLoc,
2406 SourceLocation VarLoc, SourceLocation EndLoc) {
2407 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2408 LParenLoc, VarLoc, EndLoc);
2409 }
2410
2411 /// Build a new OpenMP 'destroy' clause.
2412 ///
2413 /// By default, performs semantic analysis to build the new OpenMP clause.
2414 /// Subclasses may override this routine to provide different behavior.
2415 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2416 SourceLocation LParenLoc,
2417 SourceLocation VarLoc,
2418 SourceLocation EndLoc) {
2419 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2420 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2421 }
2422
2423 /// Build a new OpenMP 'novariants' clause.
2424 ///
2425 /// By default, performs semantic analysis to build the new OpenMP clause.
2426 /// Subclasses may override this routine to provide different behavior.
2427 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2428 SourceLocation StartLoc,
2429 SourceLocation LParenLoc,
2430 SourceLocation EndLoc) {
2431 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2432 LParenLoc, EndLoc);
2433 }
2434
2435 /// Build a new OpenMP 'nocontext' clause.
2436 ///
2437 /// By default, performs semantic analysis to build the new OpenMP clause.
2438 /// Subclasses may override this routine to provide different behavior.
2439 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2440 SourceLocation LParenLoc,
2441 SourceLocation EndLoc) {
2442 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2443 LParenLoc, EndLoc);
2444 }
2445
2446 /// Build a new OpenMP 'filter' clause.
2447 ///
2448 /// By default, performs semantic analysis to build the new OpenMP clause.
2449 /// Subclasses may override this routine to provide different behavior.
2450 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2451 SourceLocation LParenLoc,
2452 SourceLocation EndLoc) {
2453 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2454 LParenLoc, EndLoc);
2455 }
2456
2457 /// Build a new OpenMP 'bind' clause.
2458 ///
2459 /// By default, performs semantic analysis to build the new OpenMP clause.
2460 /// Subclasses may override this routine to provide different behavior.
2461 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2462 SourceLocation KindLoc,
2463 SourceLocation StartLoc,
2464 SourceLocation LParenLoc,
2465 SourceLocation EndLoc) {
2466 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2467 LParenLoc, EndLoc);
2468 }
2469
2470 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2471 ///
2472 /// By default, performs semantic analysis to build the new OpenMP clause.
2473 /// Subclasses may override this routine to provide different behavior.
2474 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2475 SourceLocation LParenLoc,
2476 SourceLocation EndLoc) {
2477 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2478 LParenLoc, EndLoc);
2479 }
2480
2481 /// Build a new OpenMP 'dyn_groupprivate' clause.
2482 ///
2483 /// By default, performs semantic analysis to build the new OpenMP clause.
2484 /// Subclasses may override this routine to provide different behavior.
2485 OMPClause *RebuildOMPDynGroupprivateClause(
2486 OpenMPDynGroupprivateClauseModifier M1,
2487 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2488 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2489 SourceLocation M2Loc, SourceLocation EndLoc) {
2490 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2491 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2492 }
2493
2494 /// Build a new OpenMP 'ompx_attribute' clause.
2495 ///
2496 /// By default, performs semantic analysis to build the new OpenMP clause.
2497 /// Subclasses may override this routine to provide different behavior.
2498 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2499 SourceLocation StartLoc,
2500 SourceLocation LParenLoc,
2501 SourceLocation EndLoc) {
2502 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2503 LParenLoc, EndLoc);
2504 }
2505
2506 /// Build a new OpenMP 'ompx_bare' clause.
2507 ///
2508 /// By default, performs semantic analysis to build the new OpenMP clause.
2509 /// Subclasses may override this routine to provide different behavior.
2510 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2511 SourceLocation EndLoc) {
2512 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2513 }
2514
2515 /// Build a new OpenMP 'align' clause.
2516 ///
2517 /// By default, performs semantic analysis to build the new OpenMP clause.
2518 /// Subclasses may override this routine to provide different behavior.
2519 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2520 SourceLocation LParenLoc,
2521 SourceLocation EndLoc) {
2522 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2523 EndLoc);
2524 }
2525
2526 /// Build a new OpenMP 'at' clause.
2527 ///
2528 /// By default, performs semantic analysis to build the new OpenMP clause.
2529 /// Subclasses may override this routine to provide different behavior.
2530 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2531 SourceLocation StartLoc,
2532 SourceLocation LParenLoc,
2533 SourceLocation EndLoc) {
2534 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2535 LParenLoc, EndLoc);
2536 }
2537
2538 /// Build a new OpenMP 'severity' clause.
2539 ///
2540 /// By default, performs semantic analysis to build the new OpenMP clause.
2541 /// Subclasses may override this routine to provide different behavior.
2542 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2543 SourceLocation KwLoc,
2544 SourceLocation StartLoc,
2545 SourceLocation LParenLoc,
2546 SourceLocation EndLoc) {
2547 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2548 LParenLoc, EndLoc);
2549 }
2550
2551 /// Build a new OpenMP 'message' clause.
2552 ///
2553 /// By default, performs semantic analysis to build the new OpenMP clause.
2554 /// Subclasses may override this routine to provide different behavior.
2555 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2556 SourceLocation LParenLoc,
2557 SourceLocation EndLoc) {
2558 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2559 EndLoc);
2560 }
2561
2562 /// Build a new OpenMP 'doacross' clause.
2563 ///
2564 /// By default, performs semantic analysis to build the new OpenMP clause.
2565 /// Subclasses may override this routine to provide different behavior.
2566 OMPClause *
2567 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2568 SourceLocation DepLoc, SourceLocation ColonLoc,
2569 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2570 SourceLocation LParenLoc, SourceLocation EndLoc) {
2571 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2572 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2573 }
2574
2575 /// Build a new OpenMP 'holds' clause.
2576 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2577 SourceLocation LParenLoc,
2578 SourceLocation EndLoc) {
2579 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2580 EndLoc);
2581 }
2582
2583 /// Rebuild the operand to an Objective-C \@synchronized statement.
2584 ///
2585 /// By default, performs semantic analysis to build the new statement.
2586 /// Subclasses may override this routine to provide different behavior.
2587 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2588 Expr *object) {
2589 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2590 }
2591
2592 /// Build a new Objective-C \@synchronized statement.
2593 ///
2594 /// By default, performs semantic analysis to build the new statement.
2595 /// Subclasses may override this routine to provide different behavior.
2596 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2597 Expr *Object, Stmt *Body) {
2598 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2599 }
2600
2601 /// Build a new Objective-C \@autoreleasepool statement.
2602 ///
2603 /// By default, performs semantic analysis to build the new statement.
2604 /// Subclasses may override this routine to provide different behavior.
2605 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2606 Stmt *Body) {
2607 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2608 }
2609
2610 /// Build a new Objective-C fast enumeration statement.
2611 ///
2612 /// By default, performs semantic analysis to build the new statement.
2613 /// Subclasses may override this routine to provide different behavior.
2614 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2615 Stmt *Element,
2616 Expr *Collection,
2617 SourceLocation RParenLoc,
2618 Stmt *Body) {
2619 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2620 ForLoc, Element, Collection, RParenLoc);
2621 if (ForEachStmt.isInvalid())
2622 return StmtError();
2623
2624 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2625 Body);
2626 }
2627
2628 /// Build a new C++ exception declaration.
2629 ///
2630 /// By default, performs semantic analysis to build the new decaration.
2631 /// Subclasses may override this routine to provide different behavior.
2632 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2633 TypeSourceInfo *Declarator,
2634 SourceLocation StartLoc,
2635 SourceLocation IdLoc,
2636 IdentifierInfo *Id) {
2637 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2638 StartLoc, IdLoc, Id);
2639 if (Var)
2640 getSema().CurContext->addDecl(Var);
2641 return Var;
2642 }
2643
2644 /// Build a new C++ catch statement.
2645 ///
2646 /// By default, performs semantic analysis to build the new statement.
2647 /// Subclasses may override this routine to provide different behavior.
2648 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2649 VarDecl *ExceptionDecl,
2650 Stmt *Handler) {
2651 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2652 Handler));
2653 }
2654
2655 /// Build a new C++ try statement.
2656 ///
2657 /// By default, performs semantic analysis to build the new statement.
2658 /// Subclasses may override this routine to provide different behavior.
2659 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2660 ArrayRef<Stmt *> Handlers) {
2661 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2662 }
2663
2664 /// Build a new C++0x range-based for statement.
2665 ///
2666 /// By default, performs semantic analysis to build the new statement.
2667 /// Subclasses may override this routine to provide different behavior.
2668 StmtResult RebuildCXXForRangeStmt(
2669 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2670 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2671 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2672 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2673 // If we've just learned that the range is actually an Objective-C
2674 // collection, treat this as an Objective-C fast enumeration loop.
2675 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2676 if (RangeStmt->isSingleDecl()) {
2677 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2678 if (RangeVar->isInvalidDecl())
2679 return StmtError();
2680
2681 Expr *RangeExpr = RangeVar->getInit();
2682 if (!RangeExpr->isTypeDependent() &&
2683 RangeExpr->getType()->isObjCObjectPointerType()) {
2684 // FIXME: Support init-statements in Objective-C++20 ranged for
2685 // statement.
2686 if (Init) {
2687 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2688 DiagID: diag::err_objc_for_range_init_stmt)
2689 << Init->getSourceRange();
2690 }
2691 return getSema().ObjC().ActOnObjCForCollectionStmt(
2692 ForLoc, LoopVar, RangeExpr, RParenLoc);
2693 }
2694 }
2695 }
2696 }
2697
2698 return getSema().BuildCXXForRangeStmt(
2699 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2700 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2701 }
2702
2703 /// Build a new C++0x range-based for statement.
2704 ///
2705 /// By default, performs semantic analysis to build the new statement.
2706 /// Subclasses may override this routine to provide different behavior.
2707 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2708 bool IsIfExists,
2709 NestedNameSpecifierLoc QualifierLoc,
2710 DeclarationNameInfo NameInfo,
2711 Stmt *Nested) {
2712 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2713 QualifierLoc, NameInfo, Nested);
2714 }
2715
2716 /// Attach body to a C++0x range-based for statement.
2717 ///
2718 /// By default, performs semantic analysis to finish the new statement.
2719 /// Subclasses may override this routine to provide different behavior.
2720 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2721 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2722 }
2723
2724 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2725 Stmt *TryBlock, Stmt *Handler) {
2726 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2727 }
2728
2729 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2730 Stmt *Block) {
2731 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2732 }
2733
2734 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2735 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2736 }
2737
2738 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2739 SourceLocation LParen,
2740 SourceLocation RParen,
2741 TypeSourceInfo *TSI) {
2742 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2743 TSI);
2744 }
2745
2746 /// Build a new predefined expression.
2747 ///
2748 /// By default, performs semantic analysis to build the new expression.
2749 /// Subclasses may override this routine to provide different behavior.
2750 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2751 return getSema().BuildPredefinedExpr(Loc, IK);
2752 }
2753
2754 /// Build a new expression that references a declaration.
2755 ///
2756 /// By default, performs semantic analysis to build the new expression.
2757 /// Subclasses may override this routine to provide different behavior.
2758 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2759 LookupResult &R,
2760 bool RequiresADL) {
2761 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2762 }
2763
2764
2765 /// Build a new expression that references a declaration.
2766 ///
2767 /// By default, performs semantic analysis to build the new expression.
2768 /// Subclasses may override this routine to provide different behavior.
2769 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2770 ValueDecl *VD,
2771 const DeclarationNameInfo &NameInfo,
2772 NamedDecl *Found,
2773 TemplateArgumentListInfo *TemplateArgs) {
2774 CXXScopeSpec SS;
2775 SS.Adopt(Other: QualifierLoc);
2776 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2777 TemplateArgs);
2778 }
2779
2780 /// Build a new expression in parentheses.
2781 ///
2782 /// By default, performs semantic analysis to build the new expression.
2783 /// Subclasses may override this routine to provide different behavior.
2784 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2785 SourceLocation RParen) {
2786 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2787 }
2788
2789 /// Build a new pseudo-destructor expression.
2790 ///
2791 /// By default, performs semantic analysis to build the new expression.
2792 /// Subclasses may override this routine to provide different behavior.
2793 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2794 SourceLocation OperatorLoc,
2795 bool isArrow,
2796 CXXScopeSpec &SS,
2797 TypeSourceInfo *ScopeType,
2798 SourceLocation CCLoc,
2799 SourceLocation TildeLoc,
2800 PseudoDestructorTypeStorage Destroyed);
2801
2802 /// Build a new unary operator expression.
2803 ///
2804 /// By default, performs semantic analysis to build the new expression.
2805 /// Subclasses may override this routine to provide different behavior.
2806 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2807 UnaryOperatorKind Opc,
2808 Expr *SubExpr) {
2809 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2810 }
2811
2812 /// Build a new builtin offsetof expression.
2813 ///
2814 /// By default, performs semantic analysis to build the new expression.
2815 /// Subclasses may override this routine to provide different behavior.
2816 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2817 TypeSourceInfo *Type,
2818 ArrayRef<Sema::OffsetOfComponent> Components,
2819 SourceLocation RParenLoc) {
2820 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2821 RParenLoc);
2822 }
2823
2824 /// Build a new sizeof, alignof or vec_step expression with a
2825 /// type argument.
2826 ///
2827 /// By default, performs semantic analysis to build the new expression.
2828 /// Subclasses may override this routine to provide different behavior.
2829 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2830 SourceLocation OpLoc,
2831 UnaryExprOrTypeTrait ExprKind,
2832 SourceRange R) {
2833 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2834 }
2835
2836 /// Build a new sizeof, alignof or vec step expression with an
2837 /// expression argument.
2838 ///
2839 /// By default, performs semantic analysis to build the new expression.
2840 /// Subclasses may override this routine to provide different behavior.
2841 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2842 UnaryExprOrTypeTrait ExprKind,
2843 SourceRange R) {
2844 ExprResult Result
2845 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2846 if (Result.isInvalid())
2847 return ExprError();
2848
2849 return Result;
2850 }
2851
2852 /// Build a new array subscript expression.
2853 ///
2854 /// By default, performs semantic analysis to build the new expression.
2855 /// Subclasses may override this routine to provide different behavior.
2856 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2857 SourceLocation LBracketLoc,
2858 Expr *RHS,
2859 SourceLocation RBracketLoc) {
2860 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2861 LBracketLoc, RHS,
2862 RBracketLoc);
2863 }
2864
2865 /// Build a new matrix single subscript expression.
2866 ///
2867 /// By default, performs semantic analysis to build the new expression.
2868 /// Subclasses may override this routine to provide different behavior.
2869 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2870 SourceLocation RBracketLoc) {
2871 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2872 RBracketLoc);
2873 }
2874
2875 /// Build a new matrix subscript expression.
2876 ///
2877 /// By default, performs semantic analysis to build the new expression.
2878 /// Subclasses may override this routine to provide different behavior.
2879 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2880 Expr *ColumnIdx,
2881 SourceLocation RBracketLoc) {
2882 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2883 RBracketLoc);
2884 }
2885
2886 /// Build a new array section expression.
2887 ///
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2890 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2891 SourceLocation LBracketLoc,
2892 Expr *LowerBound,
2893 SourceLocation ColonLocFirst,
2894 SourceLocation ColonLocSecond,
2895 Expr *Length, Expr *Stride,
2896 SourceLocation RBracketLoc) {
2897 if (IsOMPArraySection)
2898 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2899 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2900 Stride, RBracketLoc);
2901
2902 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2903 "Stride/second colon not allowed for OpenACC");
2904
2905 return getSema().OpenACC().ActOnArraySectionExpr(
2906 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2907 }
2908
2909 /// Build a new array shaping expression.
2910 ///
2911 /// By default, performs semantic analysis to build the new expression.
2912 /// Subclasses may override this routine to provide different behavior.
2913 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2914 SourceLocation RParenLoc,
2915 ArrayRef<Expr *> Dims,
2916 ArrayRef<SourceRange> BracketsRanges) {
2917 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2918 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2919 }
2920
2921 /// Build a new iterator expression.
2922 ///
2923 /// By default, performs semantic analysis to build the new expression.
2924 /// Subclasses may override this routine to provide different behavior.
2925 ExprResult
2926 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2927 SourceLocation RLoc,
2928 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2929 return getSema().OpenMP().ActOnOMPIteratorExpr(
2930 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2931 }
2932
2933 /// Build a new call expression.
2934 ///
2935 /// By default, performs semantic analysis to build the new expression.
2936 /// Subclasses may override this routine to provide different behavior.
2937 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2938 MultiExprArg Args,
2939 SourceLocation RParenLoc,
2940 Expr *ExecConfig = nullptr) {
2941 return getSema().ActOnCallExpr(
2942 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2943 }
2944
2945 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2946 MultiExprArg Args,
2947 SourceLocation RParenLoc) {
2948 return getSema().ActOnArraySubscriptExpr(
2949 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2950 }
2951
2952 /// Build a new member access expression.
2953 ///
2954 /// By default, performs semantic analysis to build the new expression.
2955 /// Subclasses may override this routine to provide different behavior.
2956 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2957 bool isArrow,
2958 NestedNameSpecifierLoc QualifierLoc,
2959 SourceLocation TemplateKWLoc,
2960 const DeclarationNameInfo &MemberNameInfo,
2961 ValueDecl *Member,
2962 NamedDecl *FoundDecl,
2963 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2964 NamedDecl *FirstQualifierInScope) {
2965 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2966 isArrow);
2967 if (!Member->getDeclName()) {
2968 // We have a reference to an unnamed field. This is always the
2969 // base of an anonymous struct/union member access, i.e. the
2970 // field is always of record type.
2971 assert(Member->getType()->isRecordType() &&
2972 "unnamed member not of record type?");
2973
2974 BaseResult =
2975 getSema().PerformObjectMemberConversion(BaseResult.get(),
2976 QualifierLoc.getNestedNameSpecifier(),
2977 FoundDecl, Member);
2978 if (BaseResult.isInvalid())
2979 return ExprError();
2980 Base = BaseResult.get();
2981
2982 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2983 // from the AST, so we need to re-insert them if needed (since
2984 // `BuildFieldRefereneExpr()` doesn't do this).
2985 if (!isArrow && Base->isPRValue()) {
2986 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2987 if (BaseResult.isInvalid())
2988 return ExprError();
2989 Base = BaseResult.get();
2990 }
2991
2992 CXXScopeSpec EmptySS;
2993 return getSema().BuildFieldReferenceExpr(
2994 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
2995 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
2996 MemberNameInfo);
2997 }
2998
2999 CXXScopeSpec SS;
3000 SS.Adopt(Other: QualifierLoc);
3001
3002 Base = BaseResult.get();
3003 if (Base->containsErrors())
3004 return ExprError();
3005
3006 QualType BaseType = Base->getType();
3007
3008 if (isArrow && !BaseType->isPointerType())
3009 return ExprError();
3010
3011 // FIXME: this involves duplicating earlier analysis in a lot of
3012 // cases; we should avoid this when possible.
3013 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3014 R.addDecl(D: FoundDecl);
3015 R.resolveKind();
3016
3017 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3018 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3019 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3020 ->getType()
3021 ->getPointeeType()
3022 ->getAsCXXRecordDecl()) {
3023 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3024 // In unevaluated contexts, an expression supposed to be a member access
3025 // might reference a member in an unrelated class.
3026 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3027 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3028 VK_LValue, Member->getLocation());
3029 }
3030 }
3031
3032 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3033 SS, TemplateKWLoc,
3034 FirstQualifierInScope,
3035 R, ExplicitTemplateArgs,
3036 /*S*/nullptr);
3037 }
3038
3039 /// Build a new binary operator expression.
3040 ///
3041 /// By default, performs semantic analysis to build the new expression.
3042 /// Subclasses may override this routine to provide different behavior.
3043 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3044 Expr *LHS, Expr *RHS,
3045 bool ForFoldExpression = false) {
3046 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3047 ForFoldExpression);
3048 }
3049
3050 /// Build a new rewritten operator expression.
3051 ///
3052 /// By default, performs semantic analysis to build the new expression.
3053 /// Subclasses may override this routine to provide different behavior.
3054 ExprResult RebuildCXXRewrittenBinaryOperator(
3055 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3056 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3057 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3058 RHS, /*RequiresADL*/false);
3059 }
3060
3061 /// Build a new conditional operator expression.
3062 ///
3063 /// By default, performs semantic analysis to build the new expression.
3064 /// Subclasses may override this routine to provide different behavior.
3065 ExprResult RebuildConditionalOperator(Expr *Cond,
3066 SourceLocation QuestionLoc,
3067 Expr *LHS,
3068 SourceLocation ColonLoc,
3069 Expr *RHS) {
3070 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3071 LHS, RHS);
3072 }
3073
3074 /// Build a new C-style cast expression.
3075 ///
3076 /// By default, performs semantic analysis to build the new expression.
3077 /// Subclasses may override this routine to provide different behavior.
3078 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3079 TypeSourceInfo *TInfo,
3080 SourceLocation RParenLoc,
3081 Expr *SubExpr) {
3082 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3083 SubExpr);
3084 }
3085
3086 /// Build a new compound literal expression.
3087 ///
3088 /// By default, performs semantic analysis to build the new expression.
3089 /// Subclasses may override this routine to provide different behavior.
3090 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3091 TypeSourceInfo *TInfo,
3092 SourceLocation RParenLoc,
3093 Expr *Init) {
3094 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3095 Init);
3096 }
3097
3098 /// Build a new extended vector or matrix element access expression.
3099 ///
3100 /// By default, performs semantic analysis to build the new expression.
3101 /// Subclasses may override this routine to provide different behavior.
3102 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3103 SourceLocation OpLoc,
3104 bool IsArrow,
3105 SourceLocation AccessorLoc,
3106 IdentifierInfo &Accessor) {
3107
3108 CXXScopeSpec SS;
3109 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3110 return getSema().BuildMemberReferenceExpr(
3111 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3112 /*FirstQualifierInScope*/ nullptr, NameInfo,
3113 /* TemplateArgs */ nullptr,
3114 /*S*/ nullptr);
3115 }
3116
3117 /// Build a new initializer list expression.
3118 ///
3119 /// By default, performs semantic analysis to build the new expression.
3120 /// Subclasses may override this routine to provide different behavior.
3121 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3122 MultiExprArg Inits,
3123 SourceLocation RBraceLoc) {
3124 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3125 }
3126
3127 /// Build a new designated initializer expression.
3128 ///
3129 /// By default, performs semantic analysis to build the new expression.
3130 /// Subclasses may override this routine to provide different behavior.
3131 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3132 MultiExprArg ArrayExprs,
3133 SourceLocation EqualOrColonLoc,
3134 bool GNUSyntax,
3135 Expr *Init) {
3136 ExprResult Result
3137 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3138 Init);
3139 if (Result.isInvalid())
3140 return ExprError();
3141
3142 return Result;
3143 }
3144
3145 /// Build a new value-initialized expression.
3146 ///
3147 /// By default, builds the implicit value initialization without performing
3148 /// any semantic analysis. Subclasses may override this routine to provide
3149 /// different behavior.
3150 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3151 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3152 }
3153
3154 /// Build a new \c va_arg expression.
3155 ///
3156 /// By default, performs semantic analysis to build the new expression.
3157 /// Subclasses may override this routine to provide different behavior.
3158 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3159 Expr *SubExpr, TypeSourceInfo *TInfo,
3160 SourceLocation RParenLoc) {
3161 return getSema().BuildVAArgExpr(BuiltinLoc,
3162 SubExpr, TInfo,
3163 RParenLoc);
3164 }
3165
3166 /// Build a new expression list in parentheses.
3167 ///
3168 /// By default, performs semantic analysis to build the new expression.
3169 /// Subclasses may override this routine to provide different behavior.
3170 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3171 MultiExprArg SubExprs,
3172 SourceLocation RParenLoc) {
3173 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3174 }
3175
3176 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3177 unsigned NumUserSpecifiedExprs,
3178 SourceLocation InitLoc,
3179 SourceLocation LParenLoc,
3180 SourceLocation RParenLoc) {
3181 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3182 InitLoc, LParenLoc, RParenLoc);
3183 }
3184
3185 /// Build a new address-of-label expression.
3186 ///
3187 /// By default, performs semantic analysis, using the name of the label
3188 /// rather than attempting to map the label statement itself.
3189 /// Subclasses may override this routine to provide different behavior.
3190 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3191 SourceLocation LabelLoc, LabelDecl *Label) {
3192 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3193 }
3194
3195 /// Build a new GNU statement expression.
3196 ///
3197 /// By default, performs semantic analysis to build the new expression.
3198 /// Subclasses may override this routine to provide different behavior.
3199 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3200 SourceLocation RParenLoc, unsigned TemplateDepth) {
3201 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3202 TemplateDepth);
3203 }
3204
3205 /// Build a new __builtin_choose_expr expression.
3206 ///
3207 /// By default, performs semantic analysis to build the new expression.
3208 /// Subclasses may override this routine to provide different behavior.
3209 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3210 Expr *Cond, Expr *LHS, Expr *RHS,
3211 SourceLocation RParenLoc) {
3212 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3213 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3214 RPLoc: RParenLoc);
3215 }
3216
3217 /// Build a new generic selection expression with an expression predicate.
3218 ///
3219 /// By default, performs semantic analysis to build the new expression.
3220 /// Subclasses may override this routine to provide different behavior.
3221 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3222 SourceLocation DefaultLoc,
3223 SourceLocation RParenLoc,
3224 Expr *ControllingExpr,
3225 ArrayRef<TypeSourceInfo *> Types,
3226 ArrayRef<Expr *> Exprs) {
3227 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3228 /*PredicateIsExpr=*/true,
3229 ControllingExpr, Types, Exprs);
3230 }
3231
3232 /// Build a new generic selection expression with a type predicate.
3233 ///
3234 /// By default, performs semantic analysis to build the new expression.
3235 /// Subclasses may override this routine to provide different behavior.
3236 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3237 SourceLocation DefaultLoc,
3238 SourceLocation RParenLoc,
3239 TypeSourceInfo *ControllingType,
3240 ArrayRef<TypeSourceInfo *> Types,
3241 ArrayRef<Expr *> Exprs) {
3242 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3243 /*PredicateIsExpr=*/false,
3244 ControllingType, Types, Exprs);
3245 }
3246
3247 /// Build a new overloaded operator call expression.
3248 ///
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// The semantic analysis provides the behavior of template instantiation,
3251 /// copying with transformations that turn what looks like an overloaded
3252 /// operator call into a use of a builtin operator, performing
3253 /// argument-dependent lookup, etc. Subclasses may override this routine to
3254 /// provide different behavior.
3255 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3256 SourceLocation OpLoc,
3257 SourceLocation CalleeLoc,
3258 bool RequiresADL,
3259 const UnresolvedSetImpl &Functions,
3260 Expr *First, Expr *Second);
3261
3262 /// Build a new C++ "named" cast expression, such as static_cast or
3263 /// reinterpret_cast.
3264 ///
3265 /// By default, this routine dispatches to one of the more-specific routines
3266 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3267 /// Subclasses may override this routine to provide different behavior.
3268 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3269 Stmt::StmtClass Class,
3270 SourceLocation LAngleLoc,
3271 TypeSourceInfo *TInfo,
3272 SourceLocation RAngleLoc,
3273 SourceLocation LParenLoc,
3274 Expr *SubExpr,
3275 SourceLocation RParenLoc) {
3276 switch (Class) {
3277 case Stmt::CXXStaticCastExprClass:
3278 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3279 RAngleLoc, LParenLoc,
3280 SubExpr, RParenLoc);
3281
3282 case Stmt::CXXDynamicCastExprClass:
3283 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3284 RAngleLoc, LParenLoc,
3285 SubExpr, RParenLoc);
3286
3287 case Stmt::CXXReinterpretCastExprClass:
3288 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3289 RAngleLoc, LParenLoc,
3290 SubExpr,
3291 RParenLoc);
3292
3293 case Stmt::CXXConstCastExprClass:
3294 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3295 RAngleLoc, LParenLoc,
3296 SubExpr, RParenLoc);
3297
3298 case Stmt::CXXAddrspaceCastExprClass:
3299 return getDerived().RebuildCXXAddrspaceCastExpr(
3300 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3301
3302 default:
3303 llvm_unreachable("Invalid C++ named cast");
3304 }
3305 }
3306
3307 /// Build a new C++ static_cast expression.
3308 ///
3309 /// By default, performs semantic analysis to build the new expression.
3310 /// Subclasses may override this routine to provide different behavior.
3311 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3312 SourceLocation LAngleLoc,
3313 TypeSourceInfo *TInfo,
3314 SourceLocation RAngleLoc,
3315 SourceLocation LParenLoc,
3316 Expr *SubExpr,
3317 SourceLocation RParenLoc) {
3318 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3319 TInfo, SubExpr,
3320 SourceRange(LAngleLoc, RAngleLoc),
3321 SourceRange(LParenLoc, RParenLoc));
3322 }
3323
3324 /// Build a new C++ dynamic_cast expression.
3325 ///
3326 /// By default, performs semantic analysis to build the new expression.
3327 /// Subclasses may override this routine to provide different behavior.
3328 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3329 SourceLocation LAngleLoc,
3330 TypeSourceInfo *TInfo,
3331 SourceLocation RAngleLoc,
3332 SourceLocation LParenLoc,
3333 Expr *SubExpr,
3334 SourceLocation RParenLoc) {
3335 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3336 TInfo, SubExpr,
3337 SourceRange(LAngleLoc, RAngleLoc),
3338 SourceRange(LParenLoc, RParenLoc));
3339 }
3340
3341 /// Build a new C++ reinterpret_cast expression.
3342 ///
3343 /// By default, performs semantic analysis to build the new expression.
3344 /// Subclasses may override this routine to provide different behavior.
3345 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3346 SourceLocation LAngleLoc,
3347 TypeSourceInfo *TInfo,
3348 SourceLocation RAngleLoc,
3349 SourceLocation LParenLoc,
3350 Expr *SubExpr,
3351 SourceLocation RParenLoc) {
3352 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3353 TInfo, SubExpr,
3354 SourceRange(LAngleLoc, RAngleLoc),
3355 SourceRange(LParenLoc, RParenLoc));
3356 }
3357
3358 /// Build a new C++ const_cast expression.
3359 ///
3360 /// By default, performs semantic analysis to build the new expression.
3361 /// Subclasses may override this routine to provide different behavior.
3362 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3363 SourceLocation LAngleLoc,
3364 TypeSourceInfo *TInfo,
3365 SourceLocation RAngleLoc,
3366 SourceLocation LParenLoc,
3367 Expr *SubExpr,
3368 SourceLocation RParenLoc) {
3369 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3370 TInfo, SubExpr,
3371 SourceRange(LAngleLoc, RAngleLoc),
3372 SourceRange(LParenLoc, RParenLoc));
3373 }
3374
3375 ExprResult
3376 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3377 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3378 SourceLocation LParenLoc, Expr *SubExpr,
3379 SourceLocation RParenLoc) {
3380 return getSema().BuildCXXNamedCast(
3381 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3382 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3383 }
3384
3385 /// Build a new C++ functional-style cast expression.
3386 ///
3387 /// By default, performs semantic analysis to build the new expression.
3388 /// Subclasses may override this routine to provide different behavior.
3389 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3390 SourceLocation LParenLoc,
3391 Expr *Sub,
3392 SourceLocation RParenLoc,
3393 bool ListInitialization) {
3394 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3395 // CXXParenListInitExpr. Pass its expanded arguments so that the
3396 // CXXParenListInitExpr can be rebuilt.
3397 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3398 return getSema().BuildCXXTypeConstructExpr(
3399 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3400 RParenLoc, ListInitialization);
3401
3402 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3403 return getSema().BuildCXXTypeConstructExpr(
3404 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3405
3406 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3407 MultiExprArg(&Sub, 1), RParenLoc,
3408 ListInitialization);
3409 }
3410
3411 /// Build a new C++ __builtin_bit_cast expression.
3412 ///
3413 /// By default, performs semantic analysis to build the new expression.
3414 /// Subclasses may override this routine to provide different behavior.
3415 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3416 TypeSourceInfo *TSI, Expr *Sub,
3417 SourceLocation RParenLoc) {
3418 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3419 }
3420
3421 /// Build a new C++ typeid(type) expression.
3422 ///
3423 /// By default, performs semantic analysis to build the new expression.
3424 /// Subclasses may override this routine to provide different behavior.
3425 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3426 SourceLocation TypeidLoc,
3427 TypeSourceInfo *Operand,
3428 SourceLocation RParenLoc) {
3429 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3430 RParenLoc);
3431 }
3432
3433
3434 /// Build a new C++ typeid(expr) expression.
3435 ///
3436 /// By default, performs semantic analysis to build the new expression.
3437 /// Subclasses may override this routine to provide different behavior.
3438 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3439 SourceLocation TypeidLoc,
3440 Expr *Operand,
3441 SourceLocation RParenLoc) {
3442 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3443 RParenLoc);
3444 }
3445
3446 /// Build a new C++ __uuidof(type) expression.
3447 ///
3448 /// By default, performs semantic analysis to build the new expression.
3449 /// Subclasses may override this routine to provide different behavior.
3450 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3451 TypeSourceInfo *Operand,
3452 SourceLocation RParenLoc) {
3453 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3454 }
3455
3456 /// Build a new C++ __uuidof(expr) expression.
3457 ///
3458 /// By default, performs semantic analysis to build the new expression.
3459 /// Subclasses may override this routine to provide different behavior.
3460 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3461 Expr *Operand, SourceLocation RParenLoc) {
3462 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3463 }
3464
3465 /// Build a new C++ "this" expression.
3466 ///
3467 /// By default, performs semantic analysis to build a new "this" expression.
3468 /// Subclasses may override this routine to provide different behavior.
3469 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3470 QualType ThisType,
3471 bool isImplicit) {
3472 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3473 return ExprError();
3474 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3475 }
3476
3477 /// Build a new C++ throw expression.
3478 ///
3479 /// By default, performs semantic analysis to build the new expression.
3480 /// Subclasses may override this routine to provide different behavior.
3481 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3482 bool IsThrownVariableInScope) {
3483 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3484 }
3485
3486 /// Build a new C++ default-argument expression.
3487 ///
3488 /// By default, builds a new default-argument expression, which does not
3489 /// require any semantic analysis. Subclasses may override this routine to
3490 /// provide different behavior.
3491 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3492 Expr *RewrittenExpr) {
3493 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3494 RewrittenExpr, UsedContext: getSema().CurContext);
3495 }
3496
3497 /// Build a new C++11 default-initialization expression.
3498 ///
3499 /// By default, builds a new default field initialization expression, which
3500 /// does not require any semantic analysis. Subclasses may override this
3501 /// routine to provide different behavior.
3502 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3503 FieldDecl *Field) {
3504 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3505 }
3506
3507 /// Build a new C++ zero-initialization expression.
3508 ///
3509 /// By default, performs semantic analysis to build the new expression.
3510 /// Subclasses may override this routine to provide different behavior.
3511 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3512 SourceLocation LParenLoc,
3513 SourceLocation RParenLoc) {
3514 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3515 /*ListInitialization=*/false);
3516 }
3517
3518 /// Build a new C++ "new" expression.
3519 ///
3520 /// By default, performs semantic analysis to build the new expression.
3521 /// Subclasses may override this routine to provide different behavior.
3522 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3523 SourceLocation PlacementLParen,
3524 MultiExprArg PlacementArgs,
3525 SourceLocation PlacementRParen,
3526 SourceRange TypeIdParens, QualType AllocatedType,
3527 TypeSourceInfo *AllocatedTypeInfo,
3528 std::optional<Expr *> ArraySize,
3529 SourceRange DirectInitRange, Expr *Initializer) {
3530 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3531 PlacementLParen,
3532 PlacementArgs,
3533 PlacementRParen,
3534 TypeIdParens,
3535 AllocatedType,
3536 AllocatedTypeInfo,
3537 ArraySize,
3538 DirectInitRange,
3539 Initializer);
3540 }
3541
3542 /// Build a new C++ "delete" expression.
3543 ///
3544 /// By default, performs semantic analysis to build the new expression.
3545 /// Subclasses may override this routine to provide different behavior.
3546 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3547 bool IsGlobalDelete,
3548 bool IsArrayForm,
3549 Expr *Operand) {
3550 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3551 Operand);
3552 }
3553
3554 /// Build a new type trait expression.
3555 ///
3556 /// By default, performs semantic analysis to build the new expression.
3557 /// Subclasses may override this routine to provide different behavior.
3558 ExprResult RebuildTypeTrait(TypeTrait Trait,
3559 SourceLocation StartLoc,
3560 ArrayRef<TypeSourceInfo *> Args,
3561 SourceLocation RParenLoc) {
3562 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3563 }
3564
3565 /// Build a new array type trait expression.
3566 ///
3567 /// By default, performs semantic analysis to build the new expression.
3568 /// Subclasses may override this routine to provide different behavior.
3569 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3570 SourceLocation StartLoc,
3571 TypeSourceInfo *TSInfo,
3572 Expr *DimExpr,
3573 SourceLocation RParenLoc) {
3574 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3575 }
3576
3577 /// Build a new expression trait expression.
3578 ///
3579 /// By default, performs semantic analysis to build the new expression.
3580 /// Subclasses may override this routine to provide different behavior.
3581 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3582 SourceLocation StartLoc,
3583 Expr *Queried,
3584 SourceLocation RParenLoc) {
3585 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3586 }
3587
3588 /// Build a new (previously unresolved) declaration reference
3589 /// expression.
3590 ///
3591 /// By default, performs semantic analysis to build the new expression.
3592 /// Subclasses may override this routine to provide different behavior.
3593 ExprResult RebuildDependentScopeDeclRefExpr(
3594 NestedNameSpecifierLoc QualifierLoc,
3595 SourceLocation TemplateKWLoc,
3596 const DeclarationNameInfo &NameInfo,
3597 const TemplateArgumentListInfo *TemplateArgs,
3598 bool IsAddressOfOperand,
3599 TypeSourceInfo **RecoveryTSI) {
3600 CXXScopeSpec SS;
3601 SS.Adopt(Other: QualifierLoc);
3602
3603 if (TemplateArgs || TemplateKWLoc.isValid())
3604 return getSema().BuildQualifiedTemplateIdExpr(
3605 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3606
3607 return getSema().BuildQualifiedDeclarationNameExpr(
3608 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3609 }
3610
3611 /// Build a new template-id expression.
3612 ///
3613 /// By default, performs semantic analysis to build the new expression.
3614 /// Subclasses may override this routine to provide different behavior.
3615 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3616 SourceLocation TemplateKWLoc,
3617 LookupResult &R,
3618 bool RequiresADL,
3619 const TemplateArgumentListInfo *TemplateArgs) {
3620 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3621 TemplateArgs);
3622 }
3623
3624 /// Build a new object-construction expression.
3625 ///
3626 /// By default, performs semantic analysis to build the new expression.
3627 /// Subclasses may override this routine to provide different behavior.
3628 ExprResult RebuildCXXConstructExpr(
3629 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3630 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3631 bool ListInitialization, bool StdInitListInitialization,
3632 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3633 SourceRange ParenRange) {
3634 // Reconstruct the constructor we originally found, which might be
3635 // different if this is a call to an inherited constructor.
3636 CXXConstructorDecl *FoundCtor = Constructor;
3637 if (Constructor->isInheritingConstructor())
3638 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3639
3640 SmallVector<Expr *, 8> ConvertedArgs;
3641 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3642 ConvertedArgs))
3643 return ExprError();
3644
3645 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3646 IsElidable,
3647 ConvertedArgs,
3648 HadMultipleCandidates,
3649 ListInitialization,
3650 StdInitListInitialization,
3651 RequiresZeroInit, ConstructKind,
3652 ParenRange);
3653 }
3654
3655 /// Build a new implicit construction via inherited constructor
3656 /// expression.
3657 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3658 CXXConstructorDecl *Constructor,
3659 bool ConstructsVBase,
3660 bool InheritedFromVBase) {
3661 return new (getSema().Context) CXXInheritedCtorInitExpr(
3662 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3663 }
3664
3665 /// Build a new object-construction expression.
3666 ///
3667 /// By default, performs semantic analysis to build the new expression.
3668 /// Subclasses may override this routine to provide different behavior.
3669 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3670 SourceLocation LParenOrBraceLoc,
3671 MultiExprArg Args,
3672 SourceLocation RParenOrBraceLoc,
3673 bool ListInitialization) {
3674 return getSema().BuildCXXTypeConstructExpr(
3675 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3676 }
3677
3678 /// Build a new object-construction expression.
3679 ///
3680 /// By default, performs semantic analysis to build the new expression.
3681 /// Subclasses may override this routine to provide different behavior.
3682 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3683 SourceLocation LParenLoc,
3684 MultiExprArg Args,
3685 SourceLocation RParenLoc,
3686 bool ListInitialization) {
3687 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3688 RParenLoc, ListInitialization);
3689 }
3690
3691 /// Build a new member reference expression.
3692 ///
3693 /// By default, performs semantic analysis to build the new expression.
3694 /// Subclasses may override this routine to provide different behavior.
3695 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3696 QualType BaseType,
3697 bool IsArrow,
3698 SourceLocation OperatorLoc,
3699 NestedNameSpecifierLoc QualifierLoc,
3700 SourceLocation TemplateKWLoc,
3701 NamedDecl *FirstQualifierInScope,
3702 const DeclarationNameInfo &MemberNameInfo,
3703 const TemplateArgumentListInfo *TemplateArgs) {
3704 CXXScopeSpec SS;
3705 SS.Adopt(Other: QualifierLoc);
3706
3707 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3708 OpLoc: OperatorLoc, IsArrow,
3709 SS, TemplateKWLoc,
3710 FirstQualifierInScope,
3711 NameInfo: MemberNameInfo,
3712 TemplateArgs, /*S*/S: nullptr);
3713 }
3714
3715 /// Build a new member reference expression.
3716 ///
3717 /// By default, performs semantic analysis to build the new expression.
3718 /// Subclasses may override this routine to provide different behavior.
3719 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3720 SourceLocation OperatorLoc,
3721 bool IsArrow,
3722 NestedNameSpecifierLoc QualifierLoc,
3723 SourceLocation TemplateKWLoc,
3724 NamedDecl *FirstQualifierInScope,
3725 LookupResult &R,
3726 const TemplateArgumentListInfo *TemplateArgs) {
3727 CXXScopeSpec SS;
3728 SS.Adopt(Other: QualifierLoc);
3729
3730 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3731 OpLoc: OperatorLoc, IsArrow,
3732 SS, TemplateKWLoc,
3733 FirstQualifierInScope,
3734 R, TemplateArgs, /*S*/S: nullptr);
3735 }
3736
3737 /// Build a new noexcept expression.
3738 ///
3739 /// By default, performs semantic analysis to build the new expression.
3740 /// Subclasses may override this routine to provide different behavior.
3741 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3742 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3743 }
3744
3745 UnsignedOrNone
3746 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3747
3748 /// Build a new expression to compute the length of a parameter pack.
3749 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3750 SourceLocation PackLoc,
3751 SourceLocation RParenLoc,
3752 UnsignedOrNone Length,
3753 ArrayRef<TemplateArgument> PartialArgs) {
3754 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3755 RParenLoc, Length, PartialArgs);
3756 }
3757
3758 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3759 SourceLocation RSquareLoc,
3760 Expr *PackIdExpression, Expr *IndexExpr,
3761 ArrayRef<Expr *> ExpandedExprs,
3762 bool FullySubstituted = false) {
3763 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3764 IndexExpr, RSquareLoc, ExpandedExprs,
3765 FullySubstituted);
3766 }
3767
3768 /// Build a new expression representing a call to a source location
3769 /// builtin.
3770 ///
3771 /// By default, performs semantic analysis to build the new expression.
3772 /// Subclasses may override this routine to provide different behavior.
3773 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3774 SourceLocation BuiltinLoc,
3775 SourceLocation RPLoc,
3776 DeclContext *ParentContext) {
3777 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3778 ParentContext);
3779 }
3780
3781 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3782 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3783 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3784 TemplateArgumentListInfo *TALI) {
3785 CXXScopeSpec SS;
3786 SS.Adopt(Other: NNS);
3787 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3788 ConceptNameInfo,
3789 FoundDecl,
3790 NamedConcept, TALI);
3791 if (Result.isInvalid())
3792 return ExprError();
3793 return Result;
3794 }
3795
3796 /// \brief Build a new requires expression.
3797 ///
3798 /// By default, performs semantic analysis to build the new expression.
3799 /// Subclasses may override this routine to provide different behavior.
3800 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3801 RequiresExprBodyDecl *Body,
3802 SourceLocation LParenLoc,
3803 ArrayRef<ParmVarDecl *> LocalParameters,
3804 SourceLocation RParenLoc,
3805 ArrayRef<concepts::Requirement *> Requirements,
3806 SourceLocation ClosingBraceLoc) {
3807 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3808 LocalParameters, RParenLoc, Requirements,
3809 RBraceLoc: ClosingBraceLoc);
3810 }
3811
3812 concepts::TypeRequirement *
3813 RebuildTypeRequirement(
3814 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3815 return SemaRef.BuildTypeRequirement(SubstDiag);
3816 }
3817
3818 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3819 return SemaRef.BuildTypeRequirement(Type: T);
3820 }
3821
3822 concepts::ExprRequirement *
3823 RebuildExprRequirement(
3824 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3825 SourceLocation NoexceptLoc,
3826 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3827 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3828 ReturnTypeRequirement: std::move(Ret));
3829 }
3830
3831 concepts::ExprRequirement *
3832 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3833 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3834 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3835 ReturnTypeRequirement: std::move(Ret));
3836 }
3837
3838 concepts::NestedRequirement *
3839 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3840 const ASTConstraintSatisfaction &Satisfaction) {
3841 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3842 Satisfaction);
3843 }
3844
3845 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3846 return SemaRef.BuildNestedRequirement(E: Constraint);
3847 }
3848
3849 /// \brief Build a new Objective-C boxed expression.
3850 ///
3851 /// By default, performs semantic analysis to build the new expression.
3852 /// Subclasses may override this routine to provide different behavior.
3853 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3854 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3855 }
3856
3857 /// Build a new Objective-C array literal.
3858 ///
3859 /// By default, performs semantic analysis to build the new expression.
3860 /// Subclasses may override this routine to provide different behavior.
3861 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3862 Expr **Elements, unsigned NumElements) {
3863 return getSema().ObjC().BuildObjCArrayLiteral(
3864 Range, MultiExprArg(Elements, NumElements));
3865 }
3866
3867 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3868 Expr *Base, Expr *Key,
3869 ObjCMethodDecl *getterMethod,
3870 ObjCMethodDecl *setterMethod) {
3871 return getSema().ObjC().BuildObjCSubscriptExpression(
3872 RB, Base, Key, getterMethod, setterMethod);
3873 }
3874
3875 /// Build a new Objective-C dictionary literal.
3876 ///
3877 /// By default, performs semantic analysis to build the new expression.
3878 /// Subclasses may override this routine to provide different behavior.
3879 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3880 MutableArrayRef<ObjCDictionaryElement> Elements) {
3881 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3882 }
3883
3884 /// Build a new Objective-C \@encode expression.
3885 ///
3886 /// By default, performs semantic analysis to build the new expression.
3887 /// Subclasses may override this routine to provide different behavior.
3888 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3889 TypeSourceInfo *EncodeTypeInfo,
3890 SourceLocation RParenLoc) {
3891 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3892 RParenLoc);
3893 }
3894
3895 /// Build a new Objective-C class message.
3896 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3897 Selector Sel,
3898 ArrayRef<SourceLocation> SelectorLocs,
3899 ObjCMethodDecl *Method,
3900 SourceLocation LBracLoc,
3901 MultiExprArg Args,
3902 SourceLocation RBracLoc) {
3903 return SemaRef.ObjC().BuildClassMessage(
3904 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3905 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3906 RBracLoc, Args);
3907 }
3908
3909 /// Build a new Objective-C instance message.
3910 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3911 Selector Sel,
3912 ArrayRef<SourceLocation> SelectorLocs,
3913 ObjCMethodDecl *Method,
3914 SourceLocation LBracLoc,
3915 MultiExprArg Args,
3916 SourceLocation RBracLoc) {
3917 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3918 /*SuperLoc=*/SuperLoc: SourceLocation(),
3919 Sel, Method, LBracLoc,
3920 SelectorLocs, RBracLoc, Args);
3921 }
3922
3923 /// Build a new Objective-C instance/class message to 'super'.
3924 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3925 Selector Sel,
3926 ArrayRef<SourceLocation> SelectorLocs,
3927 QualType SuperType,
3928 ObjCMethodDecl *Method,
3929 SourceLocation LBracLoc,
3930 MultiExprArg Args,
3931 SourceLocation RBracLoc) {
3932 return Method->isInstanceMethod()
3933 ? SemaRef.ObjC().BuildInstanceMessage(
3934 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3935 SelectorLocs, RBracLoc, Args)
3936 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3937 Sel, Method, LBracLoc,
3938 SelectorLocs, RBracLoc, Args);
3939 }
3940
3941 /// Build a new Objective-C ivar reference expression.
3942 ///
3943 /// By default, performs semantic analysis to build the new expression.
3944 /// Subclasses may override this routine to provide different behavior.
3945 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3946 SourceLocation IvarLoc,
3947 bool IsArrow, bool IsFreeIvar) {
3948 CXXScopeSpec SS;
3949 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3950 ExprResult Result = getSema().BuildMemberReferenceExpr(
3951 BaseArg, BaseArg->getType(),
3952 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3953 /*FirstQualifierInScope=*/nullptr, NameInfo,
3954 /*TemplateArgs=*/nullptr,
3955 /*S=*/nullptr);
3956 if (IsFreeIvar && Result.isUsable())
3957 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3958 return Result;
3959 }
3960
3961 /// Build a new Objective-C property reference expression.
3962 ///
3963 /// By default, performs semantic analysis to build the new expression.
3964 /// Subclasses may override this routine to provide different behavior.
3965 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3966 ObjCPropertyDecl *Property,
3967 SourceLocation PropertyLoc) {
3968 CXXScopeSpec SS;
3969 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3970 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3971 /*FIXME:*/PropertyLoc,
3972 /*IsArrow=*/false,
3973 SS, SourceLocation(),
3974 /*FirstQualifierInScope=*/nullptr,
3975 NameInfo,
3976 /*TemplateArgs=*/nullptr,
3977 /*S=*/nullptr);
3978 }
3979
3980 /// Build a new Objective-C property reference expression.
3981 ///
3982 /// By default, performs semantic analysis to build the new expression.
3983 /// Subclasses may override this routine to provide different behavior.
3984 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3985 ObjCMethodDecl *Getter,
3986 ObjCMethodDecl *Setter,
3987 SourceLocation PropertyLoc) {
3988 // Since these expressions can only be value-dependent, we do not
3989 // need to perform semantic analysis again.
3990 return Owned(
3991 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3992 VK_LValue, OK_ObjCProperty,
3993 PropertyLoc, Base));
3994 }
3995
3996 /// Build a new Objective-C "isa" expression.
3997 ///
3998 /// By default, performs semantic analysis to build the new expression.
3999 /// Subclasses may override this routine to provide different behavior.
4000 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4001 SourceLocation OpLoc, bool IsArrow) {
4002 CXXScopeSpec SS;
4003 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4004 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4005 OpLoc, IsArrow,
4006 SS, SourceLocation(),
4007 /*FirstQualifierInScope=*/nullptr,
4008 NameInfo,
4009 /*TemplateArgs=*/nullptr,
4010 /*S=*/nullptr);
4011 }
4012
4013 /// Build a new shuffle vector expression.
4014 ///
4015 /// By default, performs semantic analysis to build the new expression.
4016 /// Subclasses may override this routine to provide different behavior.
4017 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4018 MultiExprArg SubExprs,
4019 SourceLocation RParenLoc) {
4020 // Find the declaration for __builtin_shufflevector
4021 const IdentifierInfo &Name
4022 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4023 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4024 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4025 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4026
4027 // Build a reference to the __builtin_shufflevector builtin
4028 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4029 Expr *Callee = new (SemaRef.Context)
4030 DeclRefExpr(SemaRef.Context, Builtin, false,
4031 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4032 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4033 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4034 CK: CK_BuiltinFnToFnPtr).get();
4035
4036 // Build the CallExpr
4037 ExprResult TheCall = CallExpr::Create(
4038 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4039 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4040 FPFeatures: FPOptionsOverride());
4041
4042 // Type-check the __builtin_shufflevector expression.
4043 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4044 }
4045
4046 /// Build a new convert vector expression.
4047 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4048 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4049 SourceLocation RParenLoc) {
4050 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4051 }
4052
4053 /// Build a new template argument pack expansion.
4054 ///
4055 /// By default, performs semantic analysis to build a new pack expansion
4056 /// for a template argument. Subclasses may override this routine to provide
4057 /// different behavior.
4058 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4059 SourceLocation EllipsisLoc,
4060 UnsignedOrNone NumExpansions) {
4061 switch (Pattern.getArgument().getKind()) {
4062 case TemplateArgument::Expression: {
4063 ExprResult Result
4064 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4065 EllipsisLoc, NumExpansions);
4066 if (Result.isInvalid())
4067 return TemplateArgumentLoc();
4068
4069 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4070 /*IsCanonical=*/false),
4071 Result.get());
4072 }
4073
4074 case TemplateArgument::Template:
4075 return TemplateArgumentLoc(
4076 SemaRef.Context,
4077 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4078 NumExpansions),
4079 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4080 Pattern.getTemplateNameLoc(), EllipsisLoc);
4081
4082 case TemplateArgument::Null:
4083 case TemplateArgument::Integral:
4084 case TemplateArgument::Declaration:
4085 case TemplateArgument::StructuralValue:
4086 case TemplateArgument::Pack:
4087 case TemplateArgument::TemplateExpansion:
4088 case TemplateArgument::NullPtr:
4089 llvm_unreachable("Pack expansion pattern has no parameter packs");
4090
4091 case TemplateArgument::Type:
4092 if (TypeSourceInfo *Expansion
4093 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4094 EllipsisLoc,
4095 NumExpansions))
4096 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4097 Expansion);
4098 break;
4099 }
4100
4101 return TemplateArgumentLoc();
4102 }
4103
4104 /// Build a new expression pack expansion.
4105 ///
4106 /// By default, performs semantic analysis to build a new pack expansion
4107 /// for an expression. Subclasses may override this routine to provide
4108 /// different behavior.
4109 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4110 UnsignedOrNone NumExpansions) {
4111 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4112 }
4113
4114 /// Build a new C++1z fold-expression.
4115 ///
4116 /// By default, performs semantic analysis in order to build a new fold
4117 /// expression.
4118 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4119 SourceLocation LParenLoc, Expr *LHS,
4120 BinaryOperatorKind Operator,
4121 SourceLocation EllipsisLoc, Expr *RHS,
4122 SourceLocation RParenLoc,
4123 UnsignedOrNone NumExpansions) {
4124 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4125 EllipsisLoc, RHS, RParenLoc,
4126 NumExpansions);
4127 }
4128
4129 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4130 LambdaScopeInfo *LSI) {
4131 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4132 if (Expr *Init = PVD->getInit())
4133 LSI->ContainsUnexpandedParameterPack |=
4134 Init->containsUnexpandedParameterPack();
4135 else if (PVD->hasUninstantiatedDefaultArg())
4136 LSI->ContainsUnexpandedParameterPack |=
4137 PVD->getUninstantiatedDefaultArg()
4138 ->containsUnexpandedParameterPack();
4139 }
4140 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4141 }
4142
4143 /// Build an empty C++1z fold-expression with the given operator.
4144 ///
4145 /// By default, produces the fallback value for the fold-expression, or
4146 /// produce an error if there is no fallback value.
4147 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4148 BinaryOperatorKind Operator) {
4149 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4150 }
4151
4152 /// Build a new atomic operation expression.
4153 ///
4154 /// By default, performs semantic analysis to build the new expression.
4155 /// Subclasses may override this routine to provide different behavior.
4156 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4157 AtomicExpr::AtomicOp Op,
4158 SourceLocation RParenLoc) {
4159 // Use this for all of the locations, since we don't know the difference
4160 // between the call and the expr at this point.
4161 SourceRange Range{BuiltinLoc, RParenLoc};
4162 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4163 Sema::AtomicArgumentOrder::AST);
4164 }
4165
4166 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4167 ArrayRef<Expr *> SubExprs, QualType Type) {
4168 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4169 }
4170
4171 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4172 SourceLocation BeginLoc,
4173 SourceLocation DirLoc,
4174 SourceLocation EndLoc,
4175 ArrayRef<OpenACCClause *> Clauses,
4176 StmtResult StrBlock) {
4177 return getSema().OpenACC().ActOnEndStmtDirective(
4178 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4179 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4180 }
4181
4182 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4183 SourceLocation DirLoc,
4184 SourceLocation EndLoc,
4185 ArrayRef<OpenACCClause *> Clauses,
4186 StmtResult Loop) {
4187 return getSema().OpenACC().ActOnEndStmtDirective(
4188 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4189 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4190 Clauses, Loop);
4191 }
4192
4193 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4194 SourceLocation BeginLoc,
4195 SourceLocation DirLoc,
4196 SourceLocation EndLoc,
4197 ArrayRef<OpenACCClause *> Clauses,
4198 StmtResult Loop) {
4199 return getSema().OpenACC().ActOnEndStmtDirective(
4200 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4201 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4202 }
4203
4204 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4205 SourceLocation DirLoc,
4206 SourceLocation EndLoc,
4207 ArrayRef<OpenACCClause *> Clauses,
4208 StmtResult StrBlock) {
4209 return getSema().OpenACC().ActOnEndStmtDirective(
4210 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4211 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4212 Clauses, StrBlock);
4213 }
4214
4215 StmtResult
4216 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4217 SourceLocation DirLoc, SourceLocation EndLoc,
4218 ArrayRef<OpenACCClause *> Clauses) {
4219 return getSema().OpenACC().ActOnEndStmtDirective(
4220 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4221 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4222 Clauses, {});
4223 }
4224
4225 StmtResult
4226 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4227 SourceLocation DirLoc, SourceLocation EndLoc,
4228 ArrayRef<OpenACCClause *> Clauses) {
4229 return getSema().OpenACC().ActOnEndStmtDirective(
4230 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4231 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4232 Clauses, {});
4233 }
4234
4235 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4236 SourceLocation DirLoc,
4237 SourceLocation EndLoc,
4238 ArrayRef<OpenACCClause *> Clauses,
4239 StmtResult StrBlock) {
4240 return getSema().OpenACC().ActOnEndStmtDirective(
4241 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4242 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4243 Clauses, StrBlock);
4244 }
4245
4246 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4247 SourceLocation DirLoc,
4248 SourceLocation EndLoc,
4249 ArrayRef<OpenACCClause *> Clauses) {
4250 return getSema().OpenACC().ActOnEndStmtDirective(
4251 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4252 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4253 Clauses, {});
4254 }
4255
4256 StmtResult
4257 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4258 SourceLocation DirLoc, SourceLocation EndLoc,
4259 ArrayRef<OpenACCClause *> Clauses) {
4260 return getSema().OpenACC().ActOnEndStmtDirective(
4261 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4262 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4263 Clauses, {});
4264 }
4265
4266 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4267 SourceLocation DirLoc,
4268 SourceLocation EndLoc,
4269 ArrayRef<OpenACCClause *> Clauses) {
4270 return getSema().OpenACC().ActOnEndStmtDirective(
4271 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4272 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4273 Clauses, {});
4274 }
4275
4276 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4277 SourceLocation DirLoc,
4278 SourceLocation EndLoc,
4279 ArrayRef<OpenACCClause *> Clauses) {
4280 return getSema().OpenACC().ActOnEndStmtDirective(
4281 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4282 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4283 Clauses, {});
4284 }
4285
4286 StmtResult RebuildOpenACCWaitConstruct(
4287 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4288 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4289 SourceLocation RParenLoc, SourceLocation EndLoc,
4290 ArrayRef<OpenACCClause *> Clauses) {
4291 llvm::SmallVector<Expr *> Exprs;
4292 Exprs.push_back(Elt: DevNumExpr);
4293 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4294 return getSema().OpenACC().ActOnEndStmtDirective(
4295 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4296 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4297 }
4298
4299 StmtResult RebuildOpenACCCacheConstruct(
4300 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4301 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4302 SourceLocation RParenLoc, SourceLocation EndLoc) {
4303 return getSema().OpenACC().ActOnEndStmtDirective(
4304 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4305 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4306 }
4307
4308 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4309 SourceLocation DirLoc,
4310 OpenACCAtomicKind AtKind,
4311 SourceLocation EndLoc,
4312 ArrayRef<OpenACCClause *> Clauses,
4313 StmtResult AssociatedStmt) {
4314 return getSema().OpenACC().ActOnEndStmtDirective(
4315 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4316 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4317 AssociatedStmt);
4318 }
4319
4320 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4321 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4322 }
4323
4324 ExprResult
4325 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl,
4326 const NonTypeTemplateParmDecl *NTTP,
4327 SourceLocation Loc, TemplateArgument Arg,
4328 UnsignedOrNone PackIndex, bool Final) {
4329 return getSema().BuildSubstNonTypeTemplateParmExpr(
4330 AssociatedDecl, NTTP, Loc, Arg, PackIndex, Final);
4331 }
4332
4333 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4334 SourceLocation StartLoc,
4335 SourceLocation LParenLoc,
4336 SourceLocation EndLoc) {
4337 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4338 LParenLoc, EndLoc);
4339 }
4340
4341private:
4342 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4343 QualType ObjectType,
4344 NamedDecl *FirstQualifierInScope);
4345
4346 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4347 QualType ObjectType,
4348 NamedDecl *FirstQualifierInScope) {
4349 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4350 return TSInfo;
4351
4352 TypeLocBuilder TLB;
4353 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4354 ObjectType, FirstQualifierInScope);
4355 if (T.isNull())
4356 return nullptr;
4357 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4358 }
4359
4360 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4361 DependentNameTypeLoc TL,
4362 bool DeducibleTSTContext,
4363 QualType ObjectType = QualType(),
4364 NamedDecl *UnqualLookup = nullptr);
4365
4366 llvm::SmallVector<OpenACCClause *>
4367 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4368 ArrayRef<const OpenACCClause *> OldClauses);
4369
4370 OpenACCClause *
4371 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4372 OpenACCDirectiveKind DirKind,
4373 const OpenACCClause *OldClause);
4374};
4375
4376template <typename Derived>
4377StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4378 if (!S)
4379 return S;
4380
4381 switch (S->getStmtClass()) {
4382 case Stmt::NoStmtClass: break;
4383
4384 // Transform individual statement nodes
4385 // Pass SDK into statements that can produce a value
4386#define STMT(Node, Parent) \
4387 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4388#define VALUESTMT(Node, Parent) \
4389 case Stmt::Node##Class: \
4390 return getDerived().Transform##Node(cast<Node>(S), SDK);
4391#define ABSTRACT_STMT(Node)
4392#define EXPR(Node, Parent)
4393#include "clang/AST/StmtNodes.inc"
4394
4395 // Transform expressions by calling TransformExpr.
4396#define STMT(Node, Parent)
4397#define ABSTRACT_STMT(Stmt)
4398#define EXPR(Node, Parent) case Stmt::Node##Class:
4399#include "clang/AST/StmtNodes.inc"
4400 {
4401 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4402
4403 if (SDK == StmtDiscardKind::StmtExprResult)
4404 E = getSema().ActOnStmtExprResult(E);
4405 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4406 }
4407 }
4408
4409 return S;
4410}
4411
4412template<typename Derived>
4413OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4414 if (!S)
4415 return S;
4416
4417 switch (S->getClauseKind()) {
4418 default: break;
4419 // Transform individual clause nodes
4420#define GEN_CLANG_CLAUSE_CLASS
4421#define CLAUSE_CLASS(Enum, Str, Class) \
4422 case Enum: \
4423 return getDerived().Transform##Class(cast<Class>(S));
4424#include "llvm/Frontend/OpenMP/OMP.inc"
4425 }
4426
4427 return S;
4428}
4429
4430
4431template<typename Derived>
4432ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4433 if (!E)
4434 return E;
4435
4436 switch (E->getStmtClass()) {
4437 case Stmt::NoStmtClass: break;
4438#define STMT(Node, Parent) case Stmt::Node##Class: break;
4439#define ABSTRACT_STMT(Stmt)
4440#define EXPR(Node, Parent) \
4441 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4442#include "clang/AST/StmtNodes.inc"
4443 }
4444
4445 return E;
4446}
4447
4448template<typename Derived>
4449ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4450 bool NotCopyInit) {
4451 // Initializers are instantiated like expressions, except that various outer
4452 // layers are stripped.
4453 if (!Init)
4454 return Init;
4455
4456 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4457 Init = FE->getSubExpr();
4458
4459 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4460 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4461 Init = OVE->getSourceExpr();
4462 }
4463
4464 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4465 Init = MTE->getSubExpr();
4466
4467 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4468 Init = Binder->getSubExpr();
4469
4470 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4471 Init = ICE->getSubExprAsWritten();
4472
4473 if (CXXStdInitializerListExpr *ILE =
4474 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4475 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4476
4477 // If this is copy-initialization, we only need to reconstruct
4478 // InitListExprs. Other forms of copy-initialization will be a no-op if
4479 // the initializer is already the right type.
4480 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4481 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4482 return getDerived().TransformExpr(Init);
4483
4484 // Revert value-initialization back to empty parens.
4485 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4486 SourceRange Parens = VIE->getSourceRange();
4487 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4488 Parens.getEnd());
4489 }
4490
4491 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4492 if (isa<ImplicitValueInitExpr>(Val: Init))
4493 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4494 SourceLocation());
4495
4496 // Revert initialization by constructor back to a parenthesized or braced list
4497 // of expressions. Any other form of initializer can just be reused directly.
4498 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4499 return getDerived().TransformExpr(Init);
4500
4501 // If the initialization implicitly converted an initializer list to a
4502 // std::initializer_list object, unwrap the std::initializer_list too.
4503 if (Construct && Construct->isStdInitListInitialization())
4504 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4505
4506 // Enter a list-init context if this was list initialization.
4507 EnterExpressionEvaluationContext Context(
4508 getSema(), EnterExpressionEvaluationContext::InitList,
4509 Construct->isListInitialization());
4510
4511 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4512 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4513 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4514 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4515 SmallVector<Expr*, 8> NewArgs;
4516 bool ArgChanged = false;
4517 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4518 /*IsCall*/true, NewArgs, &ArgChanged))
4519 return ExprError();
4520
4521 // If this was list initialization, revert to syntactic list form.
4522 if (Construct->isListInitialization())
4523 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4524 Construct->getEndLoc());
4525
4526 // Build a ParenListExpr to represent anything else.
4527 SourceRange Parens = Construct->getParenOrBraceRange();
4528 if (Parens.isInvalid()) {
4529 // This was a variable declaration's initialization for which no initializer
4530 // was specified.
4531 assert(NewArgs.empty() &&
4532 "no parens or braces but have direct init with arguments?");
4533 return ExprEmpty();
4534 }
4535 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4536 Parens.getEnd());
4537}
4538
4539template<typename Derived>
4540bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4541 unsigned NumInputs,
4542 bool IsCall,
4543 SmallVectorImpl<Expr *> &Outputs,
4544 bool *ArgChanged) {
4545 for (unsigned I = 0; I != NumInputs; ++I) {
4546 // If requested, drop call arguments that need to be dropped.
4547 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4548 if (ArgChanged)
4549 *ArgChanged = true;
4550
4551 break;
4552 }
4553
4554 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4555 Expr *Pattern = Expansion->getPattern();
4556
4557 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4558 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4559 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4560
4561 // Determine whether the set of unexpanded parameter packs can and should
4562 // be expanded.
4563 bool Expand = true;
4564 bool RetainExpansion = false;
4565 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4566 UnsignedOrNone NumExpansions = OrigNumExpansions;
4567 if (getDerived().TryExpandParameterPacks(
4568 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4569 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4570 RetainExpansion, NumExpansions))
4571 return true;
4572
4573 if (!Expand) {
4574 // The transform has determined that we should perform a simple
4575 // transformation on the pack expansion, producing another pack
4576 // expansion.
4577 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4578 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4579 if (OutPattern.isInvalid())
4580 return true;
4581
4582 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4583 Expansion->getEllipsisLoc(),
4584 NumExpansions);
4585 if (Out.isInvalid())
4586 return true;
4587
4588 if (ArgChanged)
4589 *ArgChanged = true;
4590 Outputs.push_back(Elt: Out.get());
4591 continue;
4592 }
4593
4594 // Record right away that the argument was changed. This needs
4595 // to happen even if the array expands to nothing.
4596 if (ArgChanged) *ArgChanged = true;
4597
4598 // The transform has determined that we should perform an elementwise
4599 // expansion of the pattern. Do so.
4600 for (unsigned I = 0; I != *NumExpansions; ++I) {
4601 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4602 ExprResult Out = getDerived().TransformExpr(Pattern);
4603 if (Out.isInvalid())
4604 return true;
4605
4606 if (Out.get()->containsUnexpandedParameterPack()) {
4607 Out = getDerived().RebuildPackExpansion(
4608 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4609 if (Out.isInvalid())
4610 return true;
4611 }
4612
4613 Outputs.push_back(Elt: Out.get());
4614 }
4615
4616 // If we're supposed to retain a pack expansion, do so by temporarily
4617 // forgetting the partially-substituted parameter pack.
4618 if (RetainExpansion) {
4619 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4620
4621 ExprResult Out = getDerived().TransformExpr(Pattern);
4622 if (Out.isInvalid())
4623 return true;
4624
4625 Out = getDerived().RebuildPackExpansion(
4626 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4627 if (Out.isInvalid())
4628 return true;
4629
4630 Outputs.push_back(Elt: Out.get());
4631 }
4632
4633 continue;
4634 }
4635
4636 ExprResult Result =
4637 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4638 : getDerived().TransformExpr(Inputs[I]);
4639 if (Result.isInvalid())
4640 return true;
4641
4642 if (Result.get() != Inputs[I] && ArgChanged)
4643 *ArgChanged = true;
4644
4645 Outputs.push_back(Elt: Result.get());
4646 }
4647
4648 return false;
4649}
4650
4651template <typename Derived>
4652Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4653 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4654
4655 EnterExpressionEvaluationContext Eval(
4656 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4657 /*LambdaContextDecl=*/nullptr,
4658 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4659 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4660
4661 if (Var) {
4662 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4663 getDerived().TransformDefinition(Var->getLocation(), Var));
4664
4665 if (!ConditionVar)
4666 return Sema::ConditionError();
4667
4668 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4669 }
4670
4671 if (Expr) {
4672 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4673
4674 if (CondExpr.isInvalid())
4675 return Sema::ConditionError();
4676
4677 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4678 /*MissingOK=*/true);
4679 }
4680
4681 return Sema::ConditionResult();
4682}
4683
4684template <typename Derived>
4685NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4686 NestedNameSpecifierLoc NNS, QualType ObjectType,
4687 NamedDecl *FirstQualifierInScope) {
4688 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4689
4690 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4691 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4692 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4693 Qualifiers.push_back(Elt: Qualifier);
4694 };
4695 insertNNS(NNS);
4696
4697 CXXScopeSpec SS;
4698 while (!Qualifiers.empty()) {
4699 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4700 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4701
4702 switch (QNNS.getKind()) {
4703 case NestedNameSpecifier::Kind::Null:
4704 llvm_unreachable("unexpected null nested name specifier");
4705
4706 case NestedNameSpecifier::Kind::Namespace: {
4707 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4708 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4709 QNNS.getAsNamespaceAndPrefix().Namespace)));
4710 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4711 break;
4712 }
4713
4714 case NestedNameSpecifier::Kind::Global:
4715 // There is no meaningful transformation that one could perform on the
4716 // global scope.
4717 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4718 break;
4719
4720 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4721 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4722 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4723 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4724 ColonColonLoc: Q.getEndLoc());
4725 break;
4726 }
4727
4728 case NestedNameSpecifier::Kind::Type: {
4729 assert(SS.isEmpty());
4730 TypeLoc TL = Q.castAsTypeLoc();
4731
4732 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4733 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4734 if (QualifierLoc) {
4735 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4736 QualifierLoc, ObjectType, FirstQualifierInScope);
4737 if (!QualifierLoc)
4738 return NestedNameSpecifierLoc();
4739 ObjectType = QualType();
4740 FirstQualifierInScope = nullptr;
4741 }
4742 SS.Adopt(Other: QualifierLoc);
4743 Sema::NestedNameSpecInfo IdInfo(
4744 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4745 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4746 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4747 EnteringContext: false, SS,
4748 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4749 return NestedNameSpecifierLoc();
4750 return SS.getWithLocInContext(Context&: SemaRef.Context);
4751 }
4752
4753 QualType T = TL.getType();
4754 TypeLocBuilder TLB;
4755 if (!getDerived().AlreadyTransformed(T)) {
4756 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4757 FirstQualifierInScope);
4758 if (T.isNull())
4759 return NestedNameSpecifierLoc();
4760 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4761 }
4762
4763 if (T->isDependentType() || T->isRecordType() ||
4764 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4765 if (T->isEnumeralType())
4766 SemaRef.Diag(Loc: TL.getBeginLoc(),
4767 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4768 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4769 break;
4770 }
4771 // If the nested-name-specifier is an invalid type def, don't emit an
4772 // error because a previous error should have already been emitted.
4773 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4774 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4775 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4776 << T << SS.getRange();
4777 }
4778 return NestedNameSpecifierLoc();
4779 }
4780 }
4781 }
4782
4783 // Don't rebuild the nested-name-specifier if we don't have to.
4784 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4785 !getDerived().AlwaysRebuild())
4786 return NNS;
4787
4788 // If we can re-use the source-location data from the original
4789 // nested-name-specifier, do so.
4790 if (SS.location_size() == NNS.getDataLength() &&
4791 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4792 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4793
4794 // Allocate new nested-name-specifier location information.
4795 return SS.getWithLocInContext(Context&: SemaRef.Context);
4796}
4797
4798template<typename Derived>
4799DeclarationNameInfo
4800TreeTransform<Derived>
4801::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4802 DeclarationName Name = NameInfo.getName();
4803 if (!Name)
4804 return DeclarationNameInfo();
4805
4806 switch (Name.getNameKind()) {
4807 case DeclarationName::Identifier:
4808 case DeclarationName::ObjCZeroArgSelector:
4809 case DeclarationName::ObjCOneArgSelector:
4810 case DeclarationName::ObjCMultiArgSelector:
4811 case DeclarationName::CXXOperatorName:
4812 case DeclarationName::CXXLiteralOperatorName:
4813 case DeclarationName::CXXUsingDirective:
4814 return NameInfo;
4815
4816 case DeclarationName::CXXDeductionGuideName: {
4817 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4818 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4819 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4820 if (!NewTemplate)
4821 return DeclarationNameInfo();
4822
4823 DeclarationNameInfo NewNameInfo(NameInfo);
4824 NewNameInfo.setName(
4825 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4826 return NewNameInfo;
4827 }
4828
4829 case DeclarationName::CXXConstructorName:
4830 case DeclarationName::CXXDestructorName:
4831 case DeclarationName::CXXConversionFunctionName: {
4832 TypeSourceInfo *NewTInfo;
4833 CanQualType NewCanTy;
4834 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4835 NewTInfo = getDerived().TransformType(OldTInfo);
4836 if (!NewTInfo)
4837 return DeclarationNameInfo();
4838 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4839 }
4840 else {
4841 NewTInfo = nullptr;
4842 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4843 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4844 if (NewT.isNull())
4845 return DeclarationNameInfo();
4846 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4847 }
4848
4849 DeclarationName NewName
4850 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4851 Ty: NewCanTy);
4852 DeclarationNameInfo NewNameInfo(NameInfo);
4853 NewNameInfo.setName(NewName);
4854 NewNameInfo.setNamedTypeInfo(NewTInfo);
4855 return NewNameInfo;
4856 }
4857 }
4858
4859 llvm_unreachable("Unknown name kind.");
4860}
4861
4862template <typename Derived>
4863TemplateName TreeTransform<Derived>::RebuildTemplateName(
4864 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4865 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4866 QualType ObjectType, bool AllowInjectedClassName) {
4867 if (const IdentifierInfo *II = IO.getIdentifier())
4868 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4869 ObjectType, AllowInjectedClassName);
4870 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4871 NameLoc, ObjectType,
4872 AllowInjectedClassName);
4873}
4874
4875template <typename Derived>
4876TemplateName TreeTransform<Derived>::TransformTemplateName(
4877 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4878 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4879 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4880 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4881 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4882
4883 if (QualifierLoc) {
4884 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4885 QualifierLoc, ObjectType, FirstQualifierInScope);
4886 if (!QualifierLoc)
4887 return TemplateName();
4888 }
4889
4890 NestedNameSpecifierLoc UnderlyingQualifier;
4891 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4892 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4893 FirstQualifierInScope, AllowInjectedClassName);
4894 if (NewUnderlyingName.isNull())
4895 return TemplateName();
4896 assert(!UnderlyingQualifier && "unexpected qualifier");
4897
4898 if (!getDerived().AlwaysRebuild() &&
4899 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4900 NewUnderlyingName == UnderlyingName)
4901 return Name;
4902 CXXScopeSpec SS;
4903 SS.Adopt(Other: QualifierLoc);
4904 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4905 NewUnderlyingName);
4906 }
4907
4908 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4909 if (QualifierLoc) {
4910 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4911 QualifierLoc, ObjectType, FirstQualifierInScope);
4912 if (!QualifierLoc)
4913 return TemplateName();
4914 // The qualifier-in-scope and object type only apply to the leftmost
4915 // entity.
4916 ObjectType = QualType();
4917 }
4918
4919 if (!getDerived().AlwaysRebuild() &&
4920 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4921 ObjectType.isNull())
4922 return Name;
4923
4924 CXXScopeSpec SS;
4925 SS.Adopt(Other: QualifierLoc);
4926 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4927 NameLoc, ObjectType,
4928 AllowInjectedClassName);
4929 }
4930
4931 if (SubstTemplateTemplateParmStorage *S =
4932 Name.getAsSubstTemplateTemplateParm()) {
4933 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4934
4935 NestedNameSpecifierLoc ReplacementQualifierLoc;
4936 TemplateName ReplacementName = S->getReplacement();
4937 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4938 NestedNameSpecifierLocBuilder Builder;
4939 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4940 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4941 }
4942
4943 TemplateName NewName = getDerived().TransformTemplateName(
4944 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4945 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4946 if (NewName.isNull())
4947 return TemplateName();
4948 Decl *AssociatedDecl =
4949 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4950 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4951 AssociatedDecl == S->getAssociatedDecl())
4952 return Name;
4953 return SemaRef.Context.getSubstTemplateTemplateParm(
4954 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4955 Final: S->getFinal());
4956 }
4957
4958 assert(!Name.getAsDeducedTemplateName() &&
4959 "DeducedTemplateName should not escape partial ordering");
4960
4961 // FIXME: Preserve UsingTemplateName.
4962 if (auto *Template = Name.getAsTemplateDecl()) {
4963 assert(!QualifierLoc && "Unexpected qualifier");
4964 return TemplateName(cast_or_null<TemplateDecl>(
4965 getDerived().TransformDecl(NameLoc, Template)));
4966 }
4967
4968 if (SubstTemplateTemplateParmPackStorage *SubstPack
4969 = Name.getAsSubstTemplateTemplateParmPack()) {
4970 assert(!QualifierLoc &&
4971 "Unexpected qualified SubstTemplateTemplateParmPack");
4972 return getDerived().RebuildTemplateName(
4973 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4974 SubstPack->getIndex(), SubstPack->getFinal());
4975 }
4976
4977 // These should be getting filtered out before they reach the AST.
4978 llvm_unreachable("overloaded function decl survived to here");
4979}
4980
4981template <typename Derived>
4982TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
4983 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
4984 TemplateName Name, SourceLocation NameLoc) {
4985 TemplateName TN = getDerived().TransformTemplateName(
4986 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
4987 if (TN.isNull())
4988 return TemplateArgument();
4989 return TemplateArgument(TN);
4990}
4991
4992template<typename Derived>
4993void TreeTransform<Derived>::InventTemplateArgumentLoc(
4994 const TemplateArgument &Arg,
4995 TemplateArgumentLoc &Output) {
4996 Output = getSema().getTrivialTemplateArgumentLoc(
4997 Arg, QualType(), getDerived().getBaseLocation());
4998}
4999
5000template <typename Derived>
5001bool TreeTransform<Derived>::TransformTemplateArgument(
5002 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5003 bool Uneval) {
5004 const TemplateArgument &Arg = Input.getArgument();
5005 switch (Arg.getKind()) {
5006 case TemplateArgument::Null:
5007 case TemplateArgument::Pack:
5008 llvm_unreachable("Unexpected TemplateArgument");
5009
5010 case TemplateArgument::Integral:
5011 case TemplateArgument::NullPtr:
5012 case TemplateArgument::Declaration:
5013 case TemplateArgument::StructuralValue: {
5014 // Transform a resolved template argument straight to a resolved template
5015 // argument. We get here when substituting into an already-substituted
5016 // template type argument during concept satisfaction checking.
5017 QualType T = Arg.getNonTypeTemplateArgumentType();
5018 QualType NewT = getDerived().TransformType(T);
5019 if (NewT.isNull())
5020 return true;
5021
5022 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5023 ? Arg.getAsDecl()
5024 : nullptr;
5025 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5026 getDerived().getBaseLocation(), D))
5027 : nullptr;
5028 if (D && !NewD)
5029 return true;
5030
5031 if (NewT == T && D == NewD)
5032 Output = Input;
5033 else if (Arg.getKind() == TemplateArgument::Integral)
5034 Output = TemplateArgumentLoc(
5035 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5036 TemplateArgumentLocInfo());
5037 else if (Arg.getKind() == TemplateArgument::NullPtr)
5038 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5039 TemplateArgumentLocInfo());
5040 else if (Arg.getKind() == TemplateArgument::Declaration)
5041 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5042 TemplateArgumentLocInfo());
5043 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5044 Output = TemplateArgumentLoc(
5045 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5046 TemplateArgumentLocInfo());
5047 else
5048 llvm_unreachable("unexpected template argument kind");
5049
5050 return false;
5051 }
5052
5053 case TemplateArgument::Type: {
5054 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5055 if (!TSI)
5056 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5057
5058 TSI = getDerived().TransformType(TSI);
5059 if (!TSI)
5060 return true;
5061
5062 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5063 return false;
5064 }
5065
5066 case TemplateArgument::Template: {
5067 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5068
5069 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5070 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5071 Input.getTemplateNameLoc());
5072 if (Out.isNull())
5073 return true;
5074 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5075 QualifierLoc, Input.getTemplateNameLoc());
5076 return false;
5077 }
5078
5079 case TemplateArgument::TemplateExpansion:
5080 llvm_unreachable("Caller should expand pack expansions");
5081
5082 case TemplateArgument::Expression: {
5083 // Template argument expressions are constant expressions.
5084 EnterExpressionEvaluationContext Unevaluated(
5085 getSema(),
5086 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5087 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5088 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5089 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5090
5091 Expr *InputExpr = Input.getSourceExpression();
5092 if (!InputExpr)
5093 InputExpr = Input.getArgument().getAsExpr();
5094
5095 ExprResult E = getDerived().TransformExpr(InputExpr);
5096 E = SemaRef.ActOnConstantExpression(Res: E);
5097 if (E.isInvalid())
5098 return true;
5099 Output = TemplateArgumentLoc(
5100 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5101 return false;
5102 }
5103 }
5104
5105 // Work around bogus GCC warning
5106 return true;
5107}
5108
5109/// Iterator adaptor that invents template argument location information
5110/// for each of the template arguments in its underlying iterator.
5111template<typename Derived, typename InputIterator>
5112class TemplateArgumentLocInventIterator {
5113 TreeTransform<Derived> &Self;
5114 InputIterator Iter;
5115
5116public:
5117 typedef TemplateArgumentLoc value_type;
5118 typedef TemplateArgumentLoc reference;
5119 typedef typename std::iterator_traits<InputIterator>::difference_type
5120 difference_type;
5121 typedef std::input_iterator_tag iterator_category;
5122
5123 class pointer {
5124 TemplateArgumentLoc Arg;
5125
5126 public:
5127 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5128
5129 const TemplateArgumentLoc *operator->() const { return &Arg; }
5130 };
5131
5132 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5133 InputIterator Iter)
5134 : Self(Self), Iter(Iter) { }
5135
5136 TemplateArgumentLocInventIterator &operator++() {
5137 ++Iter;
5138 return *this;
5139 }
5140
5141 TemplateArgumentLocInventIterator operator++(int) {
5142 TemplateArgumentLocInventIterator Old(*this);
5143 ++(*this);
5144 return Old;
5145 }
5146
5147 reference operator*() const {
5148 TemplateArgumentLoc Result;
5149 Self.InventTemplateArgumentLoc(*Iter, Result);
5150 return Result;
5151 }
5152
5153 pointer operator->() const { return pointer(**this); }
5154
5155 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5156 const TemplateArgumentLocInventIterator &Y) {
5157 return X.Iter == Y.Iter;
5158 }
5159
5160 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5161 const TemplateArgumentLocInventIterator &Y) {
5162 return X.Iter != Y.Iter;
5163 }
5164};
5165
5166template<typename Derived>
5167template<typename InputIterator>
5168bool TreeTransform<Derived>::TransformTemplateArguments(
5169 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5170 bool Uneval) {
5171 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5172 TemplateArgumentLoc Out;
5173 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5174 // Unpack argument packs, which we translate them into separate
5175 // arguments.
5176 // FIXME: We could do much better if we could guarantee that the
5177 // TemplateArgumentLocInfo for the pack expansion would be usable for
5178 // all of the template arguments in the argument pack.
5179 typedef TemplateArgumentLocInventIterator<Derived,
5180 TemplateArgument::pack_iterator>
5181 PackLocIterator;
5182
5183 TemplateArgumentListInfo *PackOutput = &Outputs;
5184 TemplateArgumentListInfo New;
5185
5186 if (TransformTemplateArguments(
5187 PackLocIterator(*this, In.getArgument().pack_begin()),
5188 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5189 Uneval))
5190 return true;
5191
5192 continue;
5193 }
5194
5195 if (In.getArgument().isPackExpansion()) {
5196 UnexpandedInfo Info;
5197 TemplateArgumentLoc Prepared;
5198 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5199 return true;
5200 if (!Info.Expand) {
5201 Outputs.addArgument(Loc: Prepared);
5202 continue;
5203 }
5204
5205 // The transform has determined that we should perform an elementwise
5206 // expansion of the pattern. Do so.
5207 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5208 if (Info.ExpandUnderForgetSubstitions)
5209 ForgetSubst.emplace(getDerived());
5210 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5211 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5212
5213 TemplateArgumentLoc Out;
5214 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5215 return true;
5216
5217 if (Out.getArgument().containsUnexpandedParameterPack()) {
5218 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5219 Info.OrigNumExpansions);
5220 if (Out.getArgument().isNull())
5221 return true;
5222 }
5223
5224 Outputs.addArgument(Loc: Out);
5225 }
5226
5227 // If we're supposed to retain a pack expansion, do so by temporarily
5228 // forgetting the partially-substituted parameter pack.
5229 if (Info.RetainExpansion) {
5230 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5231
5232 TemplateArgumentLoc Out;
5233 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5234 return true;
5235
5236 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5237 Info.OrigNumExpansions);
5238 if (Out.getArgument().isNull())
5239 return true;
5240
5241 Outputs.addArgument(Loc: Out);
5242 }
5243
5244 continue;
5245 }
5246
5247 // The simple case:
5248 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5249 return true;
5250
5251 Outputs.addArgument(Loc: Out);
5252 }
5253
5254 return false;
5255}
5256
5257template <typename Derived>
5258template <typename InputIterator>
5259bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5260 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5261 bool Uneval) {
5262
5263 // [C++26][temp.constr.normal]
5264 // any non-dependent concept template argument
5265 // is substituted into the constraint-expression of C.
5266 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5267 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5268 };
5269
5270 for (; First != Last; ++First) {
5271 TemplateArgumentLoc Out;
5272 TemplateArgumentLoc In = *First;
5273
5274 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5275 typedef TemplateArgumentLocInventIterator<Derived,
5276 TemplateArgument::pack_iterator>
5277 PackLocIterator;
5278 if (TransformConceptTemplateArguments(
5279 PackLocIterator(*this, In.getArgument().pack_begin()),
5280 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5281 Uneval))
5282 return true;
5283 continue;
5284 }
5285
5286 if (!isNonDependentConceptArgument(In.getArgument())) {
5287 Outputs.addArgument(Loc: In);
5288 continue;
5289 }
5290
5291 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5292 return true;
5293
5294 Outputs.addArgument(Loc: Out);
5295 }
5296
5297 return false;
5298}
5299
5300// FIXME: Find ways to reduce code duplication for pack expansions.
5301template <typename Derived>
5302bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5303 bool Uneval,
5304 TemplateArgumentLoc &Out,
5305 UnexpandedInfo &Info) {
5306 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5307 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5308 TemplateArgumentLoc &Pattern) {
5309 assert(Arg.getArgument().isPackExpansion());
5310 // We have a pack expansion, for which we will be substituting into the
5311 // pattern.
5312 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5313 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5314 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5315 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5316 if (IsLateExpansionAttempt) {
5317 // Request expansion only when there is an opportunity to expand a pack
5318 // that required a substituion first.
5319 bool SawPackTypes =
5320 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5321 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5322 });
5323 if (!SawPackTypes) {
5324 Info.Expand = false;
5325 return false;
5326 }
5327 }
5328 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5329
5330 // Determine whether the set of unexpanded parameter packs can and
5331 // should be expanded.
5332 Info.Expand = true;
5333 Info.RetainExpansion = false;
5334 Info.NumExpansions = Info.OrigNumExpansions;
5335 return getDerived().TryExpandParameterPacks(
5336 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5337 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5338 Info.RetainExpansion, Info.NumExpansions);
5339 };
5340
5341 TemplateArgumentLoc Pattern;
5342 if (ComputeInfo(In, false, Info, Pattern))
5343 return true;
5344
5345 if (Info.Expand) {
5346 Out = Pattern;
5347 return false;
5348 }
5349
5350 // The transform has determined that we should perform a simple
5351 // transformation on the pack expansion, producing another pack
5352 // expansion.
5353 TemplateArgumentLoc OutPattern;
5354 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5355 std::in_place, getSema(), std::nullopt);
5356 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5357 return true;
5358
5359 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5360 Info.NumExpansions);
5361 if (Out.getArgument().isNull())
5362 return true;
5363 SubstIndex.reset();
5364
5365 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5366 return false;
5367
5368 // Some packs will learn their length after substitution, e.g.
5369 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5370 // value of `T`.
5371 //
5372 // We only expand after we know sizes of all packs, check if this is the case
5373 // or not. However, we avoid a full template substitution and only do
5374 // expanstions after this point.
5375
5376 // E.g. when substituting template arguments of tuple with {T -> int} in the
5377 // following example:
5378 // template <class T>
5379 // struct TupleWithInt {
5380 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5381 // };
5382 // TupleWithInt<int>::type y;
5383 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5384 // length and run `ComputeInfo()` to provide the necessary information to our
5385 // caller.
5386 //
5387 // Note that we may still have situations where builtin is not going to be
5388 // expanded. For example:
5389 // template <class T>
5390 // struct Foo {
5391 // template <class U> using tuple_with_t =
5392 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5393 // tuple_with_t<short>;
5394 // }
5395 // Because the substitution into `type` happens in dependent context, `type`
5396 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5397 // and the caller will not be able to expand it.
5398 ForgetSubstitutionRAII ForgetSubst(getDerived());
5399 if (ComputeInfo(Out, true, Info, OutPattern))
5400 return true;
5401 if (!Info.Expand)
5402 return false;
5403 Out = OutPattern;
5404 Info.ExpandUnderForgetSubstitions = true;
5405 return false;
5406}
5407
5408//===----------------------------------------------------------------------===//
5409// Type transformation
5410//===----------------------------------------------------------------------===//
5411
5412template<typename Derived>
5413QualType TreeTransform<Derived>::TransformType(QualType T) {
5414 if (getDerived().AlreadyTransformed(T))
5415 return T;
5416
5417 // Temporary workaround. All of these transformations should
5418 // eventually turn into transformations on TypeLocs.
5419 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5420 T, getDerived().getBaseLocation());
5421
5422 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5423
5424 if (!NewTSI)
5425 return QualType();
5426
5427 return NewTSI->getType();
5428}
5429
5430template <typename Derived>
5431TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5432 // Refine the base location to the type's location.
5433 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5434 getDerived().getBaseEntity());
5435 if (getDerived().AlreadyTransformed(TSI->getType()))
5436 return TSI;
5437
5438 TypeLocBuilder TLB;
5439
5440 TypeLoc TL = TSI->getTypeLoc();
5441 TLB.reserve(Requested: TL.getFullDataSize());
5442
5443 QualType Result = getDerived().TransformType(TLB, TL);
5444 if (Result.isNull())
5445 return nullptr;
5446
5447 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5448}
5449
5450template<typename Derived>
5451QualType
5452TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5453 switch (T.getTypeLocClass()) {
5454#define ABSTRACT_TYPELOC(CLASS, PARENT)
5455#define TYPELOC(CLASS, PARENT) \
5456 case TypeLoc::CLASS: \
5457 return getDerived().Transform##CLASS##Type(TLB, \
5458 T.castAs<CLASS##TypeLoc>());
5459#include "clang/AST/TypeLocNodes.def"
5460 }
5461
5462 llvm_unreachable("unhandled type loc!");
5463}
5464
5465template<typename Derived>
5466QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5467 if (!isa<DependentNameType>(Val: T))
5468 return TransformType(T);
5469
5470 if (getDerived().AlreadyTransformed(T))
5471 return T;
5472 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5473 T, getDerived().getBaseLocation());
5474 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5475 return NewTSI ? NewTSI->getType() : QualType();
5476}
5477
5478template <typename Derived>
5479TypeSourceInfo *
5480TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5481 if (!isa<DependentNameType>(Val: TSI->getType()))
5482 return TransformType(TSI);
5483
5484 // Refine the base location to the type's location.
5485 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5486 getDerived().getBaseEntity());
5487 if (getDerived().AlreadyTransformed(TSI->getType()))
5488 return TSI;
5489
5490 TypeLocBuilder TLB;
5491
5492 TypeLoc TL = TSI->getTypeLoc();
5493 TLB.reserve(Requested: TL.getFullDataSize());
5494
5495 auto QTL = TL.getAs<QualifiedTypeLoc>();
5496 if (QTL)
5497 TL = QTL.getUnqualifiedLoc();
5498
5499 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5500
5501 QualType Result = getDerived().TransformDependentNameType(
5502 TLB, DNTL, /*DeducedTSTContext*/true);
5503 if (Result.isNull())
5504 return nullptr;
5505
5506 if (QTL) {
5507 Result = getDerived().RebuildQualifiedType(Result, QTL);
5508 if (Result.isNull())
5509 return nullptr;
5510 TLB.TypeWasModifiedSafely(T: Result);
5511 }
5512
5513 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5514}
5515
5516template<typename Derived>
5517QualType
5518TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5519 QualifiedTypeLoc T) {
5520 QualType Result;
5521 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5522 auto SuppressObjCLifetime =
5523 T.getType().getLocalQualifiers().hasObjCLifetime();
5524 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5525 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5526 SuppressObjCLifetime);
5527 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5528 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5529 TLB, STTP, SuppressObjCLifetime);
5530 } else {
5531 Result = getDerived().TransformType(TLB, UnqualTL);
5532 }
5533
5534 if (Result.isNull())
5535 return QualType();
5536
5537 Result = getDerived().RebuildQualifiedType(Result, T);
5538
5539 if (Result.isNull())
5540 return QualType();
5541
5542 // RebuildQualifiedType might have updated the type, but not in a way
5543 // that invalidates the TypeLoc. (There's no location information for
5544 // qualifiers.)
5545 TLB.TypeWasModifiedSafely(T: Result);
5546
5547 return Result;
5548}
5549
5550template <typename Derived>
5551QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5552 QualifiedTypeLoc TL) {
5553
5554 SourceLocation Loc = TL.getBeginLoc();
5555 Qualifiers Quals = TL.getType().getLocalQualifiers();
5556
5557 if ((T.getAddressSpace() != LangAS::Default &&
5558 Quals.getAddressSpace() != LangAS::Default) &&
5559 T.getAddressSpace() != Quals.getAddressSpace()) {
5560 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5561 << TL.getType() << T;
5562 return QualType();
5563 }
5564
5565 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5566 if (LocalPointerAuth.isPresent()) {
5567 if (T.getPointerAuth().isPresent()) {
5568 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5569 return QualType();
5570 }
5571 if (!T->isDependentType()) {
5572 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5573 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5574 return QualType();
5575 }
5576 }
5577 }
5578 // C++ [dcl.fct]p7:
5579 // [When] adding cv-qualifications on top of the function type [...] the
5580 // cv-qualifiers are ignored.
5581 if (T->isFunctionType()) {
5582 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5583 AddressSpace: Quals.getAddressSpace());
5584 return T;
5585 }
5586
5587 // C++ [dcl.ref]p1:
5588 // when the cv-qualifiers are introduced through the use of a typedef-name
5589 // or decltype-specifier [...] the cv-qualifiers are ignored.
5590 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5591 // applied to a reference type.
5592 if (T->isReferenceType()) {
5593 // The only qualifier that applies to a reference type is restrict.
5594 if (!Quals.hasRestrict())
5595 return T;
5596 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5597 }
5598
5599 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5600 // resulting type.
5601 if (Quals.hasObjCLifetime()) {
5602 if (!T->isObjCLifetimeType() && !T->isDependentType())
5603 Quals.removeObjCLifetime();
5604 else if (T.getObjCLifetime()) {
5605 // Objective-C ARC:
5606 // A lifetime qualifier applied to a substituted template parameter
5607 // overrides the lifetime qualifier from the template argument.
5608 const AutoType *AutoTy;
5609 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5610 // 'auto' types behave the same way as template parameters.
5611 QualType Deduced = AutoTy->getDeducedType();
5612 Qualifiers Qs = Deduced.getQualifiers();
5613 Qs.removeObjCLifetime();
5614 Deduced =
5615 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5616 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5617 Keyword: AutoTy->getKeyword(),
5618 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5619 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5620 } else {
5621 // Otherwise, complain about the addition of a qualifier to an
5622 // already-qualified type.
5623 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5624 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5625 Quals.removeObjCLifetime();
5626 }
5627 }
5628 }
5629
5630 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5631}
5632
5633template <typename Derived>
5634QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5635 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5636 NamedDecl *FirstQualifierInScope) {
5637 assert(!getDerived().AlreadyTransformed(TL.getType()));
5638
5639 switch (TL.getTypeLocClass()) {
5640 case TypeLoc::TemplateSpecialization:
5641 return getDerived().TransformTemplateSpecializationType(
5642 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5643 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5644 case TypeLoc::DependentName:
5645 return getDerived().TransformDependentNameType(
5646 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5647 ObjectType, FirstQualifierInScope);
5648 default:
5649 // Any dependent canonical type can appear here, through type alias
5650 // templates.
5651 return getDerived().TransformType(TLB, TL);
5652 }
5653}
5654
5655template <class TyLoc> static inline
5656QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5657 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5658 NewT.setNameLoc(T.getNameLoc());
5659 return T.getType();
5660}
5661
5662template<typename Derived>
5663QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5664 BuiltinTypeLoc T) {
5665 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5666 NewT.setBuiltinLoc(T.getBuiltinLoc());
5667 if (T.needsExtraLocalData())
5668 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5669 return T.getType();
5670}
5671
5672template<typename Derived>
5673QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5674 ComplexTypeLoc T) {
5675 // FIXME: recurse?
5676 return TransformTypeSpecType(TLB, T);
5677}
5678
5679template <typename Derived>
5680QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5681 AdjustedTypeLoc TL) {
5682 // Adjustments applied during transformation are handled elsewhere.
5683 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5684}
5685
5686template<typename Derived>
5687QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5688 DecayedTypeLoc TL) {
5689 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5690 if (OriginalType.isNull())
5691 return QualType();
5692
5693 QualType Result = TL.getType();
5694 if (getDerived().AlwaysRebuild() ||
5695 OriginalType != TL.getOriginalLoc().getType())
5696 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5697 TLB.push<DecayedTypeLoc>(T: Result);
5698 // Nothing to set for DecayedTypeLoc.
5699 return Result;
5700}
5701
5702template <typename Derived>
5703QualType
5704TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5705 ArrayParameterTypeLoc TL) {
5706 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5707 if (OriginalType.isNull())
5708 return QualType();
5709
5710 QualType Result = TL.getType();
5711 if (getDerived().AlwaysRebuild() ||
5712 OriginalType != TL.getElementLoc().getType())
5713 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5714 TLB.push<ArrayParameterTypeLoc>(T: Result);
5715 // Nothing to set for ArrayParameterTypeLoc.
5716 return Result;
5717}
5718
5719template<typename Derived>
5720QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5721 PointerTypeLoc TL) {
5722 QualType PointeeType
5723 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5724 if (PointeeType.isNull())
5725 return QualType();
5726
5727 QualType Result = TL.getType();
5728 if (PointeeType->getAs<ObjCObjectType>()) {
5729 // A dependent pointer type 'T *' has is being transformed such
5730 // that an Objective-C class type is being replaced for 'T'. The
5731 // resulting pointer type is an ObjCObjectPointerType, not a
5732 // PointerType.
5733 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5734
5735 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5736 NewT.setStarLoc(TL.getStarLoc());
5737 return Result;
5738 }
5739
5740 if (getDerived().AlwaysRebuild() ||
5741 PointeeType != TL.getPointeeLoc().getType()) {
5742 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5743 if (Result.isNull())
5744 return QualType();
5745 }
5746
5747 // Objective-C ARC can add lifetime qualifiers to the type that we're
5748 // pointing to.
5749 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5750
5751 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5752 NewT.setSigilLoc(TL.getSigilLoc());
5753 return Result;
5754}
5755
5756template<typename Derived>
5757QualType
5758TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5759 BlockPointerTypeLoc TL) {
5760 QualType PointeeType
5761 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5762 if (PointeeType.isNull())
5763 return QualType();
5764
5765 QualType Result = TL.getType();
5766 if (getDerived().AlwaysRebuild() ||
5767 PointeeType != TL.getPointeeLoc().getType()) {
5768 Result = getDerived().RebuildBlockPointerType(PointeeType,
5769 TL.getSigilLoc());
5770 if (Result.isNull())
5771 return QualType();
5772 }
5773
5774 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5775 NewT.setSigilLoc(TL.getSigilLoc());
5776 return Result;
5777}
5778
5779/// Transforms a reference type. Note that somewhat paradoxically we
5780/// don't care whether the type itself is an l-value type or an r-value
5781/// type; we only care if the type was *written* as an l-value type
5782/// or an r-value type.
5783template<typename Derived>
5784QualType
5785TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5786 ReferenceTypeLoc TL) {
5787 const ReferenceType *T = TL.getTypePtr();
5788
5789 // Note that this works with the pointee-as-written.
5790 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5791 if (PointeeType.isNull())
5792 return QualType();
5793
5794 QualType Result = TL.getType();
5795 if (getDerived().AlwaysRebuild() ||
5796 PointeeType != T->getPointeeTypeAsWritten()) {
5797 Result = getDerived().RebuildReferenceType(PointeeType,
5798 T->isSpelledAsLValue(),
5799 TL.getSigilLoc());
5800 if (Result.isNull())
5801 return QualType();
5802 }
5803
5804 // Objective-C ARC can add lifetime qualifiers to the type that we're
5805 // referring to.
5806 TLB.TypeWasModifiedSafely(
5807 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5808
5809 // r-value references can be rebuilt as l-value references.
5810 ReferenceTypeLoc NewTL;
5811 if (isa<LValueReferenceType>(Val: Result))
5812 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5813 else
5814 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5815 NewTL.setSigilLoc(TL.getSigilLoc());
5816
5817 return Result;
5818}
5819
5820template<typename Derived>
5821QualType
5822TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5823 LValueReferenceTypeLoc TL) {
5824 return TransformReferenceType(TLB, TL);
5825}
5826
5827template<typename Derived>
5828QualType
5829TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5830 RValueReferenceTypeLoc TL) {
5831 return TransformReferenceType(TLB, TL);
5832}
5833
5834template<typename Derived>
5835QualType
5836TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5837 MemberPointerTypeLoc TL) {
5838 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5839 if (PointeeType.isNull())
5840 return QualType();
5841
5842 const MemberPointerType *T = TL.getTypePtr();
5843
5844 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5845 NestedNameSpecifierLoc NewQualifierLoc =
5846 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5847 if (!NewQualifierLoc)
5848 return QualType();
5849
5850 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5851 if (OldCls) {
5852 NewCls = cast_or_null<CXXRecordDecl>(
5853 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5854 if (!NewCls)
5855 return QualType();
5856 }
5857
5858 QualType Result = TL.getType();
5859 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5860 NewQualifierLoc.getNestedNameSpecifier() !=
5861 OldQualifierLoc.getNestedNameSpecifier() ||
5862 NewCls != OldCls) {
5863 CXXScopeSpec SS;
5864 SS.Adopt(Other: NewQualifierLoc);
5865 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5866 TL.getStarLoc());
5867 if (Result.isNull())
5868 return QualType();
5869 }
5870
5871 // If we had to adjust the pointee type when building a member pointer, make
5872 // sure to push TypeLoc info for it.
5873 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5874 if (MPT && PointeeType != MPT->getPointeeType()) {
5875 assert(isa<AdjustedType>(MPT->getPointeeType()));
5876 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5877 }
5878
5879 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5880 NewTL.setSigilLoc(TL.getSigilLoc());
5881 NewTL.setQualifierLoc(NewQualifierLoc);
5882
5883 return Result;
5884}
5885
5886template<typename Derived>
5887QualType
5888TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5889 ConstantArrayTypeLoc TL) {
5890 const ConstantArrayType *T = TL.getTypePtr();
5891 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5892 if (ElementType.isNull())
5893 return QualType();
5894
5895 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5896 Expr *OldSize = TL.getSizeExpr();
5897 if (!OldSize)
5898 OldSize = const_cast<Expr*>(T->getSizeExpr());
5899 Expr *NewSize = nullptr;
5900 if (OldSize) {
5901 EnterExpressionEvaluationContext Unevaluated(
5902 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5903 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5904 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5905 }
5906
5907 QualType Result = TL.getType();
5908 if (getDerived().AlwaysRebuild() ||
5909 ElementType != T->getElementType() ||
5910 (T->getSizeExpr() && NewSize != OldSize)) {
5911 Result = getDerived().RebuildConstantArrayType(ElementType,
5912 T->getSizeModifier(),
5913 T->getSize(), NewSize,
5914 T->getIndexTypeCVRQualifiers(),
5915 TL.getBracketsRange());
5916 if (Result.isNull())
5917 return QualType();
5918 }
5919
5920 // We might have either a ConstantArrayType or a VariableArrayType now:
5921 // a ConstantArrayType is allowed to have an element type which is a
5922 // VariableArrayType if the type is dependent. Fortunately, all array
5923 // types have the same location layout.
5924 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5925 NewTL.setLBracketLoc(TL.getLBracketLoc());
5926 NewTL.setRBracketLoc(TL.getRBracketLoc());
5927 NewTL.setSizeExpr(NewSize);
5928
5929 return Result;
5930}
5931
5932template<typename Derived>
5933QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5934 TypeLocBuilder &TLB,
5935 IncompleteArrayTypeLoc TL) {
5936 const IncompleteArrayType *T = TL.getTypePtr();
5937 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5938 if (ElementType.isNull())
5939 return QualType();
5940
5941 QualType Result = TL.getType();
5942 if (getDerived().AlwaysRebuild() ||
5943 ElementType != T->getElementType()) {
5944 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5945 T->getSizeModifier(),
5946 T->getIndexTypeCVRQualifiers(),
5947 TL.getBracketsRange());
5948 if (Result.isNull())
5949 return QualType();
5950 }
5951
5952 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5953 NewTL.setLBracketLoc(TL.getLBracketLoc());
5954 NewTL.setRBracketLoc(TL.getRBracketLoc());
5955 NewTL.setSizeExpr(nullptr);
5956
5957 return Result;
5958}
5959
5960template<typename Derived>
5961QualType
5962TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5963 VariableArrayTypeLoc TL) {
5964 const VariableArrayType *T = TL.getTypePtr();
5965 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5966 if (ElementType.isNull())
5967 return QualType();
5968
5969 ExprResult SizeResult;
5970 {
5971 EnterExpressionEvaluationContext Context(
5972 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5973 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5974 }
5975 if (SizeResult.isInvalid())
5976 return QualType();
5977 SizeResult =
5978 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5979 if (SizeResult.isInvalid())
5980 return QualType();
5981
5982 Expr *Size = SizeResult.get();
5983
5984 QualType Result = TL.getType();
5985 if (getDerived().AlwaysRebuild() ||
5986 ElementType != T->getElementType() ||
5987 Size != T->getSizeExpr()) {
5988 Result = getDerived().RebuildVariableArrayType(ElementType,
5989 T->getSizeModifier(),
5990 Size,
5991 T->getIndexTypeCVRQualifiers(),
5992 TL.getBracketsRange());
5993 if (Result.isNull())
5994 return QualType();
5995 }
5996
5997 // We might have constant size array now, but fortunately it has the same
5998 // location layout.
5999 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6000 NewTL.setLBracketLoc(TL.getLBracketLoc());
6001 NewTL.setRBracketLoc(TL.getRBracketLoc());
6002 NewTL.setSizeExpr(Size);
6003
6004 return Result;
6005}
6006
6007template<typename Derived>
6008QualType
6009TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6010 DependentSizedArrayTypeLoc TL) {
6011 const DependentSizedArrayType *T = TL.getTypePtr();
6012 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6013 if (ElementType.isNull())
6014 return QualType();
6015
6016 // Array bounds are constant expressions.
6017 EnterExpressionEvaluationContext Unevaluated(
6018 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6019
6020 // If we have a VLA then it won't be a constant.
6021 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6022
6023 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6024 Expr *origSize = TL.getSizeExpr();
6025 if (!origSize) origSize = T->getSizeExpr();
6026
6027 ExprResult sizeResult
6028 = getDerived().TransformExpr(origSize);
6029 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6030 if (sizeResult.isInvalid())
6031 return QualType();
6032
6033 Expr *size = sizeResult.get();
6034
6035 QualType Result = TL.getType();
6036 if (getDerived().AlwaysRebuild() ||
6037 ElementType != T->getElementType() ||
6038 size != origSize) {
6039 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6040 T->getSizeModifier(),
6041 size,
6042 T->getIndexTypeCVRQualifiers(),
6043 TL.getBracketsRange());
6044 if (Result.isNull())
6045 return QualType();
6046 }
6047
6048 // We might have any sort of array type now, but fortunately they
6049 // all have the same location layout.
6050 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6051 NewTL.setLBracketLoc(TL.getLBracketLoc());
6052 NewTL.setRBracketLoc(TL.getRBracketLoc());
6053 NewTL.setSizeExpr(size);
6054
6055 return Result;
6056}
6057
6058template <typename Derived>
6059QualType TreeTransform<Derived>::TransformDependentVectorType(
6060 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6061 const DependentVectorType *T = TL.getTypePtr();
6062 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6063 if (ElementType.isNull())
6064 return QualType();
6065
6066 EnterExpressionEvaluationContext Unevaluated(
6067 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6068
6069 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6070 Size = SemaRef.ActOnConstantExpression(Res: Size);
6071 if (Size.isInvalid())
6072 return QualType();
6073
6074 QualType Result = TL.getType();
6075 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6076 Size.get() != T->getSizeExpr()) {
6077 Result = getDerived().RebuildDependentVectorType(
6078 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6079 if (Result.isNull())
6080 return QualType();
6081 }
6082
6083 // Result might be dependent or not.
6084 if (isa<DependentVectorType>(Val: Result)) {
6085 DependentVectorTypeLoc NewTL =
6086 TLB.push<DependentVectorTypeLoc>(T: Result);
6087 NewTL.setNameLoc(TL.getNameLoc());
6088 } else {
6089 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6090 NewTL.setNameLoc(TL.getNameLoc());
6091 }
6092
6093 return Result;
6094}
6095
6096template<typename Derived>
6097QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6098 TypeLocBuilder &TLB,
6099 DependentSizedExtVectorTypeLoc TL) {
6100 const DependentSizedExtVectorType *T = TL.getTypePtr();
6101
6102 // FIXME: ext vector locs should be nested
6103 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6104 if (ElementType.isNull())
6105 return QualType();
6106
6107 // Vector sizes are constant expressions.
6108 EnterExpressionEvaluationContext Unevaluated(
6109 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6110
6111 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6112 Size = SemaRef.ActOnConstantExpression(Res: Size);
6113 if (Size.isInvalid())
6114 return QualType();
6115
6116 QualType Result = TL.getType();
6117 if (getDerived().AlwaysRebuild() ||
6118 ElementType != T->getElementType() ||
6119 Size.get() != T->getSizeExpr()) {
6120 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6121 Size.get(),
6122 T->getAttributeLoc());
6123 if (Result.isNull())
6124 return QualType();
6125 }
6126
6127 // Result might be dependent or not.
6128 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6129 DependentSizedExtVectorTypeLoc NewTL
6130 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6131 NewTL.setNameLoc(TL.getNameLoc());
6132 } else {
6133 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6134 NewTL.setNameLoc(TL.getNameLoc());
6135 }
6136
6137 return Result;
6138}
6139
6140template <typename Derived>
6141QualType
6142TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6143 ConstantMatrixTypeLoc TL) {
6144 const ConstantMatrixType *T = TL.getTypePtr();
6145 QualType ElementType = getDerived().TransformType(T->getElementType());
6146 if (ElementType.isNull())
6147 return QualType();
6148
6149 QualType Result = TL.getType();
6150 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6151 Result = getDerived().RebuildConstantMatrixType(
6152 ElementType, T->getNumRows(), T->getNumColumns());
6153 if (Result.isNull())
6154 return QualType();
6155 }
6156
6157 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6158 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6159 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6160 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6161 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6162
6163 return Result;
6164}
6165
6166template <typename Derived>
6167QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6168 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6169 const DependentSizedMatrixType *T = TL.getTypePtr();
6170
6171 QualType ElementType = getDerived().TransformType(T->getElementType());
6172 if (ElementType.isNull()) {
6173 return QualType();
6174 }
6175
6176 // Matrix dimensions are constant expressions.
6177 EnterExpressionEvaluationContext Unevaluated(
6178 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6179
6180 Expr *origRows = TL.getAttrRowOperand();
6181 if (!origRows)
6182 origRows = T->getRowExpr();
6183 Expr *origColumns = TL.getAttrColumnOperand();
6184 if (!origColumns)
6185 origColumns = T->getColumnExpr();
6186
6187 ExprResult rowResult = getDerived().TransformExpr(origRows);
6188 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6189 if (rowResult.isInvalid())
6190 return QualType();
6191
6192 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6193 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6194 if (columnResult.isInvalid())
6195 return QualType();
6196
6197 Expr *rows = rowResult.get();
6198 Expr *columns = columnResult.get();
6199
6200 QualType Result = TL.getType();
6201 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6202 rows != origRows || columns != origColumns) {
6203 Result = getDerived().RebuildDependentSizedMatrixType(
6204 ElementType, rows, columns, T->getAttributeLoc());
6205
6206 if (Result.isNull())
6207 return QualType();
6208 }
6209
6210 // We might have any sort of matrix type now, but fortunately they
6211 // all have the same location layout.
6212 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6213 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6214 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6215 NewTL.setAttrRowOperand(rows);
6216 NewTL.setAttrColumnOperand(columns);
6217 return Result;
6218}
6219
6220template <typename Derived>
6221QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6222 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6223 const DependentAddressSpaceType *T = TL.getTypePtr();
6224
6225 QualType pointeeType =
6226 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6227
6228 if (pointeeType.isNull())
6229 return QualType();
6230
6231 // Address spaces are constant expressions.
6232 EnterExpressionEvaluationContext Unevaluated(
6233 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6234
6235 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6236 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6237 if (AddrSpace.isInvalid())
6238 return QualType();
6239
6240 QualType Result = TL.getType();
6241 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6242 AddrSpace.get() != T->getAddrSpaceExpr()) {
6243 Result = getDerived().RebuildDependentAddressSpaceType(
6244 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6245 if (Result.isNull())
6246 return QualType();
6247 }
6248
6249 // Result might be dependent or not.
6250 if (isa<DependentAddressSpaceType>(Val: Result)) {
6251 DependentAddressSpaceTypeLoc NewTL =
6252 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6253
6254 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6255 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6256 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6257
6258 } else {
6259 TLB.TypeWasModifiedSafely(T: Result);
6260 }
6261
6262 return Result;
6263}
6264
6265template <typename Derived>
6266QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6267 VectorTypeLoc TL) {
6268 const VectorType *T = TL.getTypePtr();
6269 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6270 if (ElementType.isNull())
6271 return QualType();
6272
6273 QualType Result = TL.getType();
6274 if (getDerived().AlwaysRebuild() ||
6275 ElementType != T->getElementType()) {
6276 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6277 T->getVectorKind());
6278 if (Result.isNull())
6279 return QualType();
6280 }
6281
6282 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6283 NewTL.setNameLoc(TL.getNameLoc());
6284
6285 return Result;
6286}
6287
6288template<typename Derived>
6289QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6290 ExtVectorTypeLoc TL) {
6291 const VectorType *T = TL.getTypePtr();
6292 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6293 if (ElementType.isNull())
6294 return QualType();
6295
6296 QualType Result = TL.getType();
6297 if (getDerived().AlwaysRebuild() ||
6298 ElementType != T->getElementType()) {
6299 Result = getDerived().RebuildExtVectorType(ElementType,
6300 T->getNumElements(),
6301 /*FIXME*/ SourceLocation());
6302 if (Result.isNull())
6303 return QualType();
6304 }
6305
6306 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6307 NewTL.setNameLoc(TL.getNameLoc());
6308
6309 return Result;
6310}
6311
6312template <typename Derived>
6313ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6314 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6315 bool ExpectParameterPack) {
6316 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6317 TypeSourceInfo *NewTSI = nullptr;
6318
6319 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6320 // If we're substituting into a pack expansion type and we know the
6321 // length we want to expand to, just substitute for the pattern.
6322 TypeLoc OldTL = OldTSI->getTypeLoc();
6323 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6324
6325 TypeLocBuilder TLB;
6326 TypeLoc NewTL = OldTSI->getTypeLoc();
6327 TLB.reserve(Requested: NewTL.getFullDataSize());
6328
6329 QualType Result = getDerived().TransformType(TLB,
6330 OldExpansionTL.getPatternLoc());
6331 if (Result.isNull())
6332 return nullptr;
6333
6334 Result = RebuildPackExpansionType(Pattern: Result,
6335 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6336 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6337 NumExpansions);
6338 if (Result.isNull())
6339 return nullptr;
6340
6341 PackExpansionTypeLoc NewExpansionTL
6342 = TLB.push<PackExpansionTypeLoc>(T: Result);
6343 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6344 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6345 } else
6346 NewTSI = getDerived().TransformType(OldTSI);
6347 if (!NewTSI)
6348 return nullptr;
6349
6350 if (NewTSI == OldTSI && indexAdjustment == 0)
6351 return OldParm;
6352
6353 ParmVarDecl *newParm = ParmVarDecl::Create(
6354 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6355 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6356 TInfo: NewTSI, S: OldParm->getStorageClass(),
6357 /* DefArg */ DefArg: nullptr);
6358 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6359 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6360 getDerived().transformedLocalDecl(OldParm, {newParm});
6361 return newParm;
6362}
6363
6364template <typename Derived>
6365bool TreeTransform<Derived>::TransformFunctionTypeParams(
6366 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6367 const QualType *ParamTypes,
6368 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6369 SmallVectorImpl<QualType> &OutParamTypes,
6370 SmallVectorImpl<ParmVarDecl *> *PVars,
6371 Sema::ExtParameterInfoBuilder &PInfos,
6372 unsigned *LastParamTransformed) {
6373 int indexAdjustment = 0;
6374
6375 unsigned NumParams = Params.size();
6376 for (unsigned i = 0; i != NumParams; ++i) {
6377 if (LastParamTransformed)
6378 *LastParamTransformed = i;
6379 if (ParmVarDecl *OldParm = Params[i]) {
6380 assert(OldParm->getFunctionScopeIndex() == i);
6381
6382 UnsignedOrNone NumExpansions = std::nullopt;
6383 ParmVarDecl *NewParm = nullptr;
6384 if (OldParm->isParameterPack()) {
6385 // We have a function parameter pack that may need to be expanded.
6386 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6387
6388 // Find the parameter packs that could be expanded.
6389 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6390 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6391 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6392 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6393
6394 // Determine whether we should expand the parameter packs.
6395 bool ShouldExpand = false;
6396 bool RetainExpansion = false;
6397 UnsignedOrNone OrigNumExpansions = std::nullopt;
6398 if (Unexpanded.size() > 0) {
6399 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6400 NumExpansions = OrigNumExpansions;
6401 if (getDerived().TryExpandParameterPacks(
6402 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6403 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6404 ShouldExpand, RetainExpansion, NumExpansions)) {
6405 return true;
6406 }
6407 } else {
6408#ifndef NDEBUG
6409 const AutoType *AT =
6410 Pattern.getType().getTypePtr()->getContainedAutoType();
6411 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6412 "Could not find parameter packs or undeduced auto type!");
6413#endif
6414 }
6415
6416 if (ShouldExpand) {
6417 // Expand the function parameter pack into multiple, separate
6418 // parameters.
6419 getDerived().ExpandingFunctionParameterPack(OldParm);
6420 for (unsigned I = 0; I != *NumExpansions; ++I) {
6421 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6422 ParmVarDecl *NewParm
6423 = getDerived().TransformFunctionTypeParam(OldParm,
6424 indexAdjustment++,
6425 OrigNumExpansions,
6426 /*ExpectParameterPack=*/false);
6427 if (!NewParm)
6428 return true;
6429
6430 if (ParamInfos)
6431 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6432 OutParamTypes.push_back(Elt: NewParm->getType());
6433 if (PVars)
6434 PVars->push_back(Elt: NewParm);
6435 }
6436
6437 // If we're supposed to retain a pack expansion, do so by temporarily
6438 // forgetting the partially-substituted parameter pack.
6439 if (RetainExpansion) {
6440 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6441 ParmVarDecl *NewParm
6442 = getDerived().TransformFunctionTypeParam(OldParm,
6443 indexAdjustment++,
6444 OrigNumExpansions,
6445 /*ExpectParameterPack=*/false);
6446 if (!NewParm)
6447 return true;
6448
6449 if (ParamInfos)
6450 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6451 OutParamTypes.push_back(Elt: NewParm->getType());
6452 if (PVars)
6453 PVars->push_back(Elt: NewParm);
6454 }
6455
6456 // The next parameter should have the same adjustment as the
6457 // last thing we pushed, but we post-incremented indexAdjustment
6458 // on every push. Also, if we push nothing, the adjustment should
6459 // go down by one.
6460 indexAdjustment--;
6461
6462 // We're done with the pack expansion.
6463 continue;
6464 }
6465
6466 // We'll substitute the parameter now without expanding the pack
6467 // expansion.
6468 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6469 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6470 indexAdjustment,
6471 NumExpansions,
6472 /*ExpectParameterPack=*/true);
6473 assert(NewParm->isParameterPack() &&
6474 "Parameter pack no longer a parameter pack after "
6475 "transformation.");
6476 } else {
6477 NewParm = getDerived().TransformFunctionTypeParam(
6478 OldParm, indexAdjustment, std::nullopt,
6479 /*ExpectParameterPack=*/false);
6480 }
6481
6482 if (!NewParm)
6483 return true;
6484
6485 if (ParamInfos)
6486 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6487 OutParamTypes.push_back(Elt: NewParm->getType());
6488 if (PVars)
6489 PVars->push_back(Elt: NewParm);
6490 continue;
6491 }
6492
6493 // Deal with the possibility that we don't have a parameter
6494 // declaration for this parameter.
6495 assert(ParamTypes);
6496 QualType OldType = ParamTypes[i];
6497 bool IsPackExpansion = false;
6498 UnsignedOrNone NumExpansions = std::nullopt;
6499 QualType NewType;
6500 if (const PackExpansionType *Expansion
6501 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6502 // We have a function parameter pack that may need to be expanded.
6503 QualType Pattern = Expansion->getPattern();
6504 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6505 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6506
6507 // Determine whether we should expand the parameter packs.
6508 bool ShouldExpand = false;
6509 bool RetainExpansion = false;
6510 if (getDerived().TryExpandParameterPacks(
6511 Loc, SourceRange(), Unexpanded,
6512 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6513 RetainExpansion, NumExpansions)) {
6514 return true;
6515 }
6516
6517 if (ShouldExpand) {
6518 // Expand the function parameter pack into multiple, separate
6519 // parameters.
6520 for (unsigned I = 0; I != *NumExpansions; ++I) {
6521 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6522 QualType NewType = getDerived().TransformType(Pattern);
6523 if (NewType.isNull())
6524 return true;
6525
6526 if (NewType->containsUnexpandedParameterPack()) {
6527 NewType = getSema().getASTContext().getPackExpansionType(
6528 NewType, std::nullopt);
6529
6530 if (NewType.isNull())
6531 return true;
6532 }
6533
6534 if (ParamInfos)
6535 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6536 OutParamTypes.push_back(Elt: NewType);
6537 if (PVars)
6538 PVars->push_back(Elt: nullptr);
6539 }
6540
6541 // We're done with the pack expansion.
6542 continue;
6543 }
6544
6545 // If we're supposed to retain a pack expansion, do so by temporarily
6546 // forgetting the partially-substituted parameter pack.
6547 if (RetainExpansion) {
6548 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6549 QualType NewType = getDerived().TransformType(Pattern);
6550 if (NewType.isNull())
6551 return true;
6552
6553 if (ParamInfos)
6554 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6555 OutParamTypes.push_back(Elt: NewType);
6556 if (PVars)
6557 PVars->push_back(Elt: nullptr);
6558 }
6559
6560 // We'll substitute the parameter now without expanding the pack
6561 // expansion.
6562 OldType = Expansion->getPattern();
6563 IsPackExpansion = true;
6564 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6565 NewType = getDerived().TransformType(OldType);
6566 } else {
6567 NewType = getDerived().TransformType(OldType);
6568 }
6569
6570 if (NewType.isNull())
6571 return true;
6572
6573 if (IsPackExpansion)
6574 NewType = getSema().Context.getPackExpansionType(NewType,
6575 NumExpansions);
6576
6577 if (ParamInfos)
6578 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6579 OutParamTypes.push_back(Elt: NewType);
6580 if (PVars)
6581 PVars->push_back(Elt: nullptr);
6582 }
6583
6584#ifndef NDEBUG
6585 if (PVars) {
6586 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6587 if (ParmVarDecl *parm = (*PVars)[i])
6588 assert(parm->getFunctionScopeIndex() == i);
6589 }
6590#endif
6591
6592 return false;
6593}
6594
6595template<typename Derived>
6596QualType
6597TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6598 FunctionProtoTypeLoc TL) {
6599 SmallVector<QualType, 4> ExceptionStorage;
6600 return getDerived().TransformFunctionProtoType(
6601 TLB, TL, nullptr, Qualifiers(),
6602 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6603 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6604 ExceptionStorage, Changed);
6605 });
6606}
6607
6608template<typename Derived> template<typename Fn>
6609QualType TreeTransform<Derived>::TransformFunctionProtoType(
6610 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6611 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6612
6613 // Transform the parameters and return type.
6614 //
6615 // We are required to instantiate the params and return type in source order.
6616 // When the function has a trailing return type, we instantiate the
6617 // parameters before the return type, since the return type can then refer
6618 // to the parameters themselves (via decltype, sizeof, etc.).
6619 //
6620 SmallVector<QualType, 4> ParamTypes;
6621 SmallVector<ParmVarDecl*, 4> ParamDecls;
6622 Sema::ExtParameterInfoBuilder ExtParamInfos;
6623 const FunctionProtoType *T = TL.getTypePtr();
6624
6625 QualType ResultType;
6626
6627 if (T->hasTrailingReturn()) {
6628 if (getDerived().TransformFunctionTypeParams(
6629 TL.getBeginLoc(), TL.getParams(),
6630 TL.getTypePtr()->param_type_begin(),
6631 T->getExtParameterInfosOrNull(),
6632 ParamTypes, &ParamDecls, ExtParamInfos))
6633 return QualType();
6634
6635 {
6636 // C++11 [expr.prim.general]p3:
6637 // If a declaration declares a member function or member function
6638 // template of a class X, the expression this is a prvalue of type
6639 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6640 // and the end of the function-definition, member-declarator, or
6641 // declarator.
6642 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6643 Sema::CXXThisScopeRAII ThisScope(
6644 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6645
6646 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6647 if (ResultType.isNull())
6648 return QualType();
6649 }
6650 }
6651 else {
6652 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6653 if (ResultType.isNull())
6654 return QualType();
6655
6656 if (getDerived().TransformFunctionTypeParams(
6657 TL.getBeginLoc(), TL.getParams(),
6658 TL.getTypePtr()->param_type_begin(),
6659 T->getExtParameterInfosOrNull(),
6660 ParamTypes, &ParamDecls, ExtParamInfos))
6661 return QualType();
6662 }
6663
6664 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6665
6666 bool EPIChanged = false;
6667 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6668 return QualType();
6669
6670 // Handle extended parameter information.
6671 if (auto NewExtParamInfos =
6672 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6673 if (!EPI.ExtParameterInfos ||
6674 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6675 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6676 EPIChanged = true;
6677 }
6678 EPI.ExtParameterInfos = NewExtParamInfos;
6679 } else if (EPI.ExtParameterInfos) {
6680 EPIChanged = true;
6681 EPI.ExtParameterInfos = nullptr;
6682 }
6683
6684 // Transform any function effects with unevaluated conditions.
6685 // Hold this set in a local for the rest of this function, since EPI
6686 // may need to hold a FunctionEffectsRef pointing into it.
6687 std::optional<FunctionEffectSet> NewFX;
6688 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6689 NewFX.emplace();
6690 EnterExpressionEvaluationContext Unevaluated(
6691 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6692
6693 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6694 FunctionEffectWithCondition NewEC = PrevEC;
6695 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6696 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6697 if (NewExpr.isInvalid())
6698 return QualType();
6699 std::optional<FunctionEffectMode> Mode =
6700 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6701 if (!Mode)
6702 return QualType();
6703
6704 // The condition expression has been transformed, and re-evaluated.
6705 // It may or may not have become constant.
6706 switch (*Mode) {
6707 case FunctionEffectMode::True:
6708 NewEC.Cond = {};
6709 break;
6710 case FunctionEffectMode::False:
6711 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6712 NewEC.Cond = {};
6713 break;
6714 case FunctionEffectMode::Dependent:
6715 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6716 break;
6717 case FunctionEffectMode::None:
6718 llvm_unreachable(
6719 "FunctionEffectMode::None shouldn't be possible here");
6720 }
6721 }
6722 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6723 NewAttrLoc: TL.getBeginLoc())) {
6724 FunctionEffectSet::Conflicts Errs;
6725 NewFX->insert(NewEC, Errs);
6726 assert(Errs.empty());
6727 }
6728 }
6729 EPI.FunctionEffects = *NewFX;
6730 EPIChanged = true;
6731 }
6732
6733 QualType Result = TL.getType();
6734 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6735 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6736 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6737 if (Result.isNull())
6738 return QualType();
6739 }
6740
6741 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6742 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6743 NewTL.setLParenLoc(TL.getLParenLoc());
6744 NewTL.setRParenLoc(TL.getRParenLoc());
6745 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6746 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6747 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6748 NewTL.setParam(i, VD: ParamDecls[i]);
6749
6750 return Result;
6751}
6752
6753template<typename Derived>
6754bool TreeTransform<Derived>::TransformExceptionSpec(
6755 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6756 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6757 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6758
6759 // Instantiate a dynamic noexcept expression, if any.
6760 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6761 // Update this scrope because ContextDecl in Sema will be used in
6762 // TransformExpr.
6763 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6764 Sema::CXXThisScopeRAII ThisScope(
6765 SemaRef, Method ? Method->getParent() : nullptr,
6766 Method ? Method->getMethodQualifiers() : Qualifiers{},
6767 Method != nullptr);
6768 EnterExpressionEvaluationContext Unevaluated(
6769 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6770 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6771 if (NoexceptExpr.isInvalid())
6772 return true;
6773
6774 ExceptionSpecificationType EST = ESI.Type;
6775 NoexceptExpr =
6776 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6777 if (NoexceptExpr.isInvalid())
6778 return true;
6779
6780 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6781 Changed = true;
6782 ESI.NoexceptExpr = NoexceptExpr.get();
6783 ESI.Type = EST;
6784 }
6785
6786 if (ESI.Type != EST_Dynamic)
6787 return false;
6788
6789 // Instantiate a dynamic exception specification's type.
6790 for (QualType T : ESI.Exceptions) {
6791 if (const PackExpansionType *PackExpansion =
6792 T->getAs<PackExpansionType>()) {
6793 Changed = true;
6794
6795 // We have a pack expansion. Instantiate it.
6796 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6797 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6798 Unexpanded);
6799 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6800
6801 // Determine whether the set of unexpanded parameter packs can and
6802 // should
6803 // be expanded.
6804 bool Expand = false;
6805 bool RetainExpansion = false;
6806 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6807 // FIXME: Track the location of the ellipsis (and track source location
6808 // information for the types in the exception specification in general).
6809 if (getDerived().TryExpandParameterPacks(
6810 Loc, SourceRange(), Unexpanded,
6811 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6812 NumExpansions))
6813 return true;
6814
6815 if (!Expand) {
6816 // We can't expand this pack expansion into separate arguments yet;
6817 // just substitute into the pattern and create a new pack expansion
6818 // type.
6819 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6820 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6821 if (U.isNull())
6822 return true;
6823
6824 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6825 Exceptions.push_back(Elt: U);
6826 continue;
6827 }
6828
6829 // Substitute into the pack expansion pattern for each slice of the
6830 // pack.
6831 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6832 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6833
6834 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6835 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6836 return true;
6837
6838 Exceptions.push_back(Elt: U);
6839 }
6840 } else {
6841 QualType U = getDerived().TransformType(T);
6842 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6843 return true;
6844 if (T != U)
6845 Changed = true;
6846
6847 Exceptions.push_back(Elt: U);
6848 }
6849 }
6850
6851 ESI.Exceptions = Exceptions;
6852 if (ESI.Exceptions.empty())
6853 ESI.Type = EST_DynamicNone;
6854 return false;
6855}
6856
6857template<typename Derived>
6858QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6859 TypeLocBuilder &TLB,
6860 FunctionNoProtoTypeLoc TL) {
6861 const FunctionNoProtoType *T = TL.getTypePtr();
6862 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6863 if (ResultType.isNull())
6864 return QualType();
6865
6866 QualType Result = TL.getType();
6867 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6868 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6869
6870 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6871 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6872 NewTL.setLParenLoc(TL.getLParenLoc());
6873 NewTL.setRParenLoc(TL.getRParenLoc());
6874 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6875
6876 return Result;
6877}
6878
6879template <typename Derived>
6880QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6881 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6882
6883 const UnresolvedUsingType *T = TL.getTypePtr();
6884 bool Changed = false;
6885
6886 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6887 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6888 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6889 if (!QualifierLoc)
6890 return QualType();
6891 Changed |= QualifierLoc != OldQualifierLoc;
6892 }
6893
6894 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6895 if (!D)
6896 return QualType();
6897 Changed |= D != T->getDecl();
6898
6899 QualType Result = TL.getType();
6900 if (getDerived().AlwaysRebuild() || Changed) {
6901 Result = getDerived().RebuildUnresolvedUsingType(
6902 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
6903 D);
6904 if (Result.isNull())
6905 return QualType();
6906 }
6907
6908 if (isa<UsingType>(Val: Result))
6909 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6910 QualifierLoc, NameLoc: TL.getNameLoc());
6911 else
6912 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6913 QualifierLoc, NameLoc: TL.getNameLoc());
6914 return Result;
6915}
6916
6917template <typename Derived>
6918QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6919 UsingTypeLoc TL) {
6920 const UsingType *T = TL.getTypePtr();
6921 bool Changed = false;
6922
6923 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6924 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6925 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6926 if (!QualifierLoc)
6927 return QualType();
6928 Changed |= QualifierLoc != OldQualifierLoc;
6929 }
6930
6931 auto *D = cast_or_null<UsingShadowDecl>(
6932 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6933 if (!D)
6934 return QualType();
6935 Changed |= D != T->getDecl();
6936
6937 QualType UnderlyingType = getDerived().TransformType(T->desugar());
6938 if (UnderlyingType.isNull())
6939 return QualType();
6940 Changed |= UnderlyingType != T->desugar();
6941
6942 QualType Result = TL.getType();
6943 if (getDerived().AlwaysRebuild() || Changed) {
6944 Result = getDerived().RebuildUsingType(
6945 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
6946 UnderlyingType);
6947 if (Result.isNull())
6948 return QualType();
6949 }
6950 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
6951 NameLoc: TL.getNameLoc());
6952 return Result;
6953}
6954
6955template<typename Derived>
6956QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6957 TypedefTypeLoc TL) {
6958 const TypedefType *T = TL.getTypePtr();
6959 bool Changed = false;
6960
6961 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6962 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6963 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6964 if (!QualifierLoc)
6965 return QualType();
6966 Changed |= QualifierLoc != OldQualifierLoc;
6967 }
6968
6969 auto *Typedef = cast_or_null<TypedefNameDecl>(
6970 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6971 if (!Typedef)
6972 return QualType();
6973 Changed |= Typedef != T->getDecl();
6974
6975 // FIXME: Transform the UnderlyingType if different from decl.
6976
6977 QualType Result = TL.getType();
6978 if (getDerived().AlwaysRebuild() || Changed) {
6979 Result = getDerived().RebuildTypedefType(
6980 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
6981 if (Result.isNull())
6982 return QualType();
6983 }
6984
6985 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6986 QualifierLoc, NameLoc: TL.getNameLoc());
6987 return Result;
6988}
6989
6990template<typename Derived>
6991QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6992 TypeOfExprTypeLoc TL) {
6993 // typeof expressions are not potentially evaluated contexts
6994 EnterExpressionEvaluationContext Unevaluated(
6995 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6996 Sema::ReuseLambdaContextDecl);
6997
6998 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6999 if (E.isInvalid())
7000 return QualType();
7001
7002 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7003 if (E.isInvalid())
7004 return QualType();
7005
7006 QualType Result = TL.getType();
7007 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7008 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7009 Result =
7010 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7011 if (Result.isNull())
7012 return QualType();
7013 }
7014
7015 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7016 NewTL.setTypeofLoc(TL.getTypeofLoc());
7017 NewTL.setLParenLoc(TL.getLParenLoc());
7018 NewTL.setRParenLoc(TL.getRParenLoc());
7019
7020 return Result;
7021}
7022
7023template<typename Derived>
7024QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7025 TypeOfTypeLoc TL) {
7026 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7027 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7028 if (!New_Under_TI)
7029 return QualType();
7030
7031 QualType Result = TL.getType();
7032 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7033 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7034 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7035 if (Result.isNull())
7036 return QualType();
7037 }
7038
7039 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7040 NewTL.setTypeofLoc(TL.getTypeofLoc());
7041 NewTL.setLParenLoc(TL.getLParenLoc());
7042 NewTL.setRParenLoc(TL.getRParenLoc());
7043 NewTL.setUnmodifiedTInfo(New_Under_TI);
7044
7045 return Result;
7046}
7047
7048template<typename Derived>
7049QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7050 DecltypeTypeLoc TL) {
7051 const DecltypeType *T = TL.getTypePtr();
7052
7053 // decltype expressions are not potentially evaluated contexts
7054 EnterExpressionEvaluationContext Unevaluated(
7055 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7056 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7057
7058 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7059 if (E.isInvalid())
7060 return QualType();
7061
7062 E = getSema().ActOnDecltypeExpression(E.get());
7063 if (E.isInvalid())
7064 return QualType();
7065
7066 QualType Result = TL.getType();
7067 if (getDerived().AlwaysRebuild() ||
7068 E.get() != T->getUnderlyingExpr()) {
7069 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7070 if (Result.isNull())
7071 return QualType();
7072 }
7073 else E.get();
7074
7075 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7076 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7077 NewTL.setRParenLoc(TL.getRParenLoc());
7078 return Result;
7079}
7080
7081template <typename Derived>
7082QualType
7083TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7084 PackIndexingTypeLoc TL) {
7085 // Transform the index
7086 ExprResult IndexExpr;
7087 {
7088 EnterExpressionEvaluationContext ConstantContext(
7089 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7090
7091 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7092 if (IndexExpr.isInvalid())
7093 return QualType();
7094 }
7095 QualType Pattern = TL.getPattern();
7096
7097 const PackIndexingType *PIT = TL.getTypePtr();
7098 SmallVector<QualType, 5> SubtitutedTypes;
7099 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7100
7101 bool NotYetExpanded = Types.empty();
7102 bool FullySubstituted = true;
7103
7104 if (Types.empty() && !PIT->expandsToEmptyPack())
7105 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7106
7107 for (QualType T : Types) {
7108 if (!T->containsUnexpandedParameterPack()) {
7109 QualType Transformed = getDerived().TransformType(T);
7110 if (Transformed.isNull())
7111 return QualType();
7112 SubtitutedTypes.push_back(Elt: Transformed);
7113 continue;
7114 }
7115
7116 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7117 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7118 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7119 // Determine whether the set of unexpanded parameter packs can and should
7120 // be expanded.
7121 bool ShouldExpand = true;
7122 bool RetainExpansion = false;
7123 UnsignedOrNone NumExpansions = std::nullopt;
7124 if (getDerived().TryExpandParameterPacks(
7125 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7126 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7127 RetainExpansion, NumExpansions))
7128 return QualType();
7129 if (!ShouldExpand) {
7130 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7131 // FIXME: should we keep TypeLoc for individual expansions in
7132 // PackIndexingTypeLoc?
7133 TypeSourceInfo *TI =
7134 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7135 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7136 if (Pack.isNull())
7137 return QualType();
7138 if (NotYetExpanded) {
7139 FullySubstituted = false;
7140 QualType Out = getDerived().RebuildPackIndexingType(
7141 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7142 FullySubstituted);
7143 if (Out.isNull())
7144 return QualType();
7145
7146 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7147 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7148 return Out;
7149 }
7150 SubtitutedTypes.push_back(Elt: Pack);
7151 continue;
7152 }
7153 for (unsigned I = 0; I != *NumExpansions; ++I) {
7154 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7155 QualType Out = getDerived().TransformType(T);
7156 if (Out.isNull())
7157 return QualType();
7158 SubtitutedTypes.push_back(Elt: Out);
7159 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7160 }
7161 // If we're supposed to retain a pack expansion, do so by temporarily
7162 // forgetting the partially-substituted parameter pack.
7163 if (RetainExpansion) {
7164 FullySubstituted = false;
7165 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7166 QualType Out = getDerived().TransformType(T);
7167 if (Out.isNull())
7168 return QualType();
7169 SubtitutedTypes.push_back(Elt: Out);
7170 }
7171 }
7172
7173 // A pack indexing type can appear in a larger pack expansion,
7174 // e.g. `Pack...[pack_of_indexes]...`
7175 // so we need to temporarily disable substitution of pack elements
7176 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7177 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7178
7179 QualType Out = getDerived().RebuildPackIndexingType(
7180 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7181 FullySubstituted, SubtitutedTypes);
7182 if (Out.isNull())
7183 return Out;
7184
7185 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7186 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7187 return Out;
7188}
7189
7190template<typename Derived>
7191QualType TreeTransform<Derived>::TransformUnaryTransformType(
7192 TypeLocBuilder &TLB,
7193 UnaryTransformTypeLoc TL) {
7194 QualType Result = TL.getType();
7195 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7196 if (Result->isDependentType()) {
7197 const UnaryTransformType *T = TL.getTypePtr();
7198
7199 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7200 if (!NewBaseTSI)
7201 return QualType();
7202 QualType NewBase = NewBaseTSI->getType();
7203
7204 Result = getDerived().RebuildUnaryTransformType(NewBase,
7205 T->getUTTKind(),
7206 TL.getKWLoc());
7207 if (Result.isNull())
7208 return QualType();
7209 }
7210
7211 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7212 NewTL.setKWLoc(TL.getKWLoc());
7213 NewTL.setParensRange(TL.getParensRange());
7214 NewTL.setUnderlyingTInfo(NewBaseTSI);
7215 return Result;
7216}
7217
7218template<typename Derived>
7219QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7220 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7221 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7222
7223 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7224 TemplateName TemplateName = getDerived().TransformTemplateName(
7225 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7226 TL.getTemplateNameLoc());
7227 if (TemplateName.isNull())
7228 return QualType();
7229
7230 QualType OldDeduced = T->getDeducedType();
7231 QualType NewDeduced;
7232 if (!OldDeduced.isNull()) {
7233 NewDeduced = getDerived().TransformType(OldDeduced);
7234 if (NewDeduced.isNull())
7235 return QualType();
7236 }
7237
7238 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7239 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7240 NewDeduced, T->getKeyword(), TemplateName);
7241 if (Result.isNull())
7242 return QualType();
7243
7244 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7245 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7246 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7247 NewTL.setQualifierLoc(QualifierLoc);
7248 return Result;
7249}
7250
7251template <typename Derived>
7252QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7253 TagTypeLoc TL) {
7254 const TagType *T = TL.getTypePtr();
7255
7256 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7257 if (QualifierLoc) {
7258 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7259 if (!QualifierLoc)
7260 return QualType();
7261 }
7262
7263 auto *TD = cast_or_null<TagDecl>(
7264 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7265 if (!TD)
7266 return QualType();
7267
7268 QualType Result = TL.getType();
7269 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7270 TD != T->getDecl()) {
7271 if (T->isCanonicalUnqualified())
7272 Result = getDerived().RebuildCanonicalTagType(TD);
7273 else
7274 Result = getDerived().RebuildTagType(
7275 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7276 if (Result.isNull())
7277 return QualType();
7278 }
7279
7280 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7281 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7282 NewTL.setQualifierLoc(QualifierLoc);
7283 NewTL.setNameLoc(TL.getNameLoc());
7284
7285 return Result;
7286}
7287
7288template <typename Derived>
7289QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7290 EnumTypeLoc TL) {
7291 return getDerived().TransformTagType(TLB, TL);
7292}
7293
7294template <typename Derived>
7295QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7296 RecordTypeLoc TL) {
7297 return getDerived().TransformTagType(TLB, TL);
7298}
7299
7300template<typename Derived>
7301QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7302 TypeLocBuilder &TLB,
7303 InjectedClassNameTypeLoc TL) {
7304 return getDerived().TransformTagType(TLB, TL);
7305}
7306
7307template<typename Derived>
7308QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7309 TypeLocBuilder &TLB,
7310 TemplateTypeParmTypeLoc TL) {
7311 return getDerived().TransformTemplateTypeParmType(
7312 TLB, TL,
7313 /*SuppressObjCLifetime=*/false);
7314}
7315
7316template <typename Derived>
7317QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7318 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7319 return TransformTypeSpecType(TLB, T: TL);
7320}
7321
7322template<typename Derived>
7323QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7324 TypeLocBuilder &TLB,
7325 SubstTemplateTypeParmTypeLoc TL) {
7326 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7327
7328 Decl *NewReplaced =
7329 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7330
7331 // Substitute into the replacement type, which itself might involve something
7332 // that needs to be transformed. This only tends to occur with default
7333 // template arguments of template template parameters.
7334 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7335 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7336 if (Replacement.isNull())
7337 return QualType();
7338
7339 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7340 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7341 Final: T->getFinal());
7342
7343 // Propagate type-source information.
7344 SubstTemplateTypeParmTypeLoc NewTL
7345 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7346 NewTL.setNameLoc(TL.getNameLoc());
7347 return Result;
7348
7349}
7350template <typename Derived>
7351QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7352 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7353 return TransformTypeSpecType(TLB, T: TL);
7354}
7355
7356template<typename Derived>
7357QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7358 TypeLocBuilder &TLB,
7359 SubstTemplateTypeParmPackTypeLoc TL) {
7360 return getDerived().TransformSubstTemplateTypeParmPackType(
7361 TLB, TL, /*SuppressObjCLifetime=*/false);
7362}
7363
7364template <typename Derived>
7365QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7366 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7367 return TransformTypeSpecType(TLB, T: TL);
7368}
7369
7370template<typename Derived>
7371QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7372 AtomicTypeLoc TL) {
7373 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7374 if (ValueType.isNull())
7375 return QualType();
7376
7377 QualType Result = TL.getType();
7378 if (getDerived().AlwaysRebuild() ||
7379 ValueType != TL.getValueLoc().getType()) {
7380 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7381 if (Result.isNull())
7382 return QualType();
7383 }
7384
7385 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7386 NewTL.setKWLoc(TL.getKWLoc());
7387 NewTL.setLParenLoc(TL.getLParenLoc());
7388 NewTL.setRParenLoc(TL.getRParenLoc());
7389
7390 return Result;
7391}
7392
7393template <typename Derived>
7394QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7395 PipeTypeLoc TL) {
7396 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7397 if (ValueType.isNull())
7398 return QualType();
7399
7400 QualType Result = TL.getType();
7401 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7402 const PipeType *PT = Result->castAs<PipeType>();
7403 bool isReadPipe = PT->isReadOnly();
7404 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7405 if (Result.isNull())
7406 return QualType();
7407 }
7408
7409 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7410 NewTL.setKWLoc(TL.getKWLoc());
7411
7412 return Result;
7413}
7414
7415template <typename Derived>
7416QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7417 BitIntTypeLoc TL) {
7418 const BitIntType *EIT = TL.getTypePtr();
7419 QualType Result = TL.getType();
7420
7421 if (getDerived().AlwaysRebuild()) {
7422 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7423 EIT->getNumBits(), TL.getNameLoc());
7424 if (Result.isNull())
7425 return QualType();
7426 }
7427
7428 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7429 NewTL.setNameLoc(TL.getNameLoc());
7430 return Result;
7431}
7432
7433template <typename Derived>
7434QualType TreeTransform<Derived>::TransformDependentBitIntType(
7435 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7436 const DependentBitIntType *EIT = TL.getTypePtr();
7437
7438 EnterExpressionEvaluationContext Unevaluated(
7439 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7440 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7441 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7442
7443 if (BitsExpr.isInvalid())
7444 return QualType();
7445
7446 QualType Result = TL.getType();
7447
7448 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7449 Result = getDerived().RebuildDependentBitIntType(
7450 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7451
7452 if (Result.isNull())
7453 return QualType();
7454 }
7455
7456 if (isa<DependentBitIntType>(Val: Result)) {
7457 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7458 NewTL.setNameLoc(TL.getNameLoc());
7459 } else {
7460 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7461 NewTL.setNameLoc(TL.getNameLoc());
7462 }
7463 return Result;
7464}
7465
7466template <typename Derived>
7467QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7468 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7469 llvm_unreachable("This type does not need to be transformed.");
7470}
7471
7472 /// Simple iterator that traverses the template arguments in a
7473 /// container that provides a \c getArgLoc() member function.
7474 ///
7475 /// This iterator is intended to be used with the iterator form of
7476 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7477 template<typename ArgLocContainer>
7478 class TemplateArgumentLocContainerIterator {
7479 ArgLocContainer *Container;
7480 unsigned Index;
7481
7482 public:
7483 typedef TemplateArgumentLoc value_type;
7484 typedef TemplateArgumentLoc reference;
7485 typedef int difference_type;
7486 typedef std::input_iterator_tag iterator_category;
7487
7488 class pointer {
7489 TemplateArgumentLoc Arg;
7490
7491 public:
7492 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7493
7494 const TemplateArgumentLoc *operator->() const {
7495 return &Arg;
7496 }
7497 };
7498
7499
7500 TemplateArgumentLocContainerIterator() {}
7501
7502 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7503 unsigned Index)
7504 : Container(&Container), Index(Index) { }
7505
7506 TemplateArgumentLocContainerIterator &operator++() {
7507 ++Index;
7508 return *this;
7509 }
7510
7511 TemplateArgumentLocContainerIterator operator++(int) {
7512 TemplateArgumentLocContainerIterator Old(*this);
7513 ++(*this);
7514 return Old;
7515 }
7516
7517 TemplateArgumentLoc operator*() const {
7518 return Container->getArgLoc(Index);
7519 }
7520
7521 pointer operator->() const {
7522 return pointer(Container->getArgLoc(Index));
7523 }
7524
7525 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7526 const TemplateArgumentLocContainerIterator &Y) {
7527 return X.Container == Y.Container && X.Index == Y.Index;
7528 }
7529
7530 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7531 const TemplateArgumentLocContainerIterator &Y) {
7532 return !(X == Y);
7533 }
7534 };
7535
7536template<typename Derived>
7537QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7538 AutoTypeLoc TL) {
7539 const AutoType *T = TL.getTypePtr();
7540 QualType OldDeduced = T->getDeducedType();
7541 QualType NewDeduced;
7542 if (!OldDeduced.isNull()) {
7543 NewDeduced = getDerived().TransformType(OldDeduced);
7544 if (NewDeduced.isNull())
7545 return QualType();
7546 }
7547
7548 ConceptDecl *NewCD = nullptr;
7549 TemplateArgumentListInfo NewTemplateArgs;
7550 NestedNameSpecifierLoc NewNestedNameSpec;
7551 if (T->isConstrained()) {
7552 assert(TL.getConceptReference());
7553 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7554 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7555
7556 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7557 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7558 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7559 if (getDerived().TransformTemplateArguments(
7560 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7561 NewTemplateArgs))
7562 return QualType();
7563
7564 if (TL.getNestedNameSpecifierLoc()) {
7565 NewNestedNameSpec
7566 = getDerived().TransformNestedNameSpecifierLoc(
7567 TL.getNestedNameSpecifierLoc());
7568 if (!NewNestedNameSpec)
7569 return QualType();
7570 }
7571 }
7572
7573 QualType Result = TL.getType();
7574 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7575 T->isDependentType() || T->isConstrained()) {
7576 // FIXME: Maybe don't rebuild if all template arguments are the same.
7577 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7578 NewArgList.reserve(N: NewTemplateArgs.size());
7579 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7580 NewArgList.push_back(Elt: ArgLoc.getArgument());
7581 Result = getDerived().RebuildAutoType(
7582 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7583 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7584 if (Result.isNull())
7585 return QualType();
7586 }
7587
7588 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7589 NewTL.setNameLoc(TL.getNameLoc());
7590 NewTL.setRParenLoc(TL.getRParenLoc());
7591 NewTL.setConceptReference(nullptr);
7592
7593 if (T->isConstrained()) {
7594 DeclarationNameInfo DNI = DeclarationNameInfo(
7595 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7596 TL.getConceptNameLoc(),
7597 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7598 auto *CR = ConceptReference::Create(
7599 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7600 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7601 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7602 NewTL.setConceptReference(CR);
7603 }
7604
7605 return Result;
7606}
7607
7608template <typename Derived>
7609QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7610 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7611 return getDerived().TransformTemplateSpecializationType(
7612 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7613 /*AllowInjectedClassName=*/false);
7614}
7615
7616template <typename Derived>
7617QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7618 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7619 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7620 const TemplateSpecializationType *T = TL.getTypePtr();
7621
7622 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7623 TemplateName Template = getDerived().TransformTemplateName(
7624 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7625 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7626 AllowInjectedClassName);
7627 if (Template.isNull())
7628 return QualType();
7629
7630 TemplateArgumentListInfo NewTemplateArgs;
7631 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7632 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7633 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7634 ArgIterator;
7635 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7636 ArgIterator(TL, TL.getNumArgs()),
7637 NewTemplateArgs))
7638 return QualType();
7639
7640 // This needs to be rebuilt if either the arguments changed, or if the
7641 // original template changed. If the template changed, and even if the
7642 // arguments didn't change, these arguments might not correspond to their
7643 // respective parameters, therefore needing conversions.
7644 QualType Result = getDerived().RebuildTemplateSpecializationType(
7645 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7646 NewTemplateArgs);
7647
7648 if (!Result.isNull()) {
7649 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7650 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7651 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7652 }
7653
7654 return Result;
7655}
7656
7657template <typename Derived>
7658QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7659 AttributedTypeLoc TL) {
7660 const AttributedType *oldType = TL.getTypePtr();
7661 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7662 if (modifiedType.isNull())
7663 return QualType();
7664
7665 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7666 const Attr *oldAttr = TL.getAttr();
7667 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7668 if (oldAttr && !newAttr)
7669 return QualType();
7670
7671 QualType result = TL.getType();
7672
7673 // FIXME: dependent operand expressions?
7674 if (getDerived().AlwaysRebuild() ||
7675 modifiedType != oldType->getModifiedType()) {
7676 // If the equivalent type is equal to the modified type, we don't want to
7677 // transform it as well because:
7678 //
7679 // 1. The transformation would yield the same result and is therefore
7680 // superfluous, and
7681 //
7682 // 2. Transforming the same type twice can cause problems, e.g. if it
7683 // is a FunctionProtoType, we may end up instantiating the function
7684 // parameters twice, which causes an assertion since the parameters
7685 // are already bound to their counterparts in the template for this
7686 // instantiation.
7687 //
7688 QualType equivalentType = modifiedType;
7689 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7690 TypeLocBuilder AuxiliaryTLB;
7691 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7692 equivalentType =
7693 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7694 if (equivalentType.isNull())
7695 return QualType();
7696 }
7697
7698 // Check whether we can add nullability; it is only represented as
7699 // type sugar, and therefore cannot be diagnosed in any other way.
7700 if (auto nullability = oldType->getImmediateNullability()) {
7701 if (!modifiedType->canHaveNullability()) {
7702 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7703 : TL.getModifiedLoc().getBeginLoc()),
7704 DiagID: diag::err_nullability_nonpointer)
7705 << DiagNullabilityKind(*nullability, false) << modifiedType;
7706 return QualType();
7707 }
7708 }
7709
7710 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7711 modifiedType,
7712 equivalentType,
7713 attr: TL.getAttr());
7714 }
7715
7716 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7717 newTL.setAttr(newAttr);
7718 return result;
7719}
7720
7721template <typename Derived>
7722QualType TreeTransform<Derived>::TransformCountAttributedType(
7723 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7724 const CountAttributedType *OldTy = TL.getTypePtr();
7725 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7726 if (InnerTy.isNull())
7727 return QualType();
7728
7729 Expr *OldCount = TL.getCountExpr();
7730 Expr *NewCount = nullptr;
7731 if (OldCount) {
7732 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7733 if (CountResult.isInvalid())
7734 return QualType();
7735 NewCount = CountResult.get();
7736 }
7737
7738 QualType Result = TL.getType();
7739 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7740 OldCount != NewCount) {
7741 // Currently, CountAttributedType can only wrap incomplete array types.
7742 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7743 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7744 }
7745
7746 TLB.push<CountAttributedTypeLoc>(T: Result);
7747 return Result;
7748}
7749
7750template <typename Derived>
7751QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7752 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7753 // The BTFTagAttributedType is available for C only.
7754 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7755}
7756
7757template <typename Derived>
7758QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7759 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7760 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7761 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7762 if (InnerTy.isNull())
7763 return QualType();
7764
7765 QualType Result = TL.getType();
7766 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7767 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7768 Wrapped: InnerTy);
7769 if (Result.isNull())
7770 return QualType();
7771 }
7772
7773 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7774 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7775 return Result;
7776}
7777
7778template <typename Derived>
7779QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7780 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7781
7782 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7783
7784 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7785 if (WrappedTy.isNull())
7786 return QualType();
7787
7788 QualType ContainedTy = QualType();
7789 QualType OldContainedTy = oldType->getContainedType();
7790 TypeSourceInfo *ContainedTSI = nullptr;
7791 if (!OldContainedTy.isNull()) {
7792 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7793 if (!oldContainedTSI)
7794 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7795 OldContainedTy, SourceLocation());
7796 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7797 if (!ContainedTSI)
7798 return QualType();
7799 ContainedTy = ContainedTSI->getType();
7800 }
7801
7802 QualType Result = TL.getType();
7803 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7804 ContainedTy != oldType->getContainedType()) {
7805 Result = SemaRef.Context.getHLSLAttributedResourceType(
7806 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7807 }
7808
7809 HLSLAttributedResourceTypeLoc NewTL =
7810 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7811 NewTL.setSourceRange(TL.getLocalSourceRange());
7812 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7813 return Result;
7814}
7815
7816template <typename Derived>
7817QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7818 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7819 // No transformations needed.
7820 return TL.getType();
7821}
7822
7823template<typename Derived>
7824QualType
7825TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7826 ParenTypeLoc TL) {
7827 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7828 if (Inner.isNull())
7829 return QualType();
7830
7831 QualType Result = TL.getType();
7832 if (getDerived().AlwaysRebuild() ||
7833 Inner != TL.getInnerLoc().getType()) {
7834 Result = getDerived().RebuildParenType(Inner);
7835 if (Result.isNull())
7836 return QualType();
7837 }
7838
7839 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7840 NewTL.setLParenLoc(TL.getLParenLoc());
7841 NewTL.setRParenLoc(TL.getRParenLoc());
7842 return Result;
7843}
7844
7845template <typename Derived>
7846QualType
7847TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7848 MacroQualifiedTypeLoc TL) {
7849 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7850 if (Inner.isNull())
7851 return QualType();
7852
7853 QualType Result = TL.getType();
7854 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7855 Result =
7856 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7857 if (Result.isNull())
7858 return QualType();
7859 }
7860
7861 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7862 NewTL.setExpansionLoc(TL.getExpansionLoc());
7863 return Result;
7864}
7865
7866template<typename Derived>
7867QualType TreeTransform<Derived>::TransformDependentNameType(
7868 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7869 return TransformDependentNameType(TLB, TL, false);
7870}
7871
7872template <typename Derived>
7873QualType TreeTransform<Derived>::TransformDependentNameType(
7874 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
7875 QualType ObjectType, NamedDecl *UnqualLookup) {
7876 const DependentNameType *T = TL.getTypePtr();
7877
7878 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7879 if (QualifierLoc) {
7880 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
7881 QualifierLoc, ObjectType, UnqualLookup);
7882 if (!QualifierLoc)
7883 return QualType();
7884 } else {
7885 assert((ObjectType.isNull() && !UnqualLookup) &&
7886 "must be transformed by TransformNestedNameSpecifierLoc");
7887 }
7888
7889 QualType Result
7890 = getDerived().RebuildDependentNameType(T->getKeyword(),
7891 TL.getElaboratedKeywordLoc(),
7892 QualifierLoc,
7893 T->getIdentifier(),
7894 TL.getNameLoc(),
7895 DeducedTSTContext);
7896 if (Result.isNull())
7897 return QualType();
7898
7899 if (isa<TagType>(Val: Result)) {
7900 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
7901 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7902 NewTL.setQualifierLoc(QualifierLoc);
7903 NewTL.setNameLoc(TL.getNameLoc());
7904 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
7905 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7906 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7907 NewTL.setTemplateNameLoc(TL.getNameLoc());
7908 NewTL.setQualifierLoc(QualifierLoc);
7909 } else if (isa<TypedefType>(Val: Result)) {
7910 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7911 QualifierLoc, NameLoc: TL.getNameLoc());
7912 } else if (isa<UnresolvedUsingType>(Val: Result)) {
7913 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
7914 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
7915 } else {
7916 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7917 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7918 NewTL.setQualifierLoc(QualifierLoc);
7919 NewTL.setNameLoc(TL.getNameLoc());
7920 }
7921 return Result;
7922}
7923
7924template<typename Derived>
7925QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7926 PackExpansionTypeLoc TL) {
7927 QualType Pattern
7928 = getDerived().TransformType(TLB, TL.getPatternLoc());
7929 if (Pattern.isNull())
7930 return QualType();
7931
7932 QualType Result = TL.getType();
7933 if (getDerived().AlwaysRebuild() ||
7934 Pattern != TL.getPatternLoc().getType()) {
7935 Result = getDerived().RebuildPackExpansionType(Pattern,
7936 TL.getPatternLoc().getSourceRange(),
7937 TL.getEllipsisLoc(),
7938 TL.getTypePtr()->getNumExpansions());
7939 if (Result.isNull())
7940 return QualType();
7941 }
7942
7943 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7944 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7945 return Result;
7946}
7947
7948template<typename Derived>
7949QualType
7950TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7951 ObjCInterfaceTypeLoc TL) {
7952 // ObjCInterfaceType is never dependent.
7953 TLB.pushFullCopy(L: TL);
7954 return TL.getType();
7955}
7956
7957template<typename Derived>
7958QualType
7959TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7960 ObjCTypeParamTypeLoc TL) {
7961 const ObjCTypeParamType *T = TL.getTypePtr();
7962 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7963 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7964 if (!OTP)
7965 return QualType();
7966
7967 QualType Result = TL.getType();
7968 if (getDerived().AlwaysRebuild() ||
7969 OTP != T->getDecl()) {
7970 Result = getDerived().RebuildObjCTypeParamType(
7971 OTP, TL.getProtocolLAngleLoc(),
7972 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7973 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7974 if (Result.isNull())
7975 return QualType();
7976 }
7977
7978 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7979 if (TL.getNumProtocols()) {
7980 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7981 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7982 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7983 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7984 }
7985 return Result;
7986}
7987
7988template<typename Derived>
7989QualType
7990TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7991 ObjCObjectTypeLoc TL) {
7992 // Transform base type.
7993 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7994 if (BaseType.isNull())
7995 return QualType();
7996
7997 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7998
7999 // Transform type arguments.
8000 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8001 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8002 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8003 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8004 QualType TypeArg = TypeArgInfo->getType();
8005 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8006 AnyChanged = true;
8007
8008 // We have a pack expansion. Instantiate it.
8009 const auto *PackExpansion = PackExpansionLoc.getType()
8010 ->castAs<PackExpansionType>();
8011 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8012 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8013 Unexpanded);
8014 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8015
8016 // Determine whether the set of unexpanded parameter packs can
8017 // and should be expanded.
8018 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8019 bool Expand = false;
8020 bool RetainExpansion = false;
8021 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8022 if (getDerived().TryExpandParameterPacks(
8023 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8024 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8025 RetainExpansion, NumExpansions))
8026 return QualType();
8027
8028 if (!Expand) {
8029 // We can't expand this pack expansion into separate arguments yet;
8030 // just substitute into the pattern and create a new pack expansion
8031 // type.
8032 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8033
8034 TypeLocBuilder TypeArgBuilder;
8035 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8036 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8037 PatternLoc);
8038 if (NewPatternType.isNull())
8039 return QualType();
8040
8041 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8042 Pattern: NewPatternType, NumExpansions);
8043 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8044 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8045 NewTypeArgInfos.push_back(
8046 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8047 continue;
8048 }
8049
8050 // Substitute into the pack expansion pattern for each slice of the
8051 // pack.
8052 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8053 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8054
8055 TypeLocBuilder TypeArgBuilder;
8056 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8057
8058 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8059 PatternLoc);
8060 if (NewTypeArg.isNull())
8061 return QualType();
8062
8063 NewTypeArgInfos.push_back(
8064 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8065 }
8066
8067 continue;
8068 }
8069
8070 TypeLocBuilder TypeArgBuilder;
8071 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8072 QualType NewTypeArg =
8073 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8074 if (NewTypeArg.isNull())
8075 return QualType();
8076
8077 // If nothing changed, just keep the old TypeSourceInfo.
8078 if (NewTypeArg == TypeArg) {
8079 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8080 continue;
8081 }
8082
8083 NewTypeArgInfos.push_back(
8084 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8085 AnyChanged = true;
8086 }
8087
8088 QualType Result = TL.getType();
8089 if (getDerived().AlwaysRebuild() || AnyChanged) {
8090 // Rebuild the type.
8091 Result = getDerived().RebuildObjCObjectType(
8092 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8093 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8094 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8095 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8096
8097 if (Result.isNull())
8098 return QualType();
8099 }
8100
8101 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8102 NewT.setHasBaseTypeAsWritten(true);
8103 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8104 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8105 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8106 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8107 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8108 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8109 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8110 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8111 return Result;
8112}
8113
8114template<typename Derived>
8115QualType
8116TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8117 ObjCObjectPointerTypeLoc TL) {
8118 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8119 if (PointeeType.isNull())
8120 return QualType();
8121
8122 QualType Result = TL.getType();
8123 if (getDerived().AlwaysRebuild() ||
8124 PointeeType != TL.getPointeeLoc().getType()) {
8125 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8126 TL.getStarLoc());
8127 if (Result.isNull())
8128 return QualType();
8129 }
8130
8131 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8132 NewT.setStarLoc(TL.getStarLoc());
8133 return Result;
8134}
8135
8136//===----------------------------------------------------------------------===//
8137// Statement transformation
8138//===----------------------------------------------------------------------===//
8139template<typename Derived>
8140StmtResult
8141TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8142 return S;
8143}
8144
8145template<typename Derived>
8146StmtResult
8147TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8148 return getDerived().TransformCompoundStmt(S, false);
8149}
8150
8151template<typename Derived>
8152StmtResult
8153TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8154 bool IsStmtExpr) {
8155 Sema::CompoundScopeRAII CompoundScope(getSema());
8156 Sema::FPFeaturesStateRAII FPSave(getSema());
8157 if (S->hasStoredFPFeatures())
8158 getSema().resetFPOptions(
8159 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8160
8161 bool SubStmtInvalid = false;
8162 bool SubStmtChanged = false;
8163 SmallVector<Stmt*, 8> Statements;
8164 for (auto *B : S->body()) {
8165 StmtResult Result = getDerived().TransformStmt(
8166 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8167 : StmtDiscardKind::Discarded);
8168
8169 if (Result.isInvalid()) {
8170 // Immediately fail if this was a DeclStmt, since it's very
8171 // likely that this will cause problems for future statements.
8172 if (isa<DeclStmt>(Val: B))
8173 return StmtError();
8174
8175 // Otherwise, just keep processing substatements and fail later.
8176 SubStmtInvalid = true;
8177 continue;
8178 }
8179
8180 SubStmtChanged = SubStmtChanged || Result.get() != B;
8181 Statements.push_back(Elt: Result.getAs<Stmt>());
8182 }
8183
8184 if (SubStmtInvalid)
8185 return StmtError();
8186
8187 if (!getDerived().AlwaysRebuild() &&
8188 !SubStmtChanged)
8189 return S;
8190
8191 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8192 Statements,
8193 S->getRBracLoc(),
8194 IsStmtExpr);
8195}
8196
8197template<typename Derived>
8198StmtResult
8199TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8200 ExprResult LHS, RHS;
8201 {
8202 EnterExpressionEvaluationContext Unevaluated(
8203 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8204
8205 // Transform the left-hand case value.
8206 LHS = getDerived().TransformExpr(S->getLHS());
8207 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8208 if (LHS.isInvalid())
8209 return StmtError();
8210
8211 // Transform the right-hand case value (for the GNU case-range extension).
8212 RHS = getDerived().TransformExpr(S->getRHS());
8213 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8214 if (RHS.isInvalid())
8215 return StmtError();
8216 }
8217
8218 // Build the case statement.
8219 // Case statements are always rebuilt so that they will attached to their
8220 // transformed switch statement.
8221 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8222 LHS.get(),
8223 S->getEllipsisLoc(),
8224 RHS.get(),
8225 S->getColonLoc());
8226 if (Case.isInvalid())
8227 return StmtError();
8228
8229 // Transform the statement following the case
8230 StmtResult SubStmt =
8231 getDerived().TransformStmt(S->getSubStmt());
8232 if (SubStmt.isInvalid())
8233 return StmtError();
8234
8235 // Attach the body to the case statement
8236 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8237}
8238
8239template <typename Derived>
8240StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8241 // Transform the statement following the default case
8242 StmtResult SubStmt =
8243 getDerived().TransformStmt(S->getSubStmt());
8244 if (SubStmt.isInvalid())
8245 return StmtError();
8246
8247 // Default statements are always rebuilt
8248 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8249 SubStmt.get());
8250}
8251
8252template<typename Derived>
8253StmtResult
8254TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8255 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8256 if (SubStmt.isInvalid())
8257 return StmtError();
8258
8259 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8260 S->getDecl());
8261 if (!LD)
8262 return StmtError();
8263
8264 // If we're transforming "in-place" (we're not creating new local
8265 // declarations), assume we're replacing the old label statement
8266 // and clear out the reference to it.
8267 if (LD == S->getDecl())
8268 S->getDecl()->setStmt(nullptr);
8269
8270 // FIXME: Pass the real colon location in.
8271 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8272 cast<LabelDecl>(Val: LD), SourceLocation(),
8273 SubStmt.get());
8274}
8275
8276template <typename Derived>
8277const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8278 if (!R)
8279 return R;
8280
8281 switch (R->getKind()) {
8282// Transform attributes by calling TransformXXXAttr.
8283#define ATTR(X) \
8284 case attr::X: \
8285 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8286#include "clang/Basic/AttrList.inc"
8287 }
8288 return R;
8289}
8290
8291template <typename Derived>
8292const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8293 const Stmt *InstS,
8294 const Attr *R) {
8295 if (!R)
8296 return R;
8297
8298 switch (R->getKind()) {
8299// Transform attributes by calling TransformStmtXXXAttr.
8300#define ATTR(X) \
8301 case attr::X: \
8302 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8303#include "clang/Basic/AttrList.inc"
8304 }
8305 return TransformAttr(R);
8306}
8307
8308template <typename Derived>
8309StmtResult
8310TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8311 StmtDiscardKind SDK) {
8312 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8313 if (SubStmt.isInvalid())
8314 return StmtError();
8315
8316 bool AttrsChanged = false;
8317 SmallVector<const Attr *, 1> Attrs;
8318
8319 // Visit attributes and keep track if any are transformed.
8320 for (const auto *I : S->getAttrs()) {
8321 const Attr *R =
8322 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8323 AttrsChanged |= (I != R);
8324 if (R)
8325 Attrs.push_back(Elt: R);
8326 }
8327
8328 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8329 return S;
8330
8331 // If transforming the attributes failed for all of the attributes in the
8332 // statement, don't make an AttributedStmt without attributes.
8333 if (Attrs.empty())
8334 return SubStmt;
8335
8336 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8337 SubStmt.get());
8338}
8339
8340template<typename Derived>
8341StmtResult
8342TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8343 // Transform the initialization statement
8344 StmtResult Init = getDerived().TransformStmt(S->getInit());
8345 if (Init.isInvalid())
8346 return StmtError();
8347
8348 Sema::ConditionResult Cond;
8349 if (!S->isConsteval()) {
8350 // Transform the condition
8351 Cond = getDerived().TransformCondition(
8352 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8353 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8354 : Sema::ConditionKind::Boolean);
8355 if (Cond.isInvalid())
8356 return StmtError();
8357 }
8358
8359 // If this is a constexpr if, determine which arm we should instantiate.
8360 std::optional<bool> ConstexprConditionValue;
8361 if (S->isConstexpr())
8362 ConstexprConditionValue = Cond.getKnownValue();
8363
8364 // Transform the "then" branch.
8365 StmtResult Then;
8366 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8367 EnterExpressionEvaluationContext Ctx(
8368 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8369 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8370 S->isNonNegatedConsteval());
8371
8372 Then = getDerived().TransformStmt(S->getThen());
8373 if (Then.isInvalid())
8374 return StmtError();
8375 } else {
8376 // Discarded branch is replaced with empty CompoundStmt so we can keep
8377 // proper source location for start and end of original branch, so
8378 // subsequent transformations like CoverageMapping work properly
8379 Then = new (getSema().Context)
8380 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8381 }
8382
8383 // Transform the "else" branch.
8384 StmtResult Else;
8385 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8386 EnterExpressionEvaluationContext Ctx(
8387 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8388 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8389 S->isNegatedConsteval());
8390
8391 Else = getDerived().TransformStmt(S->getElse());
8392 if (Else.isInvalid())
8393 return StmtError();
8394 } else if (S->getElse() && ConstexprConditionValue &&
8395 *ConstexprConditionValue) {
8396 // Same thing here as with <then> branch, we are discarding it, we can't
8397 // replace it with NULL nor NullStmt as we need to keep for source location
8398 // range, for CoverageMapping
8399 Else = new (getSema().Context)
8400 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8401 }
8402
8403 if (!getDerived().AlwaysRebuild() &&
8404 Init.get() == S->getInit() &&
8405 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8406 Then.get() == S->getThen() &&
8407 Else.get() == S->getElse())
8408 return S;
8409
8410 return getDerived().RebuildIfStmt(
8411 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8412 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8413}
8414
8415template<typename Derived>
8416StmtResult
8417TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8418 // Transform the initialization statement
8419 StmtResult Init = getDerived().TransformStmt(S->getInit());
8420 if (Init.isInvalid())
8421 return StmtError();
8422
8423 // Transform the condition.
8424 Sema::ConditionResult Cond = getDerived().TransformCondition(
8425 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8426 Sema::ConditionKind::Switch);
8427 if (Cond.isInvalid())
8428 return StmtError();
8429
8430 // Rebuild the switch statement.
8431 StmtResult Switch =
8432 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8433 Init.get(), Cond, S->getRParenLoc());
8434 if (Switch.isInvalid())
8435 return StmtError();
8436
8437 // Transform the body of the switch statement.
8438 StmtResult Body = getDerived().TransformStmt(S->getBody());
8439 if (Body.isInvalid())
8440 return StmtError();
8441
8442 // Complete the switch statement.
8443 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8444 Body.get());
8445}
8446
8447template<typename Derived>
8448StmtResult
8449TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8450 // Transform the condition
8451 Sema::ConditionResult Cond = getDerived().TransformCondition(
8452 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8453 Sema::ConditionKind::Boolean);
8454 if (Cond.isInvalid())
8455 return StmtError();
8456
8457 // OpenACC Restricts a while-loop inside of certain construct/clause
8458 // combinations, so diagnose that here in OpenACC mode.
8459 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8460 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8461
8462 // Transform the body
8463 StmtResult Body = getDerived().TransformStmt(S->getBody());
8464 if (Body.isInvalid())
8465 return StmtError();
8466
8467 if (!getDerived().AlwaysRebuild() &&
8468 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8469 Body.get() == S->getBody())
8470 return Owned(S);
8471
8472 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8473 Cond, S->getRParenLoc(), Body.get());
8474}
8475
8476template<typename Derived>
8477StmtResult
8478TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8479 // OpenACC Restricts a do-loop inside of certain construct/clause
8480 // combinations, so diagnose that here in OpenACC mode.
8481 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8482 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8483
8484 // Transform the body
8485 StmtResult Body = getDerived().TransformStmt(S->getBody());
8486 if (Body.isInvalid())
8487 return StmtError();
8488
8489 // Transform the condition
8490 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8491 if (Cond.isInvalid())
8492 return StmtError();
8493
8494 if (!getDerived().AlwaysRebuild() &&
8495 Cond.get() == S->getCond() &&
8496 Body.get() == S->getBody())
8497 return S;
8498
8499 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8500 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8501 S->getRParenLoc());
8502}
8503
8504template<typename Derived>
8505StmtResult
8506TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8507 if (getSema().getLangOpts().OpenMP)
8508 getSema().OpenMP().startOpenMPLoop();
8509
8510 // Transform the initialization statement
8511 StmtResult Init = getDerived().TransformStmt(S->getInit());
8512 if (Init.isInvalid())
8513 return StmtError();
8514
8515 // In OpenMP loop region loop control variable must be captured and be
8516 // private. Perform analysis of first part (if any).
8517 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8518 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8519 Init.get());
8520
8521 // Transform the condition
8522 Sema::ConditionResult Cond = getDerived().TransformCondition(
8523 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8524 Sema::ConditionKind::Boolean);
8525 if (Cond.isInvalid())
8526 return StmtError();
8527
8528 // Transform the increment
8529 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8530 if (Inc.isInvalid())
8531 return StmtError();
8532
8533 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8534 if (S->getInc() && !FullInc.get())
8535 return StmtError();
8536
8537 // OpenACC Restricts a for-loop inside of certain construct/clause
8538 // combinations, so diagnose that here in OpenACC mode.
8539 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8540 SemaRef.OpenACC().ActOnForStmtBegin(
8541 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8542 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8543
8544 // Transform the body
8545 StmtResult Body = getDerived().TransformStmt(S->getBody());
8546 if (Body.isInvalid())
8547 return StmtError();
8548
8549 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8550
8551 if (!getDerived().AlwaysRebuild() &&
8552 Init.get() == S->getInit() &&
8553 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8554 Inc.get() == S->getInc() &&
8555 Body.get() == S->getBody())
8556 return S;
8557
8558 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8559 Init.get(), Cond, FullInc,
8560 S->getRParenLoc(), Body.get());
8561}
8562
8563template<typename Derived>
8564StmtResult
8565TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8566 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8567 S->getLabel());
8568 if (!LD)
8569 return StmtError();
8570
8571 // Goto statements must always be rebuilt, to resolve the label.
8572 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8573 cast<LabelDecl>(Val: LD));
8574}
8575
8576template<typename Derived>
8577StmtResult
8578TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8579 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8580 if (Target.isInvalid())
8581 return StmtError();
8582 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8583
8584 if (!getDerived().AlwaysRebuild() &&
8585 Target.get() == S->getTarget())
8586 return S;
8587
8588 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8589 Target.get());
8590}
8591
8592template<typename Derived>
8593StmtResult
8594TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8595 if (!S->hasLabelTarget())
8596 return S;
8597
8598 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8599 S->getLabelDecl());
8600 if (!LD)
8601 return StmtError();
8602
8603 return new (SemaRef.Context)
8604 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8605}
8606
8607template<typename Derived>
8608StmtResult
8609TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8610 if (!S->hasLabelTarget())
8611 return S;
8612
8613 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8614 S->getLabelDecl());
8615 if (!LD)
8616 return StmtError();
8617
8618 return new (SemaRef.Context)
8619 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8620}
8621
8622template <typename Derived>
8623StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8624 StmtResult Result = getDerived().TransformStmt(S->getBody());
8625 if (!Result.isUsable())
8626 return StmtError();
8627 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8628}
8629
8630template<typename Derived>
8631StmtResult
8632TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8633 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8634 /*NotCopyInit*/false);
8635 if (Result.isInvalid())
8636 return StmtError();
8637
8638 // FIXME: We always rebuild the return statement because there is no way
8639 // to tell whether the return type of the function has changed.
8640 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8641}
8642
8643template<typename Derived>
8644StmtResult
8645TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8646 bool DeclChanged = false;
8647 SmallVector<Decl *, 4> Decls;
8648 LambdaScopeInfo *LSI = getSema().getCurLambda();
8649 for (auto *D : S->decls()) {
8650 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8651 if (!Transformed)
8652 return StmtError();
8653
8654 if (Transformed != D)
8655 DeclChanged = true;
8656
8657 if (LSI) {
8658 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8659 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8660 LSI->ContainsUnexpandedParameterPack |=
8661 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8662 } else {
8663 LSI->ContainsUnexpandedParameterPack |=
8664 getSema()
8665 .getASTContext()
8666 .getTypeDeclType(TD)
8667 ->containsUnexpandedParameterPack();
8668 }
8669 }
8670 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8671 LSI->ContainsUnexpandedParameterPack |=
8672 VD->getType()->containsUnexpandedParameterPack();
8673 }
8674
8675 Decls.push_back(Elt: Transformed);
8676 }
8677
8678 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8679 return S;
8680
8681 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8682}
8683
8684template<typename Derived>
8685StmtResult
8686TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8687
8688 SmallVector<Expr*, 8> Constraints;
8689 SmallVector<Expr*, 8> Exprs;
8690 SmallVector<IdentifierInfo *, 4> Names;
8691
8692 SmallVector<Expr*, 8> Clobbers;
8693
8694 bool ExprsChanged = false;
8695
8696 auto RebuildString = [&](Expr *E) {
8697 ExprResult Result = getDerived().TransformExpr(E);
8698 if (!Result.isUsable())
8699 return Result;
8700 if (Result.get() != E) {
8701 ExprsChanged = true;
8702 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8703 }
8704 return Result;
8705 };
8706
8707 // Go through the outputs.
8708 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8709 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8710
8711 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8712 if (Result.isInvalid())
8713 return StmtError();
8714
8715 Constraints.push_back(Elt: Result.get());
8716
8717 // Transform the output expr.
8718 Expr *OutputExpr = S->getOutputExpr(i: I);
8719 Result = getDerived().TransformExpr(OutputExpr);
8720 if (Result.isInvalid())
8721 return StmtError();
8722
8723 ExprsChanged |= Result.get() != OutputExpr;
8724
8725 Exprs.push_back(Elt: Result.get());
8726 }
8727
8728 // Go through the inputs.
8729 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8730 Names.push_back(Elt: S->getInputIdentifier(i: I));
8731
8732 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8733 if (Result.isInvalid())
8734 return StmtError();
8735
8736 Constraints.push_back(Elt: Result.get());
8737
8738 // Transform the input expr.
8739 Expr *InputExpr = S->getInputExpr(i: I);
8740 Result = getDerived().TransformExpr(InputExpr);
8741 if (Result.isInvalid())
8742 return StmtError();
8743
8744 ExprsChanged |= Result.get() != InputExpr;
8745
8746 Exprs.push_back(Elt: Result.get());
8747 }
8748
8749 // Go through the Labels.
8750 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8751 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8752
8753 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8754 if (Result.isInvalid())
8755 return StmtError();
8756 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8757 Exprs.push_back(Elt: Result.get());
8758 }
8759
8760 // Go through the clobbers.
8761 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8762 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8763 if (Result.isInvalid())
8764 return StmtError();
8765 Clobbers.push_back(Elt: Result.get());
8766 }
8767
8768 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8769 if (AsmString.isInvalid())
8770 return StmtError();
8771
8772 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8773 return S;
8774
8775 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8776 S->isVolatile(), S->getNumOutputs(),
8777 S->getNumInputs(), Names.data(),
8778 Constraints, Exprs, AsmString.get(),
8779 Clobbers, S->getNumLabels(),
8780 S->getRParenLoc());
8781}
8782
8783template<typename Derived>
8784StmtResult
8785TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8786 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8787
8788 bool HadError = false, HadChange = false;
8789
8790 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8791 SmallVector<Expr*, 8> TransformedExprs;
8792 TransformedExprs.reserve(N: SrcExprs.size());
8793 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8794 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8795 if (!Result.isUsable()) {
8796 HadError = true;
8797 } else {
8798 HadChange |= (Result.get() != SrcExprs[i]);
8799 TransformedExprs.push_back(Elt: Result.get());
8800 }
8801 }
8802
8803 if (HadError) return StmtError();
8804 if (!HadChange && !getDerived().AlwaysRebuild())
8805 return Owned(S);
8806
8807 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8808 AsmToks, S->getAsmString(),
8809 S->getNumOutputs(), S->getNumInputs(),
8810 S->getAllConstraints(), S->getClobbers(),
8811 TransformedExprs, S->getEndLoc());
8812}
8813
8814// C++ Coroutines
8815template<typename Derived>
8816StmtResult
8817TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8818 auto *ScopeInfo = SemaRef.getCurFunction();
8819 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8820 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8821 ScopeInfo->NeedsCoroutineSuspends &&
8822 ScopeInfo->CoroutineSuspends.first == nullptr &&
8823 ScopeInfo->CoroutineSuspends.second == nullptr &&
8824 "expected clean scope info");
8825
8826 // Set that we have (possibly-invalid) suspend points before we do anything
8827 // that may fail.
8828 ScopeInfo->setNeedsCoroutineSuspends(false);
8829
8830 // We re-build the coroutine promise object (and the coroutine parameters its
8831 // type and constructor depend on) based on the types used in our current
8832 // function. We must do so, and set it on the current FunctionScopeInfo,
8833 // before attempting to transform the other parts of the coroutine body
8834 // statement, such as the implicit suspend statements (because those
8835 // statements reference the FunctionScopeInfo::CoroutinePromise).
8836 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8837 return StmtError();
8838 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8839 if (!Promise)
8840 return StmtError();
8841 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8842 ScopeInfo->CoroutinePromise = Promise;
8843
8844 // Transform the implicit coroutine statements constructed using dependent
8845 // types during the previous parse: initial and final suspensions, the return
8846 // object, and others. We also transform the coroutine function's body.
8847 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8848 if (InitSuspend.isInvalid())
8849 return StmtError();
8850 StmtResult FinalSuspend =
8851 getDerived().TransformStmt(S->getFinalSuspendStmt());
8852 if (FinalSuspend.isInvalid() ||
8853 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8854 return StmtError();
8855 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8856 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8857
8858 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8859 if (BodyRes.isInvalid())
8860 return StmtError();
8861
8862 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8863 if (Builder.isInvalid())
8864 return StmtError();
8865
8866 Expr *ReturnObject = S->getReturnValueInit();
8867 assert(ReturnObject && "the return object is expected to be valid");
8868 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8869 /*NoCopyInit*/ false);
8870 if (Res.isInvalid())
8871 return StmtError();
8872 Builder.ReturnValue = Res.get();
8873
8874 // If during the previous parse the coroutine still had a dependent promise
8875 // statement, we may need to build some implicit coroutine statements
8876 // (such as exception and fallthrough handlers) for the first time.
8877 if (S->hasDependentPromiseType()) {
8878 // We can only build these statements, however, if the current promise type
8879 // is not dependent.
8880 if (!Promise->getType()->isDependentType()) {
8881 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8882 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8883 "these nodes should not have been built yet");
8884 if (!Builder.buildDependentStatements())
8885 return StmtError();
8886 }
8887 } else {
8888 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8889 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8890 if (Res.isInvalid())
8891 return StmtError();
8892 Builder.OnFallthrough = Res.get();
8893 }
8894
8895 if (auto *OnException = S->getExceptionHandler()) {
8896 StmtResult Res = getDerived().TransformStmt(OnException);
8897 if (Res.isInvalid())
8898 return StmtError();
8899 Builder.OnException = Res.get();
8900 }
8901
8902 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8903 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8904 if (Res.isInvalid())
8905 return StmtError();
8906 Builder.ReturnStmtOnAllocFailure = Res.get();
8907 }
8908
8909 // Transform any additional statements we may have already built
8910 assert(S->getAllocate() && S->getDeallocate() &&
8911 "allocation and deallocation calls must already be built");
8912 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8913 if (AllocRes.isInvalid())
8914 return StmtError();
8915 Builder.Allocate = AllocRes.get();
8916
8917 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8918 if (DeallocRes.isInvalid())
8919 return StmtError();
8920 Builder.Deallocate = DeallocRes.get();
8921
8922 if (auto *ResultDecl = S->getResultDecl()) {
8923 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8924 if (Res.isInvalid())
8925 return StmtError();
8926 Builder.ResultDecl = Res.get();
8927 }
8928
8929 if (auto *ReturnStmt = S->getReturnStmt()) {
8930 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8931 if (Res.isInvalid())
8932 return StmtError();
8933 Builder.ReturnStmt = Res.get();
8934 }
8935 }
8936
8937 return getDerived().RebuildCoroutineBodyStmt(Builder);
8938}
8939
8940template<typename Derived>
8941StmtResult
8942TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8943 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8944 /*NotCopyInit*/false);
8945 if (Result.isInvalid())
8946 return StmtError();
8947
8948 // Always rebuild; we don't know if this needs to be injected into a new
8949 // context or if the promise type has changed.
8950 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8951 S->isImplicit());
8952}
8953
8954template <typename Derived>
8955ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8956 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8957 /*NotCopyInit*/ false);
8958 if (Operand.isInvalid())
8959 return ExprError();
8960
8961 // Rebuild the common-expr from the operand rather than transforming it
8962 // separately.
8963
8964 // FIXME: getCurScope() should not be used during template instantiation.
8965 // We should pick up the set of unqualified lookup results for operator
8966 // co_await during the initial parse.
8967 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8968 getSema().getCurScope(), E->getKeywordLoc());
8969
8970 // Always rebuild; we don't know if this needs to be injected into a new
8971 // context or if the promise type has changed.
8972 return getDerived().RebuildCoawaitExpr(
8973 E->getKeywordLoc(), Operand.get(),
8974 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8975}
8976
8977template <typename Derived>
8978ExprResult
8979TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8980 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8981 /*NotCopyInit*/ false);
8982 if (OperandResult.isInvalid())
8983 return ExprError();
8984
8985 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8986 E->getOperatorCoawaitLookup());
8987
8988 if (LookupResult.isInvalid())
8989 return ExprError();
8990
8991 // Always rebuild; we don't know if this needs to be injected into a new
8992 // context or if the promise type has changed.
8993 return getDerived().RebuildDependentCoawaitExpr(
8994 E->getKeywordLoc(), OperandResult.get(),
8995 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8996}
8997
8998template<typename Derived>
8999ExprResult
9000TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9001 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9002 /*NotCopyInit*/false);
9003 if (Result.isInvalid())
9004 return ExprError();
9005
9006 // Always rebuild; we don't know if this needs to be injected into a new
9007 // context or if the promise type has changed.
9008 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9009}
9010
9011// Objective-C Statements.
9012
9013template<typename Derived>
9014StmtResult
9015TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9016 // Transform the body of the @try.
9017 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9018 if (TryBody.isInvalid())
9019 return StmtError();
9020
9021 // Transform the @catch statements (if present).
9022 bool AnyCatchChanged = false;
9023 SmallVector<Stmt*, 8> CatchStmts;
9024 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9025 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9026 if (Catch.isInvalid())
9027 return StmtError();
9028 if (Catch.get() != S->getCatchStmt(I))
9029 AnyCatchChanged = true;
9030 CatchStmts.push_back(Elt: Catch.get());
9031 }
9032
9033 // Transform the @finally statement (if present).
9034 StmtResult Finally;
9035 if (S->getFinallyStmt()) {
9036 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9037 if (Finally.isInvalid())
9038 return StmtError();
9039 }
9040
9041 // If nothing changed, just retain this statement.
9042 if (!getDerived().AlwaysRebuild() &&
9043 TryBody.get() == S->getTryBody() &&
9044 !AnyCatchChanged &&
9045 Finally.get() == S->getFinallyStmt())
9046 return S;
9047
9048 // Build a new statement.
9049 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9050 CatchStmts, Finally.get());
9051}
9052
9053template<typename Derived>
9054StmtResult
9055TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9056 // Transform the @catch parameter, if there is one.
9057 VarDecl *Var = nullptr;
9058 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9059 TypeSourceInfo *TSInfo = nullptr;
9060 if (FromVar->getTypeSourceInfo()) {
9061 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9062 if (!TSInfo)
9063 return StmtError();
9064 }
9065
9066 QualType T;
9067 if (TSInfo)
9068 T = TSInfo->getType();
9069 else {
9070 T = getDerived().TransformType(FromVar->getType());
9071 if (T.isNull())
9072 return StmtError();
9073 }
9074
9075 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9076 if (!Var)
9077 return StmtError();
9078 }
9079
9080 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9081 if (Body.isInvalid())
9082 return StmtError();
9083
9084 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9085 S->getRParenLoc(),
9086 Var, Body.get());
9087}
9088
9089template<typename Derived>
9090StmtResult
9091TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9092 // Transform the body.
9093 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9094 if (Body.isInvalid())
9095 return StmtError();
9096
9097 // If nothing changed, just retain this statement.
9098 if (!getDerived().AlwaysRebuild() &&
9099 Body.get() == S->getFinallyBody())
9100 return S;
9101
9102 // Build a new statement.
9103 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9104 Body.get());
9105}
9106
9107template<typename Derived>
9108StmtResult
9109TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9110 ExprResult Operand;
9111 if (S->getThrowExpr()) {
9112 Operand = getDerived().TransformExpr(S->getThrowExpr());
9113 if (Operand.isInvalid())
9114 return StmtError();
9115 }
9116
9117 if (!getDerived().AlwaysRebuild() &&
9118 Operand.get() == S->getThrowExpr())
9119 return S;
9120
9121 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9122}
9123
9124template<typename Derived>
9125StmtResult
9126TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9127 ObjCAtSynchronizedStmt *S) {
9128 // Transform the object we are locking.
9129 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9130 if (Object.isInvalid())
9131 return StmtError();
9132 Object =
9133 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9134 Object.get());
9135 if (Object.isInvalid())
9136 return StmtError();
9137
9138 // Transform the body.
9139 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9140 if (Body.isInvalid())
9141 return StmtError();
9142
9143 // If nothing change, just retain the current statement.
9144 if (!getDerived().AlwaysRebuild() &&
9145 Object.get() == S->getSynchExpr() &&
9146 Body.get() == S->getSynchBody())
9147 return S;
9148
9149 // Build a new statement.
9150 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9151 Object.get(), Body.get());
9152}
9153
9154template<typename Derived>
9155StmtResult
9156TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9157 ObjCAutoreleasePoolStmt *S) {
9158 // Transform the body.
9159 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9160 if (Body.isInvalid())
9161 return StmtError();
9162
9163 // If nothing changed, just retain this statement.
9164 if (!getDerived().AlwaysRebuild() &&
9165 Body.get() == S->getSubStmt())
9166 return S;
9167
9168 // Build a new statement.
9169 return getDerived().RebuildObjCAutoreleasePoolStmt(
9170 S->getAtLoc(), Body.get());
9171}
9172
9173template<typename Derived>
9174StmtResult
9175TreeTransform<Derived>::TransformObjCForCollectionStmt(
9176 ObjCForCollectionStmt *S) {
9177 // Transform the element statement.
9178 StmtResult Element = getDerived().TransformStmt(
9179 S->getElement(), StmtDiscardKind::NotDiscarded);
9180 if (Element.isInvalid())
9181 return StmtError();
9182
9183 // Transform the collection expression.
9184 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9185 if (Collection.isInvalid())
9186 return StmtError();
9187
9188 // Transform the body.
9189 StmtResult Body = getDerived().TransformStmt(S->getBody());
9190 if (Body.isInvalid())
9191 return StmtError();
9192
9193 // If nothing changed, just retain this statement.
9194 if (!getDerived().AlwaysRebuild() &&
9195 Element.get() == S->getElement() &&
9196 Collection.get() == S->getCollection() &&
9197 Body.get() == S->getBody())
9198 return S;
9199
9200 // Build a new statement.
9201 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9202 Element.get(),
9203 Collection.get(),
9204 S->getRParenLoc(),
9205 Body.get());
9206}
9207
9208template <typename Derived>
9209StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9210 // Transform the exception declaration, if any.
9211 VarDecl *Var = nullptr;
9212 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9213 TypeSourceInfo *T =
9214 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9215 if (!T)
9216 return StmtError();
9217
9218 Var = getDerived().RebuildExceptionDecl(
9219 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9220 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9221 if (!Var || Var->isInvalidDecl())
9222 return StmtError();
9223 }
9224
9225 // Transform the actual exception handler.
9226 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9227 if (Handler.isInvalid())
9228 return StmtError();
9229
9230 if (!getDerived().AlwaysRebuild() && !Var &&
9231 Handler.get() == S->getHandlerBlock())
9232 return S;
9233
9234 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9235}
9236
9237template <typename Derived>
9238StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9239 // Transform the try block itself.
9240 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9241 if (TryBlock.isInvalid())
9242 return StmtError();
9243
9244 // Transform the handlers.
9245 bool HandlerChanged = false;
9246 SmallVector<Stmt *, 8> Handlers;
9247 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9248 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9249 if (Handler.isInvalid())
9250 return StmtError();
9251
9252 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9253 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9254 }
9255
9256 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9257
9258 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9259 !HandlerChanged)
9260 return S;
9261
9262 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9263 Handlers);
9264}
9265
9266template<typename Derived>
9267StmtResult
9268TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9269 EnterExpressionEvaluationContext ForRangeInitContext(
9270 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9271 /*LambdaContextDecl=*/nullptr,
9272 Sema::ExpressionEvaluationContextRecord::EK_Other,
9273 getSema().getLangOpts().CPlusPlus23);
9274
9275 // P2718R0 - Lifetime extension in range-based for loops.
9276 if (getSema().getLangOpts().CPlusPlus23) {
9277 auto &LastRecord = getSema().currentEvaluationContext();
9278 LastRecord.InLifetimeExtendingContext = true;
9279 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9280 }
9281 StmtResult Init =
9282 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9283 if (Init.isInvalid())
9284 return StmtError();
9285
9286 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9287 if (Range.isInvalid())
9288 return StmtError();
9289
9290 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9291 assert(getSema().getLangOpts().CPlusPlus23 ||
9292 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9293 auto ForRangeLifetimeExtendTemps =
9294 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9295
9296 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9297 if (Begin.isInvalid())
9298 return StmtError();
9299 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9300 if (End.isInvalid())
9301 return StmtError();
9302
9303 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9304 if (Cond.isInvalid())
9305 return StmtError();
9306 if (Cond.get())
9307 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9308 if (Cond.isInvalid())
9309 return StmtError();
9310 if (Cond.get())
9311 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9312
9313 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9314 if (Inc.isInvalid())
9315 return StmtError();
9316 if (Inc.get())
9317 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9318
9319 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9320 if (LoopVar.isInvalid())
9321 return StmtError();
9322
9323 StmtResult NewStmt = S;
9324 if (getDerived().AlwaysRebuild() ||
9325 Init.get() != S->getInit() ||
9326 Range.get() != S->getRangeStmt() ||
9327 Begin.get() != S->getBeginStmt() ||
9328 End.get() != S->getEndStmt() ||
9329 Cond.get() != S->getCond() ||
9330 Inc.get() != S->getInc() ||
9331 LoopVar.get() != S->getLoopVarStmt()) {
9332 NewStmt = getDerived().RebuildCXXForRangeStmt(
9333 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9334 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9335 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9336 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9337 // Might not have attached any initializer to the loop variable.
9338 getSema().ActOnInitializerError(
9339 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9340 return StmtError();
9341 }
9342 }
9343
9344 // OpenACC Restricts a while-loop inside of certain construct/clause
9345 // combinations, so diagnose that here in OpenACC mode.
9346 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9347 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9348
9349 StmtResult Body = getDerived().TransformStmt(S->getBody());
9350 if (Body.isInvalid())
9351 return StmtError();
9352
9353 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9354
9355 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9356 // it now so we have a new statement to attach the body to.
9357 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9358 NewStmt = getDerived().RebuildCXXForRangeStmt(
9359 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9360 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9361 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9362 if (NewStmt.isInvalid())
9363 return StmtError();
9364 }
9365
9366 if (NewStmt.get() == S)
9367 return S;
9368
9369 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9370}
9371
9372template<typename Derived>
9373StmtResult
9374TreeTransform<Derived>::TransformMSDependentExistsStmt(
9375 MSDependentExistsStmt *S) {
9376 // Transform the nested-name-specifier, if any.
9377 NestedNameSpecifierLoc QualifierLoc;
9378 if (S->getQualifierLoc()) {
9379 QualifierLoc
9380 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9381 if (!QualifierLoc)
9382 return StmtError();
9383 }
9384
9385 // Transform the declaration name.
9386 DeclarationNameInfo NameInfo = S->getNameInfo();
9387 if (NameInfo.getName()) {
9388 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9389 if (!NameInfo.getName())
9390 return StmtError();
9391 }
9392
9393 // Check whether anything changed.
9394 if (!getDerived().AlwaysRebuild() &&
9395 QualifierLoc == S->getQualifierLoc() &&
9396 NameInfo.getName() == S->getNameInfo().getName())
9397 return S;
9398
9399 // Determine whether this name exists, if we can.
9400 CXXScopeSpec SS;
9401 SS.Adopt(Other: QualifierLoc);
9402 bool Dependent = false;
9403 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9404 case IfExistsResult::Exists:
9405 if (S->isIfExists())
9406 break;
9407
9408 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9409
9410 case IfExistsResult::DoesNotExist:
9411 if (S->isIfNotExists())
9412 break;
9413
9414 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9415
9416 case IfExistsResult::Dependent:
9417 Dependent = true;
9418 break;
9419
9420 case IfExistsResult::Error:
9421 return StmtError();
9422 }
9423
9424 // We need to continue with the instantiation, so do so now.
9425 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9426 if (SubStmt.isInvalid())
9427 return StmtError();
9428
9429 // If we have resolved the name, just transform to the substatement.
9430 if (!Dependent)
9431 return SubStmt;
9432
9433 // The name is still dependent, so build a dependent expression again.
9434 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9435 S->isIfExists(),
9436 QualifierLoc,
9437 NameInfo,
9438 SubStmt.get());
9439}
9440
9441template<typename Derived>
9442ExprResult
9443TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9444 NestedNameSpecifierLoc QualifierLoc;
9445 if (E->getQualifierLoc()) {
9446 QualifierLoc
9447 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9448 if (!QualifierLoc)
9449 return ExprError();
9450 }
9451
9452 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9453 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9454 if (!PD)
9455 return ExprError();
9456
9457 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9458 if (Base.isInvalid())
9459 return ExprError();
9460
9461 return new (SemaRef.getASTContext())
9462 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9463 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9464 QualifierLoc, E->getMemberLoc());
9465}
9466
9467template <typename Derived>
9468ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9469 MSPropertySubscriptExpr *E) {
9470 auto BaseRes = getDerived().TransformExpr(E->getBase());
9471 if (BaseRes.isInvalid())
9472 return ExprError();
9473 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9474 if (IdxRes.isInvalid())
9475 return ExprError();
9476
9477 if (!getDerived().AlwaysRebuild() &&
9478 BaseRes.get() == E->getBase() &&
9479 IdxRes.get() == E->getIdx())
9480 return E;
9481
9482 return getDerived().RebuildArraySubscriptExpr(
9483 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9484}
9485
9486template <typename Derived>
9487StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9488 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9489 if (TryBlock.isInvalid())
9490 return StmtError();
9491
9492 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9493 if (Handler.isInvalid())
9494 return StmtError();
9495
9496 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9497 Handler.get() == S->getHandler())
9498 return S;
9499
9500 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9501 TryBlock.get(), Handler.get());
9502}
9503
9504template <typename Derived>
9505StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9506 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9507 if (Block.isInvalid())
9508 return StmtError();
9509
9510 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9511}
9512
9513template <typename Derived>
9514StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9515 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9516 if (FilterExpr.isInvalid())
9517 return StmtError();
9518
9519 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9520 if (Block.isInvalid())
9521 return StmtError();
9522
9523 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9524 Block.get());
9525}
9526
9527template <typename Derived>
9528StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9529 if (isa<SEHFinallyStmt>(Val: Handler))
9530 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9531 else
9532 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9533}
9534
9535template<typename Derived>
9536StmtResult
9537TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9538 return S;
9539}
9540
9541//===----------------------------------------------------------------------===//
9542// OpenMP directive transformation
9543//===----------------------------------------------------------------------===//
9544
9545template <typename Derived>
9546StmtResult
9547TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9548 // OMPCanonicalLoops are eliminated during transformation, since they will be
9549 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9550 // after transformation.
9551 return getDerived().TransformStmt(L->getLoopStmt());
9552}
9553
9554template <typename Derived>
9555StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9556 OMPExecutableDirective *D) {
9557
9558 // Transform the clauses
9559 llvm::SmallVector<OMPClause *, 16> TClauses;
9560 ArrayRef<OMPClause *> Clauses = D->clauses();
9561 TClauses.reserve(N: Clauses.size());
9562 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9563 I != E; ++I) {
9564 if (*I) {
9565 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9566 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9567 getDerived().getSema().OpenMP().EndOpenMPClause();
9568 if (Clause)
9569 TClauses.push_back(Elt: Clause);
9570 } else {
9571 TClauses.push_back(Elt: nullptr);
9572 }
9573 }
9574 StmtResult AssociatedStmt;
9575 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9576 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9577 D->getDirectiveKind(),
9578 /*CurScope=*/nullptr);
9579 StmtResult Body;
9580 {
9581 Sema::CompoundScopeRAII CompoundScope(getSema());
9582 Stmt *CS;
9583 if (D->getDirectiveKind() == OMPD_atomic ||
9584 D->getDirectiveKind() == OMPD_critical ||
9585 D->getDirectiveKind() == OMPD_section ||
9586 D->getDirectiveKind() == OMPD_master)
9587 CS = D->getAssociatedStmt();
9588 else
9589 CS = D->getRawStmt();
9590 Body = getDerived().TransformStmt(CS);
9591 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9592 getSema().getLangOpts().OpenMPIRBuilder)
9593 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9594 }
9595 AssociatedStmt =
9596 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9597 if (AssociatedStmt.isInvalid()) {
9598 return StmtError();
9599 }
9600 }
9601 if (TClauses.size() != Clauses.size()) {
9602 return StmtError();
9603 }
9604
9605 // Transform directive name for 'omp critical' directive.
9606 DeclarationNameInfo DirName;
9607 if (D->getDirectiveKind() == OMPD_critical) {
9608 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9609 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9610 }
9611 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9612 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9613 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9614 } else if (D->getDirectiveKind() == OMPD_cancel) {
9615 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9616 }
9617
9618 return getDerived().RebuildOMPExecutableDirective(
9619 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9620 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9621}
9622
9623/// This is mostly the same as above, but allows 'informational' class
9624/// directives when rebuilding the stmt. It still takes an
9625/// OMPExecutableDirective-type argument because we're reusing that as the
9626/// superclass for the 'assume' directive at present, instead of defining a
9627/// mostly-identical OMPInformationalDirective parent class.
9628template <typename Derived>
9629StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9630 OMPExecutableDirective *D) {
9631
9632 // Transform the clauses
9633 llvm::SmallVector<OMPClause *, 16> TClauses;
9634 ArrayRef<OMPClause *> Clauses = D->clauses();
9635 TClauses.reserve(N: Clauses.size());
9636 for (OMPClause *C : Clauses) {
9637 if (C) {
9638 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9639 OMPClause *Clause = getDerived().TransformOMPClause(C);
9640 getDerived().getSema().OpenMP().EndOpenMPClause();
9641 if (Clause)
9642 TClauses.push_back(Elt: Clause);
9643 } else {
9644 TClauses.push_back(Elt: nullptr);
9645 }
9646 }
9647 StmtResult AssociatedStmt;
9648 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9649 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9650 D->getDirectiveKind(),
9651 /*CurScope=*/nullptr);
9652 StmtResult Body;
9653 {
9654 Sema::CompoundScopeRAII CompoundScope(getSema());
9655 assert(D->getDirectiveKind() == OMPD_assume &&
9656 "Unexpected informational directive");
9657 Stmt *CS = D->getAssociatedStmt();
9658 Body = getDerived().TransformStmt(CS);
9659 }
9660 AssociatedStmt =
9661 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9662 if (AssociatedStmt.isInvalid())
9663 return StmtError();
9664 }
9665 if (TClauses.size() != Clauses.size())
9666 return StmtError();
9667
9668 DeclarationNameInfo DirName;
9669
9670 return getDerived().RebuildOMPInformationalDirective(
9671 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9672 D->getBeginLoc(), D->getEndLoc());
9673}
9674
9675template <typename Derived>
9676StmtResult
9677TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9678 // TODO: Fix This
9679 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9680 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9681 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9682 return StmtError();
9683}
9684
9685template <typename Derived>
9686StmtResult
9687TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9688 DeclarationNameInfo DirName;
9689 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9690 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9691 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9692 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9693 return Res;
9694}
9695
9696template <typename Derived>
9697StmtResult
9698TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9699 DeclarationNameInfo DirName;
9700 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9701 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9702 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9703 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9704 return Res;
9705}
9706
9707template <typename Derived>
9708StmtResult
9709TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9710 DeclarationNameInfo DirName;
9711 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9712 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9713 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9714 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9715 return Res;
9716}
9717
9718template <typename Derived>
9719StmtResult
9720TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9721 DeclarationNameInfo DirName;
9722 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9723 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9724 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9725 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9726 return Res;
9727}
9728
9729template <typename Derived>
9730StmtResult
9731TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9732 DeclarationNameInfo DirName;
9733 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9734 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9735 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9736 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9737 return Res;
9738}
9739
9740template <typename Derived>
9741StmtResult
9742TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9743 DeclarationNameInfo DirName;
9744 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9745 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9746 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9747 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9748 return Res;
9749}
9750
9751template <typename Derived>
9752StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9753 OMPInterchangeDirective *D) {
9754 DeclarationNameInfo DirName;
9755 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9756 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9757 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9758 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9759 return Res;
9760}
9761
9762template <typename Derived>
9763StmtResult
9764TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
9765 DeclarationNameInfo DirName;
9766 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9767 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9768 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9769 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9770 return Res;
9771}
9772
9773template <typename Derived>
9774StmtResult
9775TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9776 DeclarationNameInfo DirName;
9777 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9778 OMPD_for, DirName, nullptr, D->getBeginLoc());
9779 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9780 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9781 return Res;
9782}
9783
9784template <typename Derived>
9785StmtResult
9786TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9787 DeclarationNameInfo DirName;
9788 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9789 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9790 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9791 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9792 return Res;
9793}
9794
9795template <typename Derived>
9796StmtResult
9797TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9798 DeclarationNameInfo DirName;
9799 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9800 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9801 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9802 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9803 return Res;
9804}
9805
9806template <typename Derived>
9807StmtResult
9808TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9809 DeclarationNameInfo DirName;
9810 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9811 OMPD_section, DirName, nullptr, D->getBeginLoc());
9812 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9813 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9814 return Res;
9815}
9816
9817template <typename Derived>
9818StmtResult
9819TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9820 DeclarationNameInfo DirName;
9821 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9822 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9823 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9824 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9825 return Res;
9826}
9827
9828template <typename Derived>
9829StmtResult
9830TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9831 DeclarationNameInfo DirName;
9832 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9833 OMPD_single, DirName, nullptr, D->getBeginLoc());
9834 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9835 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9836 return Res;
9837}
9838
9839template <typename Derived>
9840StmtResult
9841TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9842 DeclarationNameInfo DirName;
9843 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9844 OMPD_master, DirName, nullptr, D->getBeginLoc());
9845 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9846 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9847 return Res;
9848}
9849
9850template <typename Derived>
9851StmtResult
9852TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9853 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9854 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9855 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9856 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9857 return Res;
9858}
9859
9860template <typename Derived>
9861StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9862 OMPParallelForDirective *D) {
9863 DeclarationNameInfo DirName;
9864 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9865 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9866 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9867 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9868 return Res;
9869}
9870
9871template <typename Derived>
9872StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9873 OMPParallelForSimdDirective *D) {
9874 DeclarationNameInfo DirName;
9875 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9876 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9877 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9878 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9879 return Res;
9880}
9881
9882template <typename Derived>
9883StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9884 OMPParallelMasterDirective *D) {
9885 DeclarationNameInfo DirName;
9886 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9887 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9888 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9889 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9890 return Res;
9891}
9892
9893template <typename Derived>
9894StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9895 OMPParallelMaskedDirective *D) {
9896 DeclarationNameInfo DirName;
9897 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9898 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9899 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9900 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9901 return Res;
9902}
9903
9904template <typename Derived>
9905StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9906 OMPParallelSectionsDirective *D) {
9907 DeclarationNameInfo DirName;
9908 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9909 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9910 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9911 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9912 return Res;
9913}
9914
9915template <typename Derived>
9916StmtResult
9917TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9918 DeclarationNameInfo DirName;
9919 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9920 OMPD_task, DirName, nullptr, D->getBeginLoc());
9921 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9922 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9923 return Res;
9924}
9925
9926template <typename Derived>
9927StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9928 OMPTaskyieldDirective *D) {
9929 DeclarationNameInfo DirName;
9930 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9931 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9932 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9933 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9934 return Res;
9935}
9936
9937template <typename Derived>
9938StmtResult
9939TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9940 DeclarationNameInfo DirName;
9941 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9942 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9943 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9944 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9945 return Res;
9946}
9947
9948template <typename Derived>
9949StmtResult
9950TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9951 DeclarationNameInfo DirName;
9952 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9953 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9954 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9955 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9956 return Res;
9957}
9958
9959template <typename Derived>
9960StmtResult
9961TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9962 DeclarationNameInfo DirName;
9963 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9964 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9965 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9966 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9967 return Res;
9968}
9969
9970template <typename Derived>
9971StmtResult
9972TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9973 DeclarationNameInfo DirName;
9974 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9975 OMPD_error, DirName, nullptr, D->getBeginLoc());
9976 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9977 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9978 return Res;
9979}
9980
9981template <typename Derived>
9982StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9983 OMPTaskgroupDirective *D) {
9984 DeclarationNameInfo DirName;
9985 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9986 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9987 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9988 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9989 return Res;
9990}
9991
9992template <typename Derived>
9993StmtResult
9994TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9995 DeclarationNameInfo DirName;
9996 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9997 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9998 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9999 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10000 return Res;
10001}
10002
10003template <typename Derived>
10004StmtResult
10005TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10006 DeclarationNameInfo DirName;
10007 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10008 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10009 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10010 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10011 return Res;
10012}
10013
10014template <typename Derived>
10015StmtResult
10016TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10017 DeclarationNameInfo DirName;
10018 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10019 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10020 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10021 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10022 return Res;
10023}
10024
10025template <typename Derived>
10026StmtResult
10027TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
10028 DeclarationNameInfo DirName;
10029 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10030 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
10031 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10032 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10033 return Res;
10034}
10035
10036template <typename Derived>
10037StmtResult
10038TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10039 DeclarationNameInfo DirName;
10040 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10041 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10042 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10043 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10044 return Res;
10045}
10046
10047template <typename Derived>
10048StmtResult
10049TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10050 DeclarationNameInfo DirName;
10051 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10052 OMPD_target, DirName, nullptr, D->getBeginLoc());
10053 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10054 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10055 return Res;
10056}
10057
10058template <typename Derived>
10059StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10060 OMPTargetDataDirective *D) {
10061 DeclarationNameInfo DirName;
10062 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10063 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10064 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10065 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10066 return Res;
10067}
10068
10069template <typename Derived>
10070StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10071 OMPTargetEnterDataDirective *D) {
10072 DeclarationNameInfo DirName;
10073 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10074 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10075 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10076 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10077 return Res;
10078}
10079
10080template <typename Derived>
10081StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10082 OMPTargetExitDataDirective *D) {
10083 DeclarationNameInfo DirName;
10084 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10085 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10086 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10087 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10088 return Res;
10089}
10090
10091template <typename Derived>
10092StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10093 OMPTargetParallelDirective *D) {
10094 DeclarationNameInfo DirName;
10095 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10096 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10097 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10098 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10099 return Res;
10100}
10101
10102template <typename Derived>
10103StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10104 OMPTargetParallelForDirective *D) {
10105 DeclarationNameInfo DirName;
10106 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10107 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10108 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10109 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10110 return Res;
10111}
10112
10113template <typename Derived>
10114StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10115 OMPTargetUpdateDirective *D) {
10116 DeclarationNameInfo DirName;
10117 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10118 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10119 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10120 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10121 return Res;
10122}
10123
10124template <typename Derived>
10125StmtResult
10126TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10127 DeclarationNameInfo DirName;
10128 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10129 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10130 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10131 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10132 return Res;
10133}
10134
10135template <typename Derived>
10136StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10137 OMPCancellationPointDirective *D) {
10138 DeclarationNameInfo DirName;
10139 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10140 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10141 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10142 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10143 return Res;
10144}
10145
10146template <typename Derived>
10147StmtResult
10148TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10149 DeclarationNameInfo DirName;
10150 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10151 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10152 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10153 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10154 return Res;
10155}
10156
10157template <typename Derived>
10158StmtResult
10159TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10160 DeclarationNameInfo DirName;
10161 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10162 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10163 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10164 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10165 return Res;
10166}
10167
10168template <typename Derived>
10169StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10170 OMPTaskLoopSimdDirective *D) {
10171 DeclarationNameInfo DirName;
10172 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10173 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10174 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10175 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10176 return Res;
10177}
10178
10179template <typename Derived>
10180StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10181 OMPMasterTaskLoopDirective *D) {
10182 DeclarationNameInfo DirName;
10183 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10184 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10185 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10186 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10187 return Res;
10188}
10189
10190template <typename Derived>
10191StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10192 OMPMaskedTaskLoopDirective *D) {
10193 DeclarationNameInfo DirName;
10194 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10195 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10196 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10197 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10198 return Res;
10199}
10200
10201template <typename Derived>
10202StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10203 OMPMasterTaskLoopSimdDirective *D) {
10204 DeclarationNameInfo DirName;
10205 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10206 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10207 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10208 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10209 return Res;
10210}
10211
10212template <typename Derived>
10213StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10214 OMPMaskedTaskLoopSimdDirective *D) {
10215 DeclarationNameInfo DirName;
10216 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10217 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10218 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10219 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10220 return Res;
10221}
10222
10223template <typename Derived>
10224StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10225 OMPParallelMasterTaskLoopDirective *D) {
10226 DeclarationNameInfo DirName;
10227 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10228 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10229 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10230 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10231 return Res;
10232}
10233
10234template <typename Derived>
10235StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10236 OMPParallelMaskedTaskLoopDirective *D) {
10237 DeclarationNameInfo DirName;
10238 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10239 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10240 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10241 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10242 return Res;
10243}
10244
10245template <typename Derived>
10246StmtResult
10247TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10248 OMPParallelMasterTaskLoopSimdDirective *D) {
10249 DeclarationNameInfo DirName;
10250 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10251 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10252 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10253 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10254 return Res;
10255}
10256
10257template <typename Derived>
10258StmtResult
10259TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10260 OMPParallelMaskedTaskLoopSimdDirective *D) {
10261 DeclarationNameInfo DirName;
10262 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10263 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10264 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10265 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10266 return Res;
10267}
10268
10269template <typename Derived>
10270StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10271 OMPDistributeDirective *D) {
10272 DeclarationNameInfo DirName;
10273 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10274 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10275 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10276 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10277 return Res;
10278}
10279
10280template <typename Derived>
10281StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10282 OMPDistributeParallelForDirective *D) {
10283 DeclarationNameInfo DirName;
10284 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10285 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10286 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10287 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10288 return Res;
10289}
10290
10291template <typename Derived>
10292StmtResult
10293TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10294 OMPDistributeParallelForSimdDirective *D) {
10295 DeclarationNameInfo DirName;
10296 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10297 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10298 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10299 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10300 return Res;
10301}
10302
10303template <typename Derived>
10304StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10305 OMPDistributeSimdDirective *D) {
10306 DeclarationNameInfo DirName;
10307 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10308 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10309 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10310 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10311 return Res;
10312}
10313
10314template <typename Derived>
10315StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10316 OMPTargetParallelForSimdDirective *D) {
10317 DeclarationNameInfo DirName;
10318 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10319 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10320 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10321 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10322 return Res;
10323}
10324
10325template <typename Derived>
10326StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10327 OMPTargetSimdDirective *D) {
10328 DeclarationNameInfo DirName;
10329 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10330 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10331 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10332 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10333 return Res;
10334}
10335
10336template <typename Derived>
10337StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10338 OMPTeamsDistributeDirective *D) {
10339 DeclarationNameInfo DirName;
10340 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10341 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10342 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10343 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10344 return Res;
10345}
10346
10347template <typename Derived>
10348StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10349 OMPTeamsDistributeSimdDirective *D) {
10350 DeclarationNameInfo DirName;
10351 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10352 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10353 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10354 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10355 return Res;
10356}
10357
10358template <typename Derived>
10359StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10360 OMPTeamsDistributeParallelForSimdDirective *D) {
10361 DeclarationNameInfo DirName;
10362 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10363 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10364 D->getBeginLoc());
10365 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10366 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10367 return Res;
10368}
10369
10370template <typename Derived>
10371StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10372 OMPTeamsDistributeParallelForDirective *D) {
10373 DeclarationNameInfo DirName;
10374 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10375 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10376 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10377 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10378 return Res;
10379}
10380
10381template <typename Derived>
10382StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10383 OMPTargetTeamsDirective *D) {
10384 DeclarationNameInfo DirName;
10385 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10386 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10387 auto Res = getDerived().TransformOMPExecutableDirective(D);
10388 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10389 return Res;
10390}
10391
10392template <typename Derived>
10393StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10394 OMPTargetTeamsDistributeDirective *D) {
10395 DeclarationNameInfo DirName;
10396 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10397 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10398 auto Res = getDerived().TransformOMPExecutableDirective(D);
10399 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10400 return Res;
10401}
10402
10403template <typename Derived>
10404StmtResult
10405TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10406 OMPTargetTeamsDistributeParallelForDirective *D) {
10407 DeclarationNameInfo DirName;
10408 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10409 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10410 D->getBeginLoc());
10411 auto Res = getDerived().TransformOMPExecutableDirective(D);
10412 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10413 return Res;
10414}
10415
10416template <typename Derived>
10417StmtResult TreeTransform<Derived>::
10418 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10419 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10420 DeclarationNameInfo DirName;
10421 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10422 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10423 D->getBeginLoc());
10424 auto Res = getDerived().TransformOMPExecutableDirective(D);
10425 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10426 return Res;
10427}
10428
10429template <typename Derived>
10430StmtResult
10431TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10432 OMPTargetTeamsDistributeSimdDirective *D) {
10433 DeclarationNameInfo DirName;
10434 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10435 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10436 auto Res = getDerived().TransformOMPExecutableDirective(D);
10437 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10438 return Res;
10439}
10440
10441template <typename Derived>
10442StmtResult
10443TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10444 DeclarationNameInfo DirName;
10445 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10446 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10447 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10448 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10449 return Res;
10450}
10451
10452template <typename Derived>
10453StmtResult
10454TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10455 DeclarationNameInfo DirName;
10456 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10457 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10458 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10459 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10460 return Res;
10461}
10462
10463template <typename Derived>
10464StmtResult
10465TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10466 DeclarationNameInfo DirName;
10467 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10468 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10469 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10470 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10471 return Res;
10472}
10473
10474template <typename Derived>
10475StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10476 OMPGenericLoopDirective *D) {
10477 DeclarationNameInfo DirName;
10478 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10479 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10480 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10481 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10482 return Res;
10483}
10484
10485template <typename Derived>
10486StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10487 OMPTeamsGenericLoopDirective *D) {
10488 DeclarationNameInfo DirName;
10489 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10490 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10491 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10492 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10493 return Res;
10494}
10495
10496template <typename Derived>
10497StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10498 OMPTargetTeamsGenericLoopDirective *D) {
10499 DeclarationNameInfo DirName;
10500 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10501 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10502 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10503 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10504 return Res;
10505}
10506
10507template <typename Derived>
10508StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10509 OMPParallelGenericLoopDirective *D) {
10510 DeclarationNameInfo DirName;
10511 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10512 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10513 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10514 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10515 return Res;
10516}
10517
10518template <typename Derived>
10519StmtResult
10520TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10521 OMPTargetParallelGenericLoopDirective *D) {
10522 DeclarationNameInfo DirName;
10523 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10524 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10525 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10526 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10527 return Res;
10528}
10529
10530//===----------------------------------------------------------------------===//
10531// OpenMP clause transformation
10532//===----------------------------------------------------------------------===//
10533template <typename Derived>
10534OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10535 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10536 if (Cond.isInvalid())
10537 return nullptr;
10538 return getDerived().RebuildOMPIfClause(
10539 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10540 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10541}
10542
10543template <typename Derived>
10544OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10545 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10546 if (Cond.isInvalid())
10547 return nullptr;
10548 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10549 C->getLParenLoc(), C->getEndLoc());
10550}
10551
10552template <typename Derived>
10553OMPClause *
10554TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10555 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10556 if (NumThreads.isInvalid())
10557 return nullptr;
10558 return getDerived().RebuildOMPNumThreadsClause(
10559 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10560 C->getModifierLoc(), C->getEndLoc());
10561}
10562
10563template <typename Derived>
10564OMPClause *
10565TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10566 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10567 if (E.isInvalid())
10568 return nullptr;
10569 return getDerived().RebuildOMPSafelenClause(
10570 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10571}
10572
10573template <typename Derived>
10574OMPClause *
10575TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10576 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10577 if (E.isInvalid())
10578 return nullptr;
10579 return getDerived().RebuildOMPAllocatorClause(
10580 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10581}
10582
10583template <typename Derived>
10584OMPClause *
10585TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10586 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10587 if (E.isInvalid())
10588 return nullptr;
10589 return getDerived().RebuildOMPSimdlenClause(
10590 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10591}
10592
10593template <typename Derived>
10594OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10595 SmallVector<Expr *, 4> TransformedSizes;
10596 TransformedSizes.reserve(N: C->getNumSizes());
10597 bool Changed = false;
10598 for (Expr *E : C->getSizesRefs()) {
10599 if (!E) {
10600 TransformedSizes.push_back(Elt: nullptr);
10601 continue;
10602 }
10603
10604 ExprResult T = getDerived().TransformExpr(E);
10605 if (T.isInvalid())
10606 return nullptr;
10607 if (E != T.get())
10608 Changed = true;
10609 TransformedSizes.push_back(Elt: T.get());
10610 }
10611
10612 if (!Changed && !getDerived().AlwaysRebuild())
10613 return C;
10614 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10615 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10616}
10617
10618template <typename Derived>
10619OMPClause *
10620TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10621 SmallVector<Expr *> TransformedArgs;
10622 TransformedArgs.reserve(N: C->getNumLoops());
10623 bool Changed = false;
10624 for (Expr *E : C->getArgsRefs()) {
10625 if (!E) {
10626 TransformedArgs.push_back(Elt: nullptr);
10627 continue;
10628 }
10629
10630 ExprResult T = getDerived().TransformExpr(E);
10631 if (T.isInvalid())
10632 return nullptr;
10633 if (E != T.get())
10634 Changed = true;
10635 TransformedArgs.push_back(Elt: T.get());
10636 }
10637
10638 if (!Changed && !getDerived().AlwaysRebuild())
10639 return C;
10640 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10641 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10642}
10643
10644template <typename Derived>
10645OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10646 if (!getDerived().AlwaysRebuild())
10647 return C;
10648 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10649}
10650
10651template <typename Derived>
10652OMPClause *
10653TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10654 ExprResult T = getDerived().TransformExpr(C->getFactor());
10655 if (T.isInvalid())
10656 return nullptr;
10657 Expr *Factor = T.get();
10658 bool Changed = Factor != C->getFactor();
10659
10660 if (!Changed && !getDerived().AlwaysRebuild())
10661 return C;
10662 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10663 EndLoc: C->getEndLoc());
10664}
10665
10666template <typename Derived>
10667OMPClause *
10668TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
10669 ExprResult F = getDerived().TransformExpr(C->getFirst());
10670 if (F.isInvalid())
10671 return nullptr;
10672
10673 ExprResult Cn = getDerived().TransformExpr(C->getCount());
10674 if (Cn.isInvalid())
10675 return nullptr;
10676
10677 Expr *First = F.get();
10678 Expr *Count = Cn.get();
10679
10680 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
10681
10682 // If no changes and AlwaysRebuild() is false, return the original clause
10683 if (!Changed && !getDerived().AlwaysRebuild())
10684 return C;
10685
10686 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
10687 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
10688 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
10689}
10690
10691template <typename Derived>
10692OMPClause *
10693TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10694 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10695 if (E.isInvalid())
10696 return nullptr;
10697 return getDerived().RebuildOMPCollapseClause(
10698 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10699}
10700
10701template <typename Derived>
10702OMPClause *
10703TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10704 return getDerived().RebuildOMPDefaultClause(
10705 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
10706 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
10707 C->getEndLoc());
10708}
10709
10710template <typename Derived>
10711OMPClause *
10712TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
10713 // No need to rebuild this clause, no template-dependent parameters.
10714 return C;
10715}
10716
10717template <typename Derived>
10718OMPClause *
10719TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
10720 Expr *Impex = C->getImpexType();
10721 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
10722
10723 if (TransformedImpex.isInvalid())
10724 return nullptr;
10725
10726 return getDerived().RebuildOMPTransparentClause(
10727 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
10728 C->getEndLoc());
10729}
10730
10731template <typename Derived>
10732OMPClause *
10733TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10734 return getDerived().RebuildOMPProcBindClause(
10735 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10736 C->getLParenLoc(), C->getEndLoc());
10737}
10738
10739template <typename Derived>
10740OMPClause *
10741TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10742 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10743 if (E.isInvalid())
10744 return nullptr;
10745 return getDerived().RebuildOMPScheduleClause(
10746 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10747 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10748 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10749 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10750}
10751
10752template <typename Derived>
10753OMPClause *
10754TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10755 ExprResult E;
10756 if (auto *Num = C->getNumForLoops()) {
10757 E = getDerived().TransformExpr(Num);
10758 if (E.isInvalid())
10759 return nullptr;
10760 }
10761 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10762 C->getLParenLoc(), E.get());
10763}
10764
10765template <typename Derived>
10766OMPClause *
10767TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10768 ExprResult E;
10769 if (Expr *Evt = C->getEventHandler()) {
10770 E = getDerived().TransformExpr(Evt);
10771 if (E.isInvalid())
10772 return nullptr;
10773 }
10774 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10775 C->getLParenLoc(), C->getEndLoc());
10776}
10777
10778template <typename Derived>
10779OMPClause *
10780TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10781 ExprResult Cond;
10782 if (auto *Condition = C->getCondition()) {
10783 Cond = getDerived().TransformExpr(Condition);
10784 if (Cond.isInvalid())
10785 return nullptr;
10786 }
10787 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
10788 C->getLParenLoc(), C->getEndLoc());
10789}
10790
10791template <typename Derived>
10792OMPClause *
10793TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10794 // No need to rebuild this clause, no template-dependent parameters.
10795 return C;
10796}
10797
10798template <typename Derived>
10799OMPClause *
10800TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10801 // No need to rebuild this clause, no template-dependent parameters.
10802 return C;
10803}
10804
10805template <typename Derived>
10806OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10807 // No need to rebuild this clause, no template-dependent parameters.
10808 return C;
10809}
10810
10811template <typename Derived>
10812OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10813 // No need to rebuild this clause, no template-dependent parameters.
10814 return C;
10815}
10816
10817template <typename Derived>
10818OMPClause *
10819TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10820 // No need to rebuild this clause, no template-dependent parameters.
10821 return C;
10822}
10823
10824template <typename Derived>
10825OMPClause *
10826TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10827 // No need to rebuild this clause, no template-dependent parameters.
10828 return C;
10829}
10830
10831template <typename Derived>
10832OMPClause *
10833TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10834 // No need to rebuild this clause, no template-dependent parameters.
10835 return C;
10836}
10837
10838template <typename Derived>
10839OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10840 // No need to rebuild this clause, no template-dependent parameters.
10841 return C;
10842}
10843
10844template <typename Derived>
10845OMPClause *
10846TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10847 return C;
10848}
10849
10850template <typename Derived>
10851OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10852 ExprResult E = getDerived().TransformExpr(C->getExpr());
10853 if (E.isInvalid())
10854 return nullptr;
10855 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10856 C->getLParenLoc(), C->getEndLoc());
10857}
10858
10859template <typename Derived>
10860OMPClause *
10861TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10862 return C;
10863}
10864
10865template <typename Derived>
10866OMPClause *
10867TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10868 return C;
10869}
10870template <typename Derived>
10871OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10872 OMPNoOpenMPRoutinesClause *C) {
10873 return C;
10874}
10875template <typename Derived>
10876OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10877 OMPNoOpenMPConstructsClause *C) {
10878 return C;
10879}
10880template <typename Derived>
10881OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10882 OMPNoParallelismClause *C) {
10883 return C;
10884}
10885
10886template <typename Derived>
10887OMPClause *
10888TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10889 // No need to rebuild this clause, no template-dependent parameters.
10890 return C;
10891}
10892
10893template <typename Derived>
10894OMPClause *
10895TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10896 // No need to rebuild this clause, no template-dependent parameters.
10897 return C;
10898}
10899
10900template <typename Derived>
10901OMPClause *
10902TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10903 // No need to rebuild this clause, no template-dependent parameters.
10904 return C;
10905}
10906
10907template <typename Derived>
10908OMPClause *
10909TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10910 // No need to rebuild this clause, no template-dependent parameters.
10911 return C;
10912}
10913
10914template <typename Derived>
10915OMPClause *
10916TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10917 // No need to rebuild this clause, no template-dependent parameters.
10918 return C;
10919}
10920
10921template <typename Derived>
10922OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10923 // No need to rebuild this clause, no template-dependent parameters.
10924 return C;
10925}
10926
10927template <typename Derived>
10928OMPClause *
10929TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10930 // No need to rebuild this clause, no template-dependent parameters.
10931 return C;
10932}
10933
10934template <typename Derived>
10935OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10936 // No need to rebuild this clause, no template-dependent parameters.
10937 return C;
10938}
10939
10940template <typename Derived>
10941OMPClause *
10942TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10943 // No need to rebuild this clause, no template-dependent parameters.
10944 return C;
10945}
10946
10947template <typename Derived>
10948OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10949 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10950 if (IVR.isInvalid())
10951 return nullptr;
10952
10953 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10954 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10955 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlist())) {
10956 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10957 if (ER.isInvalid())
10958 return nullptr;
10959 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10960 }
10961 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10962 C->getBeginLoc(), C->getLParenLoc(),
10963 C->getVarLoc(), C->getEndLoc());
10964}
10965
10966template <typename Derived>
10967OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10968 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10969 if (ER.isInvalid())
10970 return nullptr;
10971 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10972 C->getLParenLoc(), C->getVarLoc(),
10973 C->getEndLoc());
10974}
10975
10976template <typename Derived>
10977OMPClause *
10978TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10979 ExprResult ER;
10980 if (Expr *IV = C->getInteropVar()) {
10981 ER = getDerived().TransformExpr(IV);
10982 if (ER.isInvalid())
10983 return nullptr;
10984 }
10985 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10986 C->getLParenLoc(), C->getVarLoc(),
10987 C->getEndLoc());
10988}
10989
10990template <typename Derived>
10991OMPClause *
10992TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10993 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10994 if (Cond.isInvalid())
10995 return nullptr;
10996 return getDerived().RebuildOMPNovariantsClause(
10997 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10998}
10999
11000template <typename Derived>
11001OMPClause *
11002TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11003 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11004 if (Cond.isInvalid())
11005 return nullptr;
11006 return getDerived().RebuildOMPNocontextClause(
11007 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11008}
11009
11010template <typename Derived>
11011OMPClause *
11012TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11013 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11014 if (ThreadID.isInvalid())
11015 return nullptr;
11016 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11017 C->getLParenLoc(), C->getEndLoc());
11018}
11019
11020template <typename Derived>
11021OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11022 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11023 if (E.isInvalid())
11024 return nullptr;
11025 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11026 C->getLParenLoc(), C->getEndLoc());
11027}
11028
11029template <typename Derived>
11030OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11031 OMPUnifiedAddressClause *C) {
11032 llvm_unreachable("unified_address clause cannot appear in dependent context");
11033}
11034
11035template <typename Derived>
11036OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11037 OMPUnifiedSharedMemoryClause *C) {
11038 llvm_unreachable(
11039 "unified_shared_memory clause cannot appear in dependent context");
11040}
11041
11042template <typename Derived>
11043OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11044 OMPReverseOffloadClause *C) {
11045 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11046}
11047
11048template <typename Derived>
11049OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11050 OMPDynamicAllocatorsClause *C) {
11051 llvm_unreachable(
11052 "dynamic_allocators clause cannot appear in dependent context");
11053}
11054
11055template <typename Derived>
11056OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11057 OMPAtomicDefaultMemOrderClause *C) {
11058 llvm_unreachable(
11059 "atomic_default_mem_order clause cannot appear in dependent context");
11060}
11061
11062template <typename Derived>
11063OMPClause *
11064TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11065 llvm_unreachable("self_maps clause cannot appear in dependent context");
11066}
11067
11068template <typename Derived>
11069OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11070 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11071 C->getBeginLoc(), C->getLParenLoc(),
11072 C->getEndLoc());
11073}
11074
11075template <typename Derived>
11076OMPClause *
11077TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11078 return getDerived().RebuildOMPSeverityClause(
11079 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11080 C->getLParenLoc(), C->getEndLoc());
11081}
11082
11083template <typename Derived>
11084OMPClause *
11085TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11086 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11087 if (E.isInvalid())
11088 return nullptr;
11089 return getDerived().RebuildOMPMessageClause(
11090 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11091}
11092
11093template <typename Derived>
11094OMPClause *
11095TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11096 llvm::SmallVector<Expr *, 16> Vars;
11097 Vars.reserve(N: C->varlist_size());
11098 for (auto *VE : C->varlist()) {
11099 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11100 if (EVar.isInvalid())
11101 return nullptr;
11102 Vars.push_back(Elt: EVar.get());
11103 }
11104 return getDerived().RebuildOMPPrivateClause(
11105 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11106}
11107
11108template <typename Derived>
11109OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11110 OMPFirstprivateClause *C) {
11111 llvm::SmallVector<Expr *, 16> Vars;
11112 Vars.reserve(N: C->varlist_size());
11113 for (auto *VE : C->varlist()) {
11114 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11115 if (EVar.isInvalid())
11116 return nullptr;
11117 Vars.push_back(Elt: EVar.get());
11118 }
11119 return getDerived().RebuildOMPFirstprivateClause(
11120 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11121}
11122
11123template <typename Derived>
11124OMPClause *
11125TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11126 llvm::SmallVector<Expr *, 16> Vars;
11127 Vars.reserve(N: C->varlist_size());
11128 for (auto *VE : C->varlist()) {
11129 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11130 if (EVar.isInvalid())
11131 return nullptr;
11132 Vars.push_back(Elt: EVar.get());
11133 }
11134 return getDerived().RebuildOMPLastprivateClause(
11135 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11136 C->getLParenLoc(), C->getEndLoc());
11137}
11138
11139template <typename Derived>
11140OMPClause *
11141TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11142 llvm::SmallVector<Expr *, 16> Vars;
11143 Vars.reserve(N: C->varlist_size());
11144 for (auto *VE : C->varlist()) {
11145 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11146 if (EVar.isInvalid())
11147 return nullptr;
11148 Vars.push_back(Elt: EVar.get());
11149 }
11150 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11151 C->getLParenLoc(), C->getEndLoc());
11152}
11153
11154template <typename Derived>
11155OMPClause *
11156TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11157 llvm::SmallVector<Expr *, 16> Vars;
11158 Vars.reserve(N: C->varlist_size());
11159 for (auto *VE : C->varlist()) {
11160 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11161 if (EVar.isInvalid())
11162 return nullptr;
11163 Vars.push_back(Elt: EVar.get());
11164 }
11165 CXXScopeSpec ReductionIdScopeSpec;
11166 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11167
11168 DeclarationNameInfo NameInfo = C->getNameInfo();
11169 if (NameInfo.getName()) {
11170 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11171 if (!NameInfo.getName())
11172 return nullptr;
11173 }
11174 // Build a list of all UDR decls with the same names ranged by the Scopes.
11175 // The Scope boundary is a duplication of the previous decl.
11176 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11177 for (auto *E : C->reduction_ops()) {
11178 // Transform all the decls.
11179 if (E) {
11180 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11181 UnresolvedSet<8> Decls;
11182 for (auto *D : ULE->decls()) {
11183 NamedDecl *InstD =
11184 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11185 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11186 }
11187 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11188 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11189 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11190 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11191 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11192 } else
11193 UnresolvedReductions.push_back(Elt: nullptr);
11194 }
11195 return getDerived().RebuildOMPReductionClause(
11196 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11197 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11198 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11199}
11200
11201template <typename Derived>
11202OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11203 OMPTaskReductionClause *C) {
11204 llvm::SmallVector<Expr *, 16> Vars;
11205 Vars.reserve(N: C->varlist_size());
11206 for (auto *VE : C->varlist()) {
11207 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11208 if (EVar.isInvalid())
11209 return nullptr;
11210 Vars.push_back(Elt: EVar.get());
11211 }
11212 CXXScopeSpec ReductionIdScopeSpec;
11213 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11214
11215 DeclarationNameInfo NameInfo = C->getNameInfo();
11216 if (NameInfo.getName()) {
11217 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11218 if (!NameInfo.getName())
11219 return nullptr;
11220 }
11221 // Build a list of all UDR decls with the same names ranged by the Scopes.
11222 // The Scope boundary is a duplication of the previous decl.
11223 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11224 for (auto *E : C->reduction_ops()) {
11225 // Transform all the decls.
11226 if (E) {
11227 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11228 UnresolvedSet<8> Decls;
11229 for (auto *D : ULE->decls()) {
11230 NamedDecl *InstD =
11231 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11232 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11233 }
11234 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11235 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11236 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11237 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11238 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11239 } else
11240 UnresolvedReductions.push_back(Elt: nullptr);
11241 }
11242 return getDerived().RebuildOMPTaskReductionClause(
11243 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11244 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11245}
11246
11247template <typename Derived>
11248OMPClause *
11249TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11250 llvm::SmallVector<Expr *, 16> Vars;
11251 Vars.reserve(N: C->varlist_size());
11252 for (auto *VE : C->varlist()) {
11253 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11254 if (EVar.isInvalid())
11255 return nullptr;
11256 Vars.push_back(Elt: EVar.get());
11257 }
11258 CXXScopeSpec ReductionIdScopeSpec;
11259 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11260
11261 DeclarationNameInfo NameInfo = C->getNameInfo();
11262 if (NameInfo.getName()) {
11263 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11264 if (!NameInfo.getName())
11265 return nullptr;
11266 }
11267 // Build a list of all UDR decls with the same names ranged by the Scopes.
11268 // The Scope boundary is a duplication of the previous decl.
11269 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11270 for (auto *E : C->reduction_ops()) {
11271 // Transform all the decls.
11272 if (E) {
11273 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11274 UnresolvedSet<8> Decls;
11275 for (auto *D : ULE->decls()) {
11276 NamedDecl *InstD =
11277 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11278 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11279 }
11280 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11281 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11282 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11283 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11284 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11285 } else
11286 UnresolvedReductions.push_back(Elt: nullptr);
11287 }
11288 return getDerived().RebuildOMPInReductionClause(
11289 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11290 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11291}
11292
11293template <typename Derived>
11294OMPClause *
11295TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *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 Step = getDerived().TransformExpr(C->getStep());
11305 if (Step.isInvalid())
11306 return nullptr;
11307 return getDerived().RebuildOMPLinearClause(
11308 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11309 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11310 C->getEndLoc());
11311}
11312
11313template <typename Derived>
11314OMPClause *
11315TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11316 llvm::SmallVector<Expr *, 16> Vars;
11317 Vars.reserve(N: C->varlist_size());
11318 for (auto *VE : C->varlist()) {
11319 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11320 if (EVar.isInvalid())
11321 return nullptr;
11322 Vars.push_back(Elt: EVar.get());
11323 }
11324 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11325 if (Alignment.isInvalid())
11326 return nullptr;
11327 return getDerived().RebuildOMPAlignedClause(
11328 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11329 C->getColonLoc(), C->getEndLoc());
11330}
11331
11332template <typename Derived>
11333OMPClause *
11334TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11335 llvm::SmallVector<Expr *, 16> Vars;
11336 Vars.reserve(N: C->varlist_size());
11337 for (auto *VE : C->varlist()) {
11338 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11339 if (EVar.isInvalid())
11340 return nullptr;
11341 Vars.push_back(Elt: EVar.get());
11342 }
11343 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11344 C->getLParenLoc(), C->getEndLoc());
11345}
11346
11347template <typename Derived>
11348OMPClause *
11349TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11350 llvm::SmallVector<Expr *, 16> Vars;
11351 Vars.reserve(N: C->varlist_size());
11352 for (auto *VE : C->varlist()) {
11353 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11354 if (EVar.isInvalid())
11355 return nullptr;
11356 Vars.push_back(Elt: EVar.get());
11357 }
11358 return getDerived().RebuildOMPCopyprivateClause(
11359 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11360}
11361
11362template <typename Derived>
11363OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11364 llvm::SmallVector<Expr *, 16> Vars;
11365 Vars.reserve(N: C->varlist_size());
11366 for (auto *VE : C->varlist()) {
11367 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11368 if (EVar.isInvalid())
11369 return nullptr;
11370 Vars.push_back(Elt: EVar.get());
11371 }
11372 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11373 C->getLParenLoc(), C->getEndLoc());
11374}
11375
11376template <typename Derived>
11377OMPClause *
11378TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11379 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11380 if (E.isInvalid())
11381 return nullptr;
11382 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11383 C->getLParenLoc(), C->getEndLoc());
11384}
11385
11386template <typename Derived>
11387OMPClause *
11388TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11389 llvm::SmallVector<Expr *, 16> Vars;
11390 Expr *DepModifier = C->getModifier();
11391 if (DepModifier) {
11392 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11393 if (DepModRes.isInvalid())
11394 return nullptr;
11395 DepModifier = DepModRes.get();
11396 }
11397 Vars.reserve(N: C->varlist_size());
11398 for (auto *VE : C->varlist()) {
11399 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11400 if (EVar.isInvalid())
11401 return nullptr;
11402 Vars.push_back(Elt: EVar.get());
11403 }
11404 return getDerived().RebuildOMPDependClause(
11405 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11406 C->getOmpAllMemoryLoc()},
11407 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11408}
11409
11410template <typename Derived>
11411OMPClause *
11412TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11413 ExprResult E = getDerived().TransformExpr(C->getDevice());
11414 if (E.isInvalid())
11415 return nullptr;
11416 return getDerived().RebuildOMPDeviceClause(
11417 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11418 C->getModifierLoc(), C->getEndLoc());
11419}
11420
11421template <typename Derived, class T>
11422bool transformOMPMappableExprListClause(
11423 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11424 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11425 DeclarationNameInfo &MapperIdInfo,
11426 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11427 // Transform expressions in the list.
11428 Vars.reserve(N: C->varlist_size());
11429 for (auto *VE : C->varlist()) {
11430 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11431 if (EVar.isInvalid())
11432 return true;
11433 Vars.push_back(Elt: EVar.get());
11434 }
11435 // Transform mapper scope specifier and identifier.
11436 NestedNameSpecifierLoc QualifierLoc;
11437 if (C->getMapperQualifierLoc()) {
11438 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11439 C->getMapperQualifierLoc());
11440 if (!QualifierLoc)
11441 return true;
11442 }
11443 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11444 MapperIdInfo = C->getMapperIdInfo();
11445 if (MapperIdInfo.getName()) {
11446 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11447 if (!MapperIdInfo.getName())
11448 return true;
11449 }
11450 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11451 // the previous user-defined mapper lookup in dependent environment.
11452 for (auto *E : C->mapperlists()) {
11453 // Transform all the decls.
11454 if (E) {
11455 auto *ULE = cast<UnresolvedLookupExpr>(E);
11456 UnresolvedSet<8> Decls;
11457 for (auto *D : ULE->decls()) {
11458 NamedDecl *InstD =
11459 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11460 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11461 }
11462 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11463 TT.getSema().Context, /*NamingClass=*/nullptr,
11464 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11465 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11466 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11467 } else {
11468 UnresolvedMappers.push_back(Elt: nullptr);
11469 }
11470 }
11471 return false;
11472}
11473
11474template <typename Derived>
11475OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11476 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11477 llvm::SmallVector<Expr *, 16> Vars;
11478 Expr *IteratorModifier = C->getIteratorModifier();
11479 if (IteratorModifier) {
11480 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11481 if (MapModRes.isInvalid())
11482 return nullptr;
11483 IteratorModifier = MapModRes.get();
11484 }
11485 CXXScopeSpec MapperIdScopeSpec;
11486 DeclarationNameInfo MapperIdInfo;
11487 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11488 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11489 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11490 return nullptr;
11491 return getDerived().RebuildOMPMapClause(
11492 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11493 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11494 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11495}
11496
11497template <typename Derived>
11498OMPClause *
11499TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11500 Expr *Allocator = C->getAllocator();
11501 if (Allocator) {
11502 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11503 if (AllocatorRes.isInvalid())
11504 return nullptr;
11505 Allocator = AllocatorRes.get();
11506 }
11507 Expr *Alignment = C->getAlignment();
11508 if (Alignment) {
11509 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11510 if (AlignmentRes.isInvalid())
11511 return nullptr;
11512 Alignment = AlignmentRes.get();
11513 }
11514 llvm::SmallVector<Expr *, 16> Vars;
11515 Vars.reserve(N: C->varlist_size());
11516 for (auto *VE : C->varlist()) {
11517 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11518 if (EVar.isInvalid())
11519 return nullptr;
11520 Vars.push_back(Elt: EVar.get());
11521 }
11522 return getDerived().RebuildOMPAllocateClause(
11523 Allocator, Alignment, C->getFirstAllocateModifier(),
11524 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11525 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11526 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11527}
11528
11529template <typename Derived>
11530OMPClause *
11531TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11532 llvm::SmallVector<Expr *, 3> Vars;
11533 Vars.reserve(N: C->varlist_size());
11534 for (auto *VE : C->varlist()) {
11535 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11536 if (EVar.isInvalid())
11537 return nullptr;
11538 Vars.push_back(Elt: EVar.get());
11539 }
11540 return getDerived().RebuildOMPNumTeamsClause(
11541 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11542}
11543
11544template <typename Derived>
11545OMPClause *
11546TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11547 llvm::SmallVector<Expr *, 3> Vars;
11548 Vars.reserve(N: C->varlist_size());
11549 for (auto *VE : C->varlist()) {
11550 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11551 if (EVar.isInvalid())
11552 return nullptr;
11553 Vars.push_back(Elt: EVar.get());
11554 }
11555 return getDerived().RebuildOMPThreadLimitClause(
11556 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11557}
11558
11559template <typename Derived>
11560OMPClause *
11561TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11562 ExprResult E = getDerived().TransformExpr(C->getPriority());
11563 if (E.isInvalid())
11564 return nullptr;
11565 return getDerived().RebuildOMPPriorityClause(
11566 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11567}
11568
11569template <typename Derived>
11570OMPClause *
11571TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11572 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11573 if (E.isInvalid())
11574 return nullptr;
11575 return getDerived().RebuildOMPGrainsizeClause(
11576 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11577 C->getModifierLoc(), C->getEndLoc());
11578}
11579
11580template <typename Derived>
11581OMPClause *
11582TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11583 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11584 if (E.isInvalid())
11585 return nullptr;
11586 return getDerived().RebuildOMPNumTasksClause(
11587 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11588 C->getModifierLoc(), C->getEndLoc());
11589}
11590
11591template <typename Derived>
11592OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11593 ExprResult E = getDerived().TransformExpr(C->getHint());
11594 if (E.isInvalid())
11595 return nullptr;
11596 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11597 C->getLParenLoc(), C->getEndLoc());
11598}
11599
11600template <typename Derived>
11601OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11602 OMPDistScheduleClause *C) {
11603 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11604 if (E.isInvalid())
11605 return nullptr;
11606 return getDerived().RebuildOMPDistScheduleClause(
11607 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11608 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11609}
11610
11611template <typename Derived>
11612OMPClause *
11613TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11614 // Rebuild Defaultmap Clause since we need to invoke the checking of
11615 // defaultmap(none:variable-category) after template initialization.
11616 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11617 C->getDefaultmapKind(),
11618 C->getBeginLoc(),
11619 C->getLParenLoc(),
11620 C->getDefaultmapModifierLoc(),
11621 C->getDefaultmapKindLoc(),
11622 C->getEndLoc());
11623}
11624
11625template <typename Derived>
11626OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11627 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11628 llvm::SmallVector<Expr *, 16> Vars;
11629 Expr *IteratorModifier = C->getIteratorModifier();
11630 if (IteratorModifier) {
11631 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11632 if (MapModRes.isInvalid())
11633 return nullptr;
11634 IteratorModifier = MapModRes.get();
11635 }
11636 CXXScopeSpec MapperIdScopeSpec;
11637 DeclarationNameInfo MapperIdInfo;
11638 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11639 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11640 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11641 return nullptr;
11642 return getDerived().RebuildOMPToClause(
11643 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11644 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11645 UnresolvedMappers);
11646}
11647
11648template <typename Derived>
11649OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11650 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11651 llvm::SmallVector<Expr *, 16> Vars;
11652 Expr *IteratorModifier = C->getIteratorModifier();
11653 if (IteratorModifier) {
11654 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11655 if (MapModRes.isInvalid())
11656 return nullptr;
11657 IteratorModifier = MapModRes.get();
11658 }
11659 CXXScopeSpec MapperIdScopeSpec;
11660 DeclarationNameInfo MapperIdInfo;
11661 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11662 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11663 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11664 return nullptr;
11665 return getDerived().RebuildOMPFromClause(
11666 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11667 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11668 UnresolvedMappers);
11669}
11670
11671template <typename Derived>
11672OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11673 OMPUseDevicePtrClause *C) {
11674 llvm::SmallVector<Expr *, 16> Vars;
11675 Vars.reserve(N: C->varlist_size());
11676 for (auto *VE : C->varlist()) {
11677 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11678 if (EVar.isInvalid())
11679 return nullptr;
11680 Vars.push_back(Elt: EVar.get());
11681 }
11682 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11683 return getDerived().RebuildOMPUseDevicePtrClause(
11684 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
11685}
11686
11687template <typename Derived>
11688OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11689 OMPUseDeviceAddrClause *C) {
11690 llvm::SmallVector<Expr *, 16> Vars;
11691 Vars.reserve(N: C->varlist_size());
11692 for (auto *VE : C->varlist()) {
11693 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11694 if (EVar.isInvalid())
11695 return nullptr;
11696 Vars.push_back(Elt: EVar.get());
11697 }
11698 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11699 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11700}
11701
11702template <typename Derived>
11703OMPClause *
11704TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11705 llvm::SmallVector<Expr *, 16> Vars;
11706 Vars.reserve(N: C->varlist_size());
11707 for (auto *VE : C->varlist()) {
11708 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11709 if (EVar.isInvalid())
11710 return nullptr;
11711 Vars.push_back(Elt: EVar.get());
11712 }
11713 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11714 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11715}
11716
11717template <typename Derived>
11718OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11719 OMPHasDeviceAddrClause *C) {
11720 llvm::SmallVector<Expr *, 16> Vars;
11721 Vars.reserve(N: C->varlist_size());
11722 for (auto *VE : C->varlist()) {
11723 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11724 if (EVar.isInvalid())
11725 return nullptr;
11726 Vars.push_back(Elt: EVar.get());
11727 }
11728 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11729 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11730}
11731
11732template <typename Derived>
11733OMPClause *
11734TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11735 llvm::SmallVector<Expr *, 16> Vars;
11736 Vars.reserve(N: C->varlist_size());
11737 for (auto *VE : C->varlist()) {
11738 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11739 if (EVar.isInvalid())
11740 return nullptr;
11741 Vars.push_back(Elt: EVar.get());
11742 }
11743 return getDerived().RebuildOMPNontemporalClause(
11744 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11745}
11746
11747template <typename Derived>
11748OMPClause *
11749TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11750 llvm::SmallVector<Expr *, 16> Vars;
11751 Vars.reserve(N: C->varlist_size());
11752 for (auto *VE : C->varlist()) {
11753 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11754 if (EVar.isInvalid())
11755 return nullptr;
11756 Vars.push_back(Elt: EVar.get());
11757 }
11758 return getDerived().RebuildOMPInclusiveClause(
11759 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11760}
11761
11762template <typename Derived>
11763OMPClause *
11764TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11765 llvm::SmallVector<Expr *, 16> Vars;
11766 Vars.reserve(N: C->varlist_size());
11767 for (auto *VE : C->varlist()) {
11768 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11769 if (EVar.isInvalid())
11770 return nullptr;
11771 Vars.push_back(Elt: EVar.get());
11772 }
11773 return getDerived().RebuildOMPExclusiveClause(
11774 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11775}
11776
11777template <typename Derived>
11778OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11779 OMPUsesAllocatorsClause *C) {
11780 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11781 Data.reserve(N: C->getNumberOfAllocators());
11782 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11783 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11784 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11785 if (Allocator.isInvalid())
11786 continue;
11787 ExprResult AllocatorTraits;
11788 if (Expr *AT = D.AllocatorTraits) {
11789 AllocatorTraits = getDerived().TransformExpr(AT);
11790 if (AllocatorTraits.isInvalid())
11791 continue;
11792 }
11793 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11794 NewD.Allocator = Allocator.get();
11795 NewD.AllocatorTraits = AllocatorTraits.get();
11796 NewD.LParenLoc = D.LParenLoc;
11797 NewD.RParenLoc = D.RParenLoc;
11798 }
11799 return getDerived().RebuildOMPUsesAllocatorsClause(
11800 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11801}
11802
11803template <typename Derived>
11804OMPClause *
11805TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11806 SmallVector<Expr *, 4> Locators;
11807 Locators.reserve(N: C->varlist_size());
11808 ExprResult ModifierRes;
11809 if (Expr *Modifier = C->getModifier()) {
11810 ModifierRes = getDerived().TransformExpr(Modifier);
11811 if (ModifierRes.isInvalid())
11812 return nullptr;
11813 }
11814 for (Expr *E : C->varlist()) {
11815 ExprResult Locator = getDerived().TransformExpr(E);
11816 if (Locator.isInvalid())
11817 continue;
11818 Locators.push_back(Elt: Locator.get());
11819 }
11820 return getDerived().RebuildOMPAffinityClause(
11821 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11822 ModifierRes.get(), Locators);
11823}
11824
11825template <typename Derived>
11826OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11827 return getDerived().RebuildOMPOrderClause(
11828 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11829 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11830}
11831
11832template <typename Derived>
11833OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11834 return getDerived().RebuildOMPBindClause(
11835 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11836 C->getLParenLoc(), C->getEndLoc());
11837}
11838
11839template <typename Derived>
11840OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11841 OMPXDynCGroupMemClause *C) {
11842 ExprResult Size = getDerived().TransformExpr(C->getSize());
11843 if (Size.isInvalid())
11844 return nullptr;
11845 return getDerived().RebuildOMPXDynCGroupMemClause(
11846 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11847}
11848
11849template <typename Derived>
11850OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
11851 OMPDynGroupprivateClause *C) {
11852 ExprResult Size = getDerived().TransformExpr(C->getSize());
11853 if (Size.isInvalid())
11854 return nullptr;
11855 return getDerived().RebuildOMPDynGroupprivateClause(
11856 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
11857 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
11858 C->getDynGroupprivateModifierLoc(),
11859 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
11860}
11861
11862template <typename Derived>
11863OMPClause *
11864TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11865 llvm::SmallVector<Expr *, 16> Vars;
11866 Vars.reserve(N: C->varlist_size());
11867 for (auto *VE : C->varlist()) {
11868 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11869 if (EVar.isInvalid())
11870 return nullptr;
11871 Vars.push_back(Elt: EVar.get());
11872 }
11873 return getDerived().RebuildOMPDoacrossClause(
11874 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11875 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11876}
11877
11878template <typename Derived>
11879OMPClause *
11880TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11881 SmallVector<const Attr *> NewAttrs;
11882 for (auto *A : C->getAttrs())
11883 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11884 return getDerived().RebuildOMPXAttributeClause(
11885 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11886}
11887
11888template <typename Derived>
11889OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11890 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11891}
11892
11893//===----------------------------------------------------------------------===//
11894// OpenACC transformation
11895//===----------------------------------------------------------------------===//
11896namespace {
11897template <typename Derived>
11898class OpenACCClauseTransform final
11899 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11900 TreeTransform<Derived> &Self;
11901 ArrayRef<const OpenACCClause *> ExistingClauses;
11902 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11903 OpenACCClause *NewClause = nullptr;
11904
11905 ExprResult VisitVar(Expr *VarRef) {
11906 ExprResult Res = Self.TransformExpr(VarRef);
11907
11908 if (!Res.isUsable())
11909 return Res;
11910
11911 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11912 ParsedClause.getClauseKind(),
11913 Res.get());
11914
11915 return Res;
11916 }
11917
11918 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11919 llvm::SmallVector<Expr *> InstantiatedVarList;
11920 for (Expr *CurVar : VarList) {
11921 ExprResult VarRef = VisitVar(VarRef: CurVar);
11922
11923 if (VarRef.isUsable())
11924 InstantiatedVarList.push_back(Elt: VarRef.get());
11925 }
11926
11927 return InstantiatedVarList;
11928 }
11929
11930public:
11931 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11932 ArrayRef<const OpenACCClause *> ExistingClauses,
11933 SemaOpenACC::OpenACCParsedClause &PC)
11934 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11935
11936 OpenACCClause *CreatedClause() const { return NewClause; }
11937
11938#define VISIT_CLAUSE(CLAUSE_NAME) \
11939 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11940#include "clang/Basic/OpenACCClauses.def"
11941};
11942
11943template <typename Derived>
11944void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11945 const OpenACCDefaultClause &C) {
11946 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11947
11948 NewClause = OpenACCDefaultClause::Create(
11949 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11950 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11951 EndLoc: ParsedClause.getEndLoc());
11952}
11953
11954template <typename Derived>
11955void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11956 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11957 assert(Cond && "If constructed with invalid Condition");
11958 Sema::ConditionResult Res = Self.TransformCondition(
11959 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11960
11961 if (Res.isInvalid() || !Res.get().second)
11962 return;
11963
11964 ParsedClause.setConditionDetails(Res.get().second);
11965
11966 NewClause = OpenACCIfClause::Create(
11967 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11968 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11969 EndLoc: ParsedClause.getEndLoc());
11970}
11971
11972template <typename Derived>
11973void OpenACCClauseTransform<Derived>::VisitSelfClause(
11974 const OpenACCSelfClause &C) {
11975
11976 // If this is an 'update' 'self' clause, this is actually a var list instead.
11977 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11978 llvm::SmallVector<Expr *> InstantiatedVarList;
11979 for (Expr *CurVar : C.getVarList()) {
11980 ExprResult Res = Self.TransformExpr(CurVar);
11981
11982 if (!Res.isUsable())
11983 continue;
11984
11985 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11986 ParsedClause.getClauseKind(),
11987 Res.get());
11988
11989 if (Res.isUsable())
11990 InstantiatedVarList.push_back(Elt: Res.get());
11991 }
11992
11993 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
11994 ModKind: OpenACCModifierKind::Invalid);
11995
11996 NewClause = OpenACCSelfClause::Create(
11997 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11998 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11999 ParsedClause.getEndLoc());
12000 } else {
12001
12002 if (C.hasConditionExpr()) {
12003 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12004 Sema::ConditionResult Res =
12005 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12006 Sema::ConditionKind::Boolean);
12007
12008 if (Res.isInvalid() || !Res.get().second)
12009 return;
12010
12011 ParsedClause.setConditionDetails(Res.get().second);
12012 }
12013
12014 NewClause = OpenACCSelfClause::Create(
12015 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12016 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12017 ParsedClause.getEndLoc());
12018 }
12019}
12020
12021template <typename Derived>
12022void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12023 const OpenACCNumGangsClause &C) {
12024 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12025
12026 for (Expr *CurIntExpr : C.getIntExprs()) {
12027 ExprResult Res = Self.TransformExpr(CurIntExpr);
12028
12029 if (!Res.isUsable())
12030 return;
12031
12032 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12033 C.getClauseKind(),
12034 C.getBeginLoc(), Res.get());
12035 if (!Res.isUsable())
12036 return;
12037
12038 InstantiatedIntExprs.push_back(Elt: Res.get());
12039 }
12040
12041 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12042 NewClause = OpenACCNumGangsClause::Create(
12043 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12044 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12045 EndLoc: ParsedClause.getEndLoc());
12046}
12047
12048template <typename Derived>
12049void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12050 const OpenACCPrivateClause &C) {
12051 llvm::SmallVector<Expr *> InstantiatedVarList;
12052 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12053
12054 for (const auto [RefExpr, InitRecipe] :
12055 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12056 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12057
12058 if (VarRef.isUsable()) {
12059 InstantiatedVarList.push_back(Elt: VarRef.get());
12060
12061 // We only have to create a new one if it is dependent, and Sema won't
12062 // make one of these unless the type is non-dependent.
12063 if (InitRecipe.isSet())
12064 InitRecipes.push_back(Elt: InitRecipe);
12065 else
12066 InitRecipes.push_back(
12067 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12068 }
12069 }
12070 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12071 ModKind: OpenACCModifierKind::Invalid);
12072
12073 NewClause = OpenACCPrivateClause::Create(
12074 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12075 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12076 EndLoc: ParsedClause.getEndLoc());
12077}
12078
12079template <typename Derived>
12080void OpenACCClauseTransform<Derived>::VisitHostClause(
12081 const OpenACCHostClause &C) {
12082 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12083 OpenACCModifierKind::Invalid);
12084
12085 NewClause = OpenACCHostClause::Create(
12086 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12087 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12088 EndLoc: ParsedClause.getEndLoc());
12089}
12090
12091template <typename Derived>
12092void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12093 const OpenACCDeviceClause &C) {
12094 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12095 OpenACCModifierKind::Invalid);
12096
12097 NewClause = OpenACCDeviceClause::Create(
12098 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12099 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12100 EndLoc: ParsedClause.getEndLoc());
12101}
12102
12103template <typename Derived>
12104void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12105 const OpenACCFirstPrivateClause &C) {
12106 llvm::SmallVector<Expr *> InstantiatedVarList;
12107 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12108
12109 for (const auto [RefExpr, InitRecipe] :
12110 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12111 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12112
12113 if (VarRef.isUsable()) {
12114 InstantiatedVarList.push_back(Elt: VarRef.get());
12115
12116 // We only have to create a new one if it is dependent, and Sema won't
12117 // make one of these unless the type is non-dependent.
12118 if (InitRecipe.isSet())
12119 InitRecipes.push_back(Elt: InitRecipe);
12120 else
12121 InitRecipes.push_back(
12122 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12123 VarRef.get()));
12124 }
12125 }
12126 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12127 ModKind: OpenACCModifierKind::Invalid);
12128
12129 NewClause = OpenACCFirstPrivateClause::Create(
12130 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12131 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12132 EndLoc: ParsedClause.getEndLoc());
12133}
12134
12135template <typename Derived>
12136void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12137 const OpenACCNoCreateClause &C) {
12138 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12139 OpenACCModifierKind::Invalid);
12140
12141 NewClause = OpenACCNoCreateClause::Create(
12142 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12143 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12144 EndLoc: ParsedClause.getEndLoc());
12145}
12146
12147template <typename Derived>
12148void OpenACCClauseTransform<Derived>::VisitPresentClause(
12149 const OpenACCPresentClause &C) {
12150 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12151 OpenACCModifierKind::Invalid);
12152
12153 NewClause = OpenACCPresentClause::Create(
12154 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12155 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12156 EndLoc: ParsedClause.getEndLoc());
12157}
12158
12159template <typename Derived>
12160void OpenACCClauseTransform<Derived>::VisitCopyClause(
12161 const OpenACCCopyClause &C) {
12162 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12163 C.getModifierList());
12164
12165 NewClause = OpenACCCopyClause::Create(
12166 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12167 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12168 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12169 EndLoc: ParsedClause.getEndLoc());
12170}
12171
12172template <typename Derived>
12173void OpenACCClauseTransform<Derived>::VisitLinkClause(
12174 const OpenACCLinkClause &C) {
12175 llvm_unreachable("link clause not valid unless a decl transform");
12176}
12177
12178template <typename Derived>
12179void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12180 const OpenACCDeviceResidentClause &C) {
12181 llvm_unreachable("device_resident clause not valid unless a decl transform");
12182}
12183template <typename Derived>
12184void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12185 const OpenACCNoHostClause &C) {
12186 llvm_unreachable("nohost clause not valid unless a decl transform");
12187}
12188template <typename Derived>
12189void OpenACCClauseTransform<Derived>::VisitBindClause(
12190 const OpenACCBindClause &C) {
12191 llvm_unreachable("bind clause not valid unless a decl transform");
12192}
12193
12194template <typename Derived>
12195void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12196 const OpenACCCopyInClause &C) {
12197 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12198 C.getModifierList());
12199
12200 NewClause = OpenACCCopyInClause::Create(
12201 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12202 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12203 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12204 EndLoc: ParsedClause.getEndLoc());
12205}
12206
12207template <typename Derived>
12208void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12209 const OpenACCCopyOutClause &C) {
12210 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12211 C.getModifierList());
12212
12213 NewClause = OpenACCCopyOutClause::Create(
12214 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12215 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12216 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12217 EndLoc: ParsedClause.getEndLoc());
12218}
12219
12220template <typename Derived>
12221void OpenACCClauseTransform<Derived>::VisitCreateClause(
12222 const OpenACCCreateClause &C) {
12223 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12224 C.getModifierList());
12225
12226 NewClause = OpenACCCreateClause::Create(
12227 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12228 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12229 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12230 EndLoc: ParsedClause.getEndLoc());
12231}
12232template <typename Derived>
12233void OpenACCClauseTransform<Derived>::VisitAttachClause(
12234 const OpenACCAttachClause &C) {
12235 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12236
12237 // Ensure each var is a pointer type.
12238 llvm::erase_if(VarList, [&](Expr *E) {
12239 return Self.getSema().OpenACC().CheckVarIsPointerType(
12240 OpenACCClauseKind::Attach, E);
12241 });
12242
12243 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12244 NewClause = OpenACCAttachClause::Create(
12245 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12246 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12247 EndLoc: ParsedClause.getEndLoc());
12248}
12249
12250template <typename Derived>
12251void OpenACCClauseTransform<Derived>::VisitDetachClause(
12252 const OpenACCDetachClause &C) {
12253 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12254
12255 // Ensure each var is a pointer type.
12256 llvm::erase_if(VarList, [&](Expr *E) {
12257 return Self.getSema().OpenACC().CheckVarIsPointerType(
12258 OpenACCClauseKind::Detach, E);
12259 });
12260
12261 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12262 NewClause = OpenACCDetachClause::Create(
12263 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12264 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12265 EndLoc: ParsedClause.getEndLoc());
12266}
12267
12268template <typename Derived>
12269void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12270 const OpenACCDeleteClause &C) {
12271 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12272 OpenACCModifierKind::Invalid);
12273 NewClause = OpenACCDeleteClause::Create(
12274 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12275 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12276 EndLoc: ParsedClause.getEndLoc());
12277}
12278
12279template <typename Derived>
12280void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12281 const OpenACCUseDeviceClause &C) {
12282 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12283 OpenACCModifierKind::Invalid);
12284 NewClause = OpenACCUseDeviceClause::Create(
12285 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12286 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12287 EndLoc: ParsedClause.getEndLoc());
12288}
12289
12290template <typename Derived>
12291void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12292 const OpenACCDevicePtrClause &C) {
12293 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12294
12295 // Ensure each var is a pointer type.
12296 llvm::erase_if(VarList, [&](Expr *E) {
12297 return Self.getSema().OpenACC().CheckVarIsPointerType(
12298 OpenACCClauseKind::DevicePtr, E);
12299 });
12300
12301 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12302 NewClause = OpenACCDevicePtrClause::Create(
12303 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12304 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12305 EndLoc: ParsedClause.getEndLoc());
12306}
12307
12308template <typename Derived>
12309void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12310 const OpenACCNumWorkersClause &C) {
12311 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12312 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12313
12314 ExprResult Res = Self.TransformExpr(IntExpr);
12315 if (!Res.isUsable())
12316 return;
12317
12318 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12319 C.getClauseKind(),
12320 C.getBeginLoc(), Res.get());
12321 if (!Res.isUsable())
12322 return;
12323
12324 ParsedClause.setIntExprDetails(Res.get());
12325 NewClause = OpenACCNumWorkersClause::Create(
12326 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12327 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12328 EndLoc: ParsedClause.getEndLoc());
12329}
12330
12331template <typename Derived>
12332void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12333 const OpenACCDeviceNumClause &C) {
12334 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12335 assert(IntExpr && "device_num clause constructed with invalid int expr");
12336
12337 ExprResult Res = Self.TransformExpr(IntExpr);
12338 if (!Res.isUsable())
12339 return;
12340
12341 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12342 C.getClauseKind(),
12343 C.getBeginLoc(), Res.get());
12344 if (!Res.isUsable())
12345 return;
12346
12347 ParsedClause.setIntExprDetails(Res.get());
12348 NewClause = OpenACCDeviceNumClause::Create(
12349 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12350 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12351 EndLoc: ParsedClause.getEndLoc());
12352}
12353
12354template <typename Derived>
12355void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12356 const OpenACCDefaultAsyncClause &C) {
12357 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12358 assert(IntExpr && "default_async clause constructed with invalid int expr");
12359
12360 ExprResult Res = Self.TransformExpr(IntExpr);
12361 if (!Res.isUsable())
12362 return;
12363
12364 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12365 C.getClauseKind(),
12366 C.getBeginLoc(), Res.get());
12367 if (!Res.isUsable())
12368 return;
12369
12370 ParsedClause.setIntExprDetails(Res.get());
12371 NewClause = OpenACCDefaultAsyncClause::Create(
12372 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12373 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12374 EndLoc: ParsedClause.getEndLoc());
12375}
12376
12377template <typename Derived>
12378void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12379 const OpenACCVectorLengthClause &C) {
12380 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12381 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12382
12383 ExprResult Res = Self.TransformExpr(IntExpr);
12384 if (!Res.isUsable())
12385 return;
12386
12387 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12388 C.getClauseKind(),
12389 C.getBeginLoc(), Res.get());
12390 if (!Res.isUsable())
12391 return;
12392
12393 ParsedClause.setIntExprDetails(Res.get());
12394 NewClause = OpenACCVectorLengthClause::Create(
12395 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12396 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12397 EndLoc: ParsedClause.getEndLoc());
12398}
12399
12400template <typename Derived>
12401void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12402 const OpenACCAsyncClause &C) {
12403 if (C.hasIntExpr()) {
12404 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12405 if (!Res.isUsable())
12406 return;
12407
12408 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12409 C.getClauseKind(),
12410 C.getBeginLoc(), Res.get());
12411 if (!Res.isUsable())
12412 return;
12413 ParsedClause.setIntExprDetails(Res.get());
12414 }
12415
12416 NewClause = OpenACCAsyncClause::Create(
12417 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12418 LParenLoc: ParsedClause.getLParenLoc(),
12419 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12420 : nullptr,
12421 EndLoc: ParsedClause.getEndLoc());
12422}
12423
12424template <typename Derived>
12425void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12426 const OpenACCWorkerClause &C) {
12427 if (C.hasIntExpr()) {
12428 // restrictions on this expression are all "does it exist in certain
12429 // situations" that are not possible to be dependent, so the only check we
12430 // have is that it transforms, and is an int expression.
12431 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12432 if (!Res.isUsable())
12433 return;
12434
12435 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12436 C.getClauseKind(),
12437 C.getBeginLoc(), Res.get());
12438 if (!Res.isUsable())
12439 return;
12440 ParsedClause.setIntExprDetails(Res.get());
12441 }
12442
12443 NewClause = OpenACCWorkerClause::Create(
12444 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12445 LParenLoc: ParsedClause.getLParenLoc(),
12446 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12447 : nullptr,
12448 EndLoc: ParsedClause.getEndLoc());
12449}
12450
12451template <typename Derived>
12452void OpenACCClauseTransform<Derived>::VisitVectorClause(
12453 const OpenACCVectorClause &C) {
12454 if (C.hasIntExpr()) {
12455 // restrictions on this expression are all "does it exist in certain
12456 // situations" that are not possible to be dependent, so the only check we
12457 // have is that it transforms, and is an int expression.
12458 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12459 if (!Res.isUsable())
12460 return;
12461
12462 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12463 C.getClauseKind(),
12464 C.getBeginLoc(), Res.get());
12465 if (!Res.isUsable())
12466 return;
12467 ParsedClause.setIntExprDetails(Res.get());
12468 }
12469
12470 NewClause = OpenACCVectorClause::Create(
12471 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12472 LParenLoc: ParsedClause.getLParenLoc(),
12473 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12474 : nullptr,
12475 EndLoc: ParsedClause.getEndLoc());
12476}
12477
12478template <typename Derived>
12479void OpenACCClauseTransform<Derived>::VisitWaitClause(
12480 const OpenACCWaitClause &C) {
12481 if (C.hasExprs()) {
12482 Expr *DevNumExpr = nullptr;
12483 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12484
12485 // Instantiate devnum expr if it exists.
12486 if (C.getDevNumExpr()) {
12487 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12488 if (!Res.isUsable())
12489 return;
12490 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12491 C.getClauseKind(),
12492 C.getBeginLoc(), Res.get());
12493 if (!Res.isUsable())
12494 return;
12495
12496 DevNumExpr = Res.get();
12497 }
12498
12499 // Instantiate queue ids.
12500 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12501 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12502 if (!Res.isUsable())
12503 return;
12504 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12505 C.getClauseKind(),
12506 C.getBeginLoc(), Res.get());
12507 if (!Res.isUsable())
12508 return;
12509
12510 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12511 }
12512
12513 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12514 IntExprs: std::move(InstantiatedQueueIdExprs));
12515 }
12516
12517 NewClause = OpenACCWaitClause::Create(
12518 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12519 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12520 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12521 EndLoc: ParsedClause.getEndLoc());
12522}
12523
12524template <typename Derived>
12525void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12526 const OpenACCDeviceTypeClause &C) {
12527 // Nothing to transform here, just create a new version of 'C'.
12528 NewClause = OpenACCDeviceTypeClause::Create(
12529 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12530 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12531 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12532}
12533
12534template <typename Derived>
12535void OpenACCClauseTransform<Derived>::VisitAutoClause(
12536 const OpenACCAutoClause &C) {
12537 // Nothing to do, so just create a new node.
12538 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12539 BeginLoc: ParsedClause.getBeginLoc(),
12540 EndLoc: ParsedClause.getEndLoc());
12541}
12542
12543template <typename Derived>
12544void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12545 const OpenACCIndependentClause &C) {
12546 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12547 BeginLoc: ParsedClause.getBeginLoc(),
12548 EndLoc: ParsedClause.getEndLoc());
12549}
12550
12551template <typename Derived>
12552void OpenACCClauseTransform<Derived>::VisitSeqClause(
12553 const OpenACCSeqClause &C) {
12554 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12555 BeginLoc: ParsedClause.getBeginLoc(),
12556 EndLoc: ParsedClause.getEndLoc());
12557}
12558template <typename Derived>
12559void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12560 const OpenACCFinalizeClause &C) {
12561 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12562 BeginLoc: ParsedClause.getBeginLoc(),
12563 EndLoc: ParsedClause.getEndLoc());
12564}
12565
12566template <typename Derived>
12567void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12568 const OpenACCIfPresentClause &C) {
12569 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12570 BeginLoc: ParsedClause.getBeginLoc(),
12571 EndLoc: ParsedClause.getEndLoc());
12572}
12573
12574template <typename Derived>
12575void OpenACCClauseTransform<Derived>::VisitReductionClause(
12576 const OpenACCReductionClause &C) {
12577 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12578 SmallVector<Expr *> ValidVars;
12579 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
12580
12581 for (const auto [Var, OrigRecipe] :
12582 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
12583 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12584 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12585 if (Res.isUsable()) {
12586 ValidVars.push_back(Elt: Res.get());
12587
12588 if (OrigRecipe.isSet())
12589 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
12590 else
12591 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
12592 C.getReductionOp(), Res.get()));
12593 }
12594 }
12595
12596 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12597 ExistingClauses, ParsedClause.getDirectiveKind(),
12598 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12599 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
12600}
12601
12602template <typename Derived>
12603void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12604 const OpenACCCollapseClause &C) {
12605 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12606 assert(LoopCount && "collapse clause constructed with invalid loop count");
12607
12608 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12609
12610 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12611 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12612 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12613
12614 NewLoopCount =
12615 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12616
12617 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12618 NewClause = OpenACCCollapseClause::Create(
12619 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12620 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12621 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12622}
12623
12624template <typename Derived>
12625void OpenACCClauseTransform<Derived>::VisitTileClause(
12626 const OpenACCTileClause &C) {
12627
12628 llvm::SmallVector<Expr *> TransformedExprs;
12629
12630 for (Expr *E : C.getSizeExprs()) {
12631 ExprResult NewSizeExpr = Self.TransformExpr(E);
12632
12633 if (!NewSizeExpr.isUsable())
12634 return;
12635
12636 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12637 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12638 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12639
12640 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12641
12642 if (!NewSizeExpr.isUsable())
12643 return;
12644 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12645 }
12646
12647 ParsedClause.setIntExprDetails(TransformedExprs);
12648 NewClause = OpenACCTileClause::Create(
12649 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12650 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12651 EndLoc: ParsedClause.getEndLoc());
12652}
12653template <typename Derived>
12654void OpenACCClauseTransform<Derived>::VisitGangClause(
12655 const OpenACCGangClause &C) {
12656 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12657 llvm::SmallVector<Expr *> TransformedIntExprs;
12658
12659 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12660 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12661 if (!ER.isUsable())
12662 continue;
12663
12664 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12665 ParsedClause.getDirectiveKind(),
12666 C.getExpr(I).first, ER.get());
12667 if (!ER.isUsable())
12668 continue;
12669 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12670 TransformedIntExprs.push_back(Elt: ER.get());
12671 }
12672
12673 NewClause = Self.getSema().OpenACC().CheckGangClause(
12674 ParsedClause.getDirectiveKind(), ExistingClauses,
12675 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12676 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12677}
12678} // namespace
12679template <typename Derived>
12680OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12681 ArrayRef<const OpenACCClause *> ExistingClauses,
12682 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12683
12684 SemaOpenACC::OpenACCParsedClause ParsedClause(
12685 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12686 ParsedClause.setEndLoc(OldClause->getEndLoc());
12687
12688 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12689 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12690
12691 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12692 ParsedClause};
12693 Transform.Visit(OldClause);
12694
12695 return Transform.CreatedClause();
12696}
12697
12698template <typename Derived>
12699llvm::SmallVector<OpenACCClause *>
12700TreeTransform<Derived>::TransformOpenACCClauseList(
12701 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12702 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12703 for (const auto *Clause : OldClauses) {
12704 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12705 TransformedClauses, DirKind, Clause))
12706 TransformedClauses.push_back(Elt: TransformedClause);
12707 }
12708 return TransformedClauses;
12709}
12710
12711template <typename Derived>
12712StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12713 OpenACCComputeConstruct *C) {
12714 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12715
12716 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12717 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12718 C->clauses());
12719
12720 if (getSema().OpenACC().ActOnStartStmtDirective(
12721 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12722 return StmtError();
12723
12724 // Transform Structured Block.
12725 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12726 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12727 C->clauses(), TransformedClauses);
12728 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12729 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12730 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12731
12732 return getDerived().RebuildOpenACCComputeConstruct(
12733 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12734 C->getEndLoc(), TransformedClauses, StrBlock);
12735}
12736
12737template <typename Derived>
12738StmtResult
12739TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12740
12741 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12742
12743 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12744 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12745 C->clauses());
12746
12747 if (getSema().OpenACC().ActOnStartStmtDirective(
12748 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12749 return StmtError();
12750
12751 // Transform Loop.
12752 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12753 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12754 C->clauses(), TransformedClauses);
12755 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12756 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12757 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12758
12759 return getDerived().RebuildOpenACCLoopConstruct(
12760 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12761 TransformedClauses, Loop);
12762}
12763
12764template <typename Derived>
12765StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12766 OpenACCCombinedConstruct *C) {
12767 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12768
12769 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12770 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12771 C->clauses());
12772
12773 if (getSema().OpenACC().ActOnStartStmtDirective(
12774 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12775 return StmtError();
12776
12777 // Transform Loop.
12778 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12779 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12780 C->clauses(), TransformedClauses);
12781 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12782 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12783 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12784
12785 return getDerived().RebuildOpenACCCombinedConstruct(
12786 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12787 C->getEndLoc(), TransformedClauses, Loop);
12788}
12789
12790template <typename Derived>
12791StmtResult
12792TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12793 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12794
12795 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12796 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12797 C->clauses());
12798 if (getSema().OpenACC().ActOnStartStmtDirective(
12799 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12800 return StmtError();
12801
12802 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12803 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12804 C->clauses(), TransformedClauses);
12805 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12806 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12807 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12808
12809 return getDerived().RebuildOpenACCDataConstruct(
12810 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12811 TransformedClauses, StrBlock);
12812}
12813
12814template <typename Derived>
12815StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12816 OpenACCEnterDataConstruct *C) {
12817 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12818
12819 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12820 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12821 C->clauses());
12822 if (getSema().OpenACC().ActOnStartStmtDirective(
12823 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12824 return StmtError();
12825
12826 return getDerived().RebuildOpenACCEnterDataConstruct(
12827 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12828 TransformedClauses);
12829}
12830
12831template <typename Derived>
12832StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12833 OpenACCExitDataConstruct *C) {
12834 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12835
12836 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12837 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12838 C->clauses());
12839 if (getSema().OpenACC().ActOnStartStmtDirective(
12840 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12841 return StmtError();
12842
12843 return getDerived().RebuildOpenACCExitDataConstruct(
12844 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12845 TransformedClauses);
12846}
12847
12848template <typename Derived>
12849StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12850 OpenACCHostDataConstruct *C) {
12851 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12852
12853 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12854 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12855 C->clauses());
12856 if (getSema().OpenACC().ActOnStartStmtDirective(
12857 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12858 return StmtError();
12859
12860 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12861 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12862 C->clauses(), TransformedClauses);
12863 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12864 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12865 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12866
12867 return getDerived().RebuildOpenACCHostDataConstruct(
12868 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12869 TransformedClauses, StrBlock);
12870}
12871
12872template <typename Derived>
12873StmtResult
12874TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12875 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12876
12877 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12878 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12879 C->clauses());
12880 if (getSema().OpenACC().ActOnStartStmtDirective(
12881 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12882 return StmtError();
12883
12884 return getDerived().RebuildOpenACCInitConstruct(
12885 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12886 TransformedClauses);
12887}
12888
12889template <typename Derived>
12890StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12891 OpenACCShutdownConstruct *C) {
12892 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12893
12894 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12895 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12896 C->clauses());
12897 if (getSema().OpenACC().ActOnStartStmtDirective(
12898 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12899 return StmtError();
12900
12901 return getDerived().RebuildOpenACCShutdownConstruct(
12902 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12903 TransformedClauses);
12904}
12905template <typename Derived>
12906StmtResult
12907TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12908 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12909
12910 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12911 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12912 C->clauses());
12913 if (getSema().OpenACC().ActOnStartStmtDirective(
12914 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12915 return StmtError();
12916
12917 return getDerived().RebuildOpenACCSetConstruct(
12918 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12919 TransformedClauses);
12920}
12921
12922template <typename Derived>
12923StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12924 OpenACCUpdateConstruct *C) {
12925 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12926
12927 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12928 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12929 C->clauses());
12930 if (getSema().OpenACC().ActOnStartStmtDirective(
12931 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12932 return StmtError();
12933
12934 return getDerived().RebuildOpenACCUpdateConstruct(
12935 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12936 TransformedClauses);
12937}
12938
12939template <typename Derived>
12940StmtResult
12941TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12942 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12943
12944 ExprResult DevNumExpr;
12945 if (C->hasDevNumExpr()) {
12946 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12947
12948 if (DevNumExpr.isUsable())
12949 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12950 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12951 C->getBeginLoc(), DevNumExpr.get());
12952 }
12953
12954 llvm::SmallVector<Expr *> QueueIdExprs;
12955
12956 for (Expr *QE : C->getQueueIdExprs()) {
12957 assert(QE && "Null queue id expr?");
12958 ExprResult NewEQ = getDerived().TransformExpr(QE);
12959
12960 if (!NewEQ.isUsable())
12961 break;
12962 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12963 OpenACCClauseKind::Invalid,
12964 C->getBeginLoc(), NewEQ.get());
12965 if (NewEQ.isUsable())
12966 QueueIdExprs.push_back(Elt: NewEQ.get());
12967 }
12968
12969 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12970 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12971 C->clauses());
12972
12973 if (getSema().OpenACC().ActOnStartStmtDirective(
12974 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12975 return StmtError();
12976
12977 return getDerived().RebuildOpenACCWaitConstruct(
12978 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12979 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12980 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12981}
12982template <typename Derived>
12983StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12984 OpenACCCacheConstruct *C) {
12985 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12986
12987 llvm::SmallVector<Expr *> TransformedVarList;
12988 for (Expr *Var : C->getVarList()) {
12989 assert(Var && "Null var listexpr?");
12990
12991 ExprResult NewVar = getDerived().TransformExpr(Var);
12992
12993 if (!NewVar.isUsable())
12994 break;
12995
12996 NewVar = getSema().OpenACC().ActOnVar(
12997 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12998 if (!NewVar.isUsable())
12999 break;
13000
13001 TransformedVarList.push_back(Elt: NewVar.get());
13002 }
13003
13004 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13005 C->getBeginLoc(), {}))
13006 return StmtError();
13007
13008 return getDerived().RebuildOpenACCCacheConstruct(
13009 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13010 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13011 C->getEndLoc());
13012}
13013
13014template <typename Derived>
13015StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13016 OpenACCAtomicConstruct *C) {
13017 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13018
13019 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13020 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13021 C->clauses());
13022
13023 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13024 C->getBeginLoc(), {}))
13025 return StmtError();
13026
13027 // Transform Associated Stmt.
13028 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13029 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13030
13031 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13032 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13033 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13034 AssocStmt);
13035
13036 return getDerived().RebuildOpenACCAtomicConstruct(
13037 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13038 C->getEndLoc(), TransformedClauses, AssocStmt);
13039}
13040
13041template <typename Derived>
13042ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13043 OpenACCAsteriskSizeExpr *E) {
13044 if (getDerived().AlwaysRebuild())
13045 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13046 // Nothing can ever change, so there is never anything to transform.
13047 return E;
13048}
13049
13050//===----------------------------------------------------------------------===//
13051// Expression transformation
13052//===----------------------------------------------------------------------===//
13053template<typename Derived>
13054ExprResult
13055TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13056 return TransformExpr(E: E->getSubExpr());
13057}
13058
13059template <typename Derived>
13060ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13061 SYCLUniqueStableNameExpr *E) {
13062 if (!E->isTypeDependent())
13063 return E;
13064
13065 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13066
13067 if (!NewT)
13068 return ExprError();
13069
13070 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13071 return E;
13072
13073 return getDerived().RebuildSYCLUniqueStableNameExpr(
13074 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13075}
13076
13077template <typename Derived>
13078StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13079 UnresolvedSYCLKernelCallStmt *S) {
13080 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13081 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13082 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13083 return StmtError();
13084
13085 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13086 if (IdExpr.isInvalid())
13087 return StmtError();
13088
13089 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13090 if (Body.isInvalid())
13091 return StmtError();
13092
13093 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13094 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13095 LaunchIdExpr: IdExpr.get());
13096 if (SR.isInvalid())
13097 return StmtError();
13098
13099 return SR;
13100}
13101
13102template <typename Derived>
13103ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13104 // TODO(reflection): Implement its transform
13105 assert(false && "not implemented yet");
13106 return ExprError();
13107}
13108
13109template<typename Derived>
13110ExprResult
13111TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13112 if (!E->isTypeDependent())
13113 return E;
13114
13115 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13116 E->getIdentKind());
13117}
13118
13119template<typename Derived>
13120ExprResult
13121TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13122 NestedNameSpecifierLoc QualifierLoc;
13123 if (E->getQualifierLoc()) {
13124 QualifierLoc
13125 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13126 if (!QualifierLoc)
13127 return ExprError();
13128 }
13129
13130 ValueDecl *ND
13131 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13132 E->getDecl()));
13133 if (!ND || ND->isInvalidDecl())
13134 return ExprError();
13135
13136 NamedDecl *Found = ND;
13137 if (E->getFoundDecl() != E->getDecl()) {
13138 Found = cast_or_null<NamedDecl>(
13139 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13140 if (!Found)
13141 return ExprError();
13142 }
13143
13144 DeclarationNameInfo NameInfo = E->getNameInfo();
13145 if (NameInfo.getName()) {
13146 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13147 if (!NameInfo.getName())
13148 return ExprError();
13149 }
13150
13151 if (!getDerived().AlwaysRebuild() &&
13152 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13153 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13154 Found == E->getFoundDecl() &&
13155 NameInfo.getName() == E->getDecl()->getDeclName() &&
13156 !E->hasExplicitTemplateArgs()) {
13157
13158 // Mark it referenced in the new context regardless.
13159 // FIXME: this is a bit instantiation-specific.
13160 SemaRef.MarkDeclRefReferenced(E);
13161
13162 return E;
13163 }
13164
13165 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13166 if (E->hasExplicitTemplateArgs()) {
13167 TemplateArgs = &TransArgs;
13168 TransArgs.setLAngleLoc(E->getLAngleLoc());
13169 TransArgs.setRAngleLoc(E->getRAngleLoc());
13170 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13171 E->getNumTemplateArgs(),
13172 TransArgs))
13173 return ExprError();
13174 }
13175
13176 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13177 Found, TemplateArgs);
13178}
13179
13180template<typename Derived>
13181ExprResult
13182TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13183 return E;
13184}
13185
13186template <typename Derived>
13187ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13188 FixedPointLiteral *E) {
13189 return E;
13190}
13191
13192template<typename Derived>
13193ExprResult
13194TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13195 return E;
13196}
13197
13198template<typename Derived>
13199ExprResult
13200TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13201 return E;
13202}
13203
13204template<typename Derived>
13205ExprResult
13206TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13207 return E;
13208}
13209
13210template<typename Derived>
13211ExprResult
13212TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13213 return E;
13214}
13215
13216template<typename Derived>
13217ExprResult
13218TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13219 return getDerived().TransformCallExpr(E);
13220}
13221
13222template<typename Derived>
13223ExprResult
13224TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13225 ExprResult ControllingExpr;
13226 TypeSourceInfo *ControllingType = nullptr;
13227 if (E->isExprPredicate())
13228 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13229 else
13230 ControllingType = getDerived().TransformType(E->getControllingType());
13231
13232 if (ControllingExpr.isInvalid() && !ControllingType)
13233 return ExprError();
13234
13235 SmallVector<Expr *, 4> AssocExprs;
13236 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13237 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13238 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13239 if (TSI) {
13240 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13241 if (!AssocType)
13242 return ExprError();
13243 AssocTypes.push_back(Elt: AssocType);
13244 } else {
13245 AssocTypes.push_back(Elt: nullptr);
13246 }
13247
13248 ExprResult AssocExpr =
13249 getDerived().TransformExpr(Assoc.getAssociationExpr());
13250 if (AssocExpr.isInvalid())
13251 return ExprError();
13252 AssocExprs.push_back(Elt: AssocExpr.get());
13253 }
13254
13255 if (!ControllingType)
13256 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13257 E->getDefaultLoc(),
13258 E->getRParenLoc(),
13259 ControllingExpr.get(),
13260 AssocTypes,
13261 AssocExprs);
13262 return getDerived().RebuildGenericSelectionExpr(
13263 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13264 ControllingType, AssocTypes, AssocExprs);
13265}
13266
13267template<typename Derived>
13268ExprResult
13269TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13270 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13271 if (SubExpr.isInvalid())
13272 return ExprError();
13273
13274 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13275 return E;
13276
13277 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13278 E->getRParen());
13279}
13280
13281/// The operand of a unary address-of operator has special rules: it's
13282/// allowed to refer to a non-static member of a class even if there's no 'this'
13283/// object available.
13284template<typename Derived>
13285ExprResult
13286TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13287 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13288 return getDerived().TransformDependentScopeDeclRefExpr(
13289 DRE, /*IsAddressOfOperand=*/true, nullptr);
13290 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13291 return getDerived().TransformUnresolvedLookupExpr(
13292 ULE, /*IsAddressOfOperand=*/true);
13293 else
13294 return getDerived().TransformExpr(E);
13295}
13296
13297template<typename Derived>
13298ExprResult
13299TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13300 ExprResult SubExpr;
13301 if (E->getOpcode() == UO_AddrOf)
13302 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13303 else
13304 SubExpr = TransformExpr(E: E->getSubExpr());
13305 if (SubExpr.isInvalid())
13306 return ExprError();
13307
13308 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13309 return E;
13310
13311 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13312 E->getOpcode(),
13313 SubExpr.get());
13314}
13315
13316template<typename Derived>
13317ExprResult
13318TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13319 // Transform the type.
13320 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13321 if (!Type)
13322 return ExprError();
13323
13324 // Transform all of the components into components similar to what the
13325 // parser uses.
13326 // FIXME: It would be slightly more efficient in the non-dependent case to
13327 // just map FieldDecls, rather than requiring the rebuilder to look for
13328 // the fields again. However, __builtin_offsetof is rare enough in
13329 // template code that we don't care.
13330 bool ExprChanged = false;
13331 typedef Sema::OffsetOfComponent Component;
13332 SmallVector<Component, 4> Components;
13333 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13334 const OffsetOfNode &ON = E->getComponent(Idx: I);
13335 Component Comp;
13336 Comp.isBrackets = true;
13337 Comp.LocStart = ON.getSourceRange().getBegin();
13338 Comp.LocEnd = ON.getSourceRange().getEnd();
13339 switch (ON.getKind()) {
13340 case OffsetOfNode::Array: {
13341 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13342 ExprResult Index = getDerived().TransformExpr(FromIndex);
13343 if (Index.isInvalid())
13344 return ExprError();
13345
13346 ExprChanged = ExprChanged || Index.get() != FromIndex;
13347 Comp.isBrackets = true;
13348 Comp.U.E = Index.get();
13349 break;
13350 }
13351
13352 case OffsetOfNode::Field:
13353 case OffsetOfNode::Identifier:
13354 Comp.isBrackets = false;
13355 Comp.U.IdentInfo = ON.getFieldName();
13356 if (!Comp.U.IdentInfo)
13357 continue;
13358
13359 break;
13360
13361 case OffsetOfNode::Base:
13362 // Will be recomputed during the rebuild.
13363 continue;
13364 }
13365
13366 Components.push_back(Elt: Comp);
13367 }
13368
13369 // If nothing changed, retain the existing expression.
13370 if (!getDerived().AlwaysRebuild() &&
13371 Type == E->getTypeSourceInfo() &&
13372 !ExprChanged)
13373 return E;
13374
13375 // Build a new offsetof expression.
13376 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13377 Components, E->getRParenLoc());
13378}
13379
13380template<typename Derived>
13381ExprResult
13382TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13383 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13384 "opaque value expression requires transformation");
13385 return E;
13386}
13387
13388template <typename Derived>
13389ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13390 llvm::SmallVector<Expr *, 8> Children;
13391 bool Changed = false;
13392 for (Expr *C : E->subExpressions()) {
13393 ExprResult NewC = getDerived().TransformExpr(C);
13394 if (NewC.isInvalid())
13395 return ExprError();
13396 Children.push_back(Elt: NewC.get());
13397
13398 Changed |= NewC.get() != C;
13399 }
13400 if (!getDerived().AlwaysRebuild() && !Changed)
13401 return E;
13402 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13403 Children, E->getType());
13404}
13405
13406template<typename Derived>
13407ExprResult
13408TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13409 // Rebuild the syntactic form. The original syntactic form has
13410 // opaque-value expressions in it, so strip those away and rebuild
13411 // the result. This is a really awful way of doing this, but the
13412 // better solution (rebuilding the semantic expressions and
13413 // rebinding OVEs as necessary) doesn't work; we'd need
13414 // TreeTransform to not strip away implicit conversions.
13415 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13416 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13417 if (result.isInvalid()) return ExprError();
13418
13419 // If that gives us a pseudo-object result back, the pseudo-object
13420 // expression must have been an lvalue-to-rvalue conversion which we
13421 // should reapply.
13422 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13423 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13424
13425 return result;
13426}
13427
13428template<typename Derived>
13429ExprResult
13430TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13431 UnaryExprOrTypeTraitExpr *E) {
13432 if (E->isArgumentType()) {
13433 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13434
13435 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13436 if (!NewT)
13437 return ExprError();
13438
13439 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13440 return E;
13441
13442 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13443 E->getKind(),
13444 E->getSourceRange());
13445 }
13446
13447 // C++0x [expr.sizeof]p1:
13448 // The operand is either an expression, which is an unevaluated operand
13449 // [...]
13450 EnterExpressionEvaluationContext Unevaluated(
13451 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13452 Sema::ReuseLambdaContextDecl);
13453
13454 // Try to recover if we have something like sizeof(T::X) where X is a type.
13455 // Notably, there must be *exactly* one set of parens if X is a type.
13456 TypeSourceInfo *RecoveryTSI = nullptr;
13457 ExprResult SubExpr;
13458 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13459 if (auto *DRE =
13460 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13461 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13462 PE, DRE, false, &RecoveryTSI);
13463 else
13464 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13465
13466 if (RecoveryTSI) {
13467 return getDerived().RebuildUnaryExprOrTypeTrait(
13468 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13469 } else if (SubExpr.isInvalid())
13470 return ExprError();
13471
13472 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13473 return E;
13474
13475 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13476 E->getOperatorLoc(),
13477 E->getKind(),
13478 E->getSourceRange());
13479}
13480
13481template<typename Derived>
13482ExprResult
13483TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13484 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13485 if (LHS.isInvalid())
13486 return ExprError();
13487
13488 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13489 if (RHS.isInvalid())
13490 return ExprError();
13491
13492
13493 if (!getDerived().AlwaysRebuild() &&
13494 LHS.get() == E->getLHS() &&
13495 RHS.get() == E->getRHS())
13496 return E;
13497
13498 return getDerived().RebuildArraySubscriptExpr(
13499 LHS.get(),
13500 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13501}
13502
13503template <typename Derived>
13504ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13505 MatrixSingleSubscriptExpr *E) {
13506 ExprResult Base = getDerived().TransformExpr(E->getBase());
13507 if (Base.isInvalid())
13508 return ExprError();
13509
13510 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13511 if (RowIdx.isInvalid())
13512 return ExprError();
13513
13514 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13515 RowIdx.get() == E->getRowIdx())
13516 return E;
13517
13518 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
13519 E->getRBracketLoc());
13520}
13521
13522template <typename Derived>
13523ExprResult
13524TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13525 ExprResult Base = getDerived().TransformExpr(E->getBase());
13526 if (Base.isInvalid())
13527 return ExprError();
13528
13529 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13530 if (RowIdx.isInvalid())
13531 return ExprError();
13532
13533 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13534 if (ColumnIdx.isInvalid())
13535 return ExprError();
13536
13537 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13538 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13539 return E;
13540
13541 return getDerived().RebuildMatrixSubscriptExpr(
13542 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13543}
13544
13545template <typename Derived>
13546ExprResult
13547TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13548 ExprResult Base = getDerived().TransformExpr(E->getBase());
13549 if (Base.isInvalid())
13550 return ExprError();
13551
13552 ExprResult LowerBound;
13553 if (E->getLowerBound()) {
13554 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13555 if (LowerBound.isInvalid())
13556 return ExprError();
13557 }
13558
13559 ExprResult Length;
13560 if (E->getLength()) {
13561 Length = getDerived().TransformExpr(E->getLength());
13562 if (Length.isInvalid())
13563 return ExprError();
13564 }
13565
13566 ExprResult Stride;
13567 if (E->isOMPArraySection()) {
13568 if (Expr *Str = E->getStride()) {
13569 Stride = getDerived().TransformExpr(Str);
13570 if (Stride.isInvalid())
13571 return ExprError();
13572 }
13573 }
13574
13575 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13576 LowerBound.get() == E->getLowerBound() &&
13577 Length.get() == E->getLength() &&
13578 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13579 return E;
13580
13581 return getDerived().RebuildArraySectionExpr(
13582 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13583 LowerBound.get(), E->getColonLocFirst(),
13584 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13585 Length.get(), Stride.get(), E->getRBracketLoc());
13586}
13587
13588template <typename Derived>
13589ExprResult
13590TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13591 ExprResult Base = getDerived().TransformExpr(E->getBase());
13592 if (Base.isInvalid())
13593 return ExprError();
13594
13595 SmallVector<Expr *, 4> Dims;
13596 bool ErrorFound = false;
13597 for (Expr *Dim : E->getDimensions()) {
13598 ExprResult DimRes = getDerived().TransformExpr(Dim);
13599 if (DimRes.isInvalid()) {
13600 ErrorFound = true;
13601 continue;
13602 }
13603 Dims.push_back(Elt: DimRes.get());
13604 }
13605
13606 if (ErrorFound)
13607 return ExprError();
13608 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13609 E->getRParenLoc(), Dims,
13610 E->getBracketsRanges());
13611}
13612
13613template <typename Derived>
13614ExprResult
13615TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13616 unsigned NumIterators = E->numOfIterators();
13617 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13618
13619 bool ErrorFound = false;
13620 bool NeedToRebuild = getDerived().AlwaysRebuild();
13621 for (unsigned I = 0; I < NumIterators; ++I) {
13622 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13623 Data[I].DeclIdent = D->getIdentifier();
13624 Data[I].DeclIdentLoc = D->getLocation();
13625 if (D->getLocation() == D->getBeginLoc()) {
13626 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13627 "Implicit type must be int.");
13628 } else {
13629 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13630 QualType DeclTy = getDerived().TransformType(D->getType());
13631 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13632 }
13633 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13634 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13635 ExprResult End = getDerived().TransformExpr(Range.End);
13636 ExprResult Step = getDerived().TransformExpr(Range.Step);
13637 ErrorFound = ErrorFound ||
13638 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13639 !Data[I].Type.get().isNull())) ||
13640 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13641 if (ErrorFound)
13642 continue;
13643 Data[I].Range.Begin = Begin.get();
13644 Data[I].Range.End = End.get();
13645 Data[I].Range.Step = Step.get();
13646 Data[I].AssignLoc = E->getAssignLoc(I);
13647 Data[I].ColonLoc = E->getColonLoc(I);
13648 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13649 NeedToRebuild =
13650 NeedToRebuild ||
13651 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13652 D->getType().getTypePtrOrNull()) ||
13653 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13654 Range.Step != Data[I].Range.Step;
13655 }
13656 if (ErrorFound)
13657 return ExprError();
13658 if (!NeedToRebuild)
13659 return E;
13660
13661 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13662 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13663 if (!Res.isUsable())
13664 return Res;
13665 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13666 for (unsigned I = 0; I < NumIterators; ++I)
13667 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13668 IE->getIteratorDecl(I));
13669 return Res;
13670}
13671
13672template<typename Derived>
13673ExprResult
13674TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13675 // Transform the callee.
13676 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13677 if (Callee.isInvalid())
13678 return ExprError();
13679
13680 // Transform arguments.
13681 bool ArgChanged = false;
13682 SmallVector<Expr*, 8> Args;
13683 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13684 &ArgChanged))
13685 return ExprError();
13686
13687 if (!getDerived().AlwaysRebuild() &&
13688 Callee.get() == E->getCallee() &&
13689 !ArgChanged)
13690 return SemaRef.MaybeBindToTemporary(E);
13691
13692 // FIXME: Wrong source location information for the '('.
13693 SourceLocation FakeLParenLoc
13694 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13695
13696 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13697 if (E->hasStoredFPFeatures()) {
13698 FPOptionsOverride NewOverrides = E->getFPFeatures();
13699 getSema().CurFPFeatures =
13700 NewOverrides.applyOverrides(getSema().getLangOpts());
13701 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13702 }
13703
13704 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13705 Args,
13706 E->getRParenLoc());
13707}
13708
13709template<typename Derived>
13710ExprResult
13711TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13712 ExprResult Base = getDerived().TransformExpr(E->getBase());
13713 if (Base.isInvalid())
13714 return ExprError();
13715
13716 NestedNameSpecifierLoc QualifierLoc;
13717 if (E->hasQualifier()) {
13718 QualifierLoc
13719 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13720
13721 if (!QualifierLoc)
13722 return ExprError();
13723 }
13724 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13725
13726 ValueDecl *Member
13727 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13728 E->getMemberDecl()));
13729 if (!Member)
13730 return ExprError();
13731
13732 NamedDecl *FoundDecl = E->getFoundDecl();
13733 if (FoundDecl == E->getMemberDecl()) {
13734 FoundDecl = Member;
13735 } else {
13736 FoundDecl = cast_or_null<NamedDecl>(
13737 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13738 if (!FoundDecl)
13739 return ExprError();
13740 }
13741
13742 if (!getDerived().AlwaysRebuild() &&
13743 Base.get() == E->getBase() &&
13744 QualifierLoc == E->getQualifierLoc() &&
13745 Member == E->getMemberDecl() &&
13746 FoundDecl == E->getFoundDecl() &&
13747 !E->hasExplicitTemplateArgs()) {
13748
13749 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13750 // for Openmp where the field need to be privatizized in the case.
13751 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13752 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13753 cast<ValueDecl>(Val: Member)))) {
13754 // Mark it referenced in the new context regardless.
13755 // FIXME: this is a bit instantiation-specific.
13756 SemaRef.MarkMemberReferenced(E);
13757 return E;
13758 }
13759 }
13760
13761 TemplateArgumentListInfo TransArgs;
13762 if (E->hasExplicitTemplateArgs()) {
13763 TransArgs.setLAngleLoc(E->getLAngleLoc());
13764 TransArgs.setRAngleLoc(E->getRAngleLoc());
13765 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13766 E->getNumTemplateArgs(),
13767 TransArgs))
13768 return ExprError();
13769 }
13770
13771 // FIXME: Bogus source location for the operator
13772 SourceLocation FakeOperatorLoc =
13773 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13774
13775 // FIXME: to do this check properly, we will need to preserve the
13776 // first-qualifier-in-scope here, just in case we had a dependent
13777 // base (and therefore couldn't do the check) and a
13778 // nested-name-qualifier (and therefore could do the lookup).
13779 NamedDecl *FirstQualifierInScope = nullptr;
13780 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13781 if (MemberNameInfo.getName()) {
13782 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13783 if (!MemberNameInfo.getName())
13784 return ExprError();
13785 }
13786
13787 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13788 E->isArrow(),
13789 QualifierLoc,
13790 TemplateKWLoc,
13791 MemberNameInfo,
13792 Member,
13793 FoundDecl,
13794 (E->hasExplicitTemplateArgs()
13795 ? &TransArgs : nullptr),
13796 FirstQualifierInScope);
13797}
13798
13799template<typename Derived>
13800ExprResult
13801TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13802 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13803 if (LHS.isInvalid())
13804 return ExprError();
13805
13806 ExprResult RHS =
13807 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13808 if (RHS.isInvalid())
13809 return ExprError();
13810
13811 if (!getDerived().AlwaysRebuild() &&
13812 LHS.get() == E->getLHS() &&
13813 RHS.get() == E->getRHS())
13814 return E;
13815
13816 if (E->isCompoundAssignmentOp())
13817 // FPFeatures has already been established from trailing storage
13818 return getDerived().RebuildBinaryOperator(
13819 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13820 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13821 FPOptionsOverride NewOverrides(E->getFPFeatures());
13822 getSema().CurFPFeatures =
13823 NewOverrides.applyOverrides(getSema().getLangOpts());
13824 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13825 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13826 LHS.get(), RHS.get());
13827}
13828
13829template <typename Derived>
13830ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13831 CXXRewrittenBinaryOperator *E) {
13832 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13833
13834 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13835 if (LHS.isInvalid())
13836 return ExprError();
13837
13838 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13839 if (RHS.isInvalid())
13840 return ExprError();
13841
13842 // Extract the already-resolved callee declarations so that we can restrict
13843 // ourselves to using them as the unqualified lookup results when rebuilding.
13844 UnresolvedSet<2> UnqualLookups;
13845 bool ChangedAnyLookups = false;
13846 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13847 const_cast<Expr *>(Decomp.InnerBinOp)};
13848 for (Expr *PossibleBinOp : PossibleBinOps) {
13849 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13850 if (!Op)
13851 continue;
13852 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13853 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13854 continue;
13855
13856 // Transform the callee in case we built a call to a local extern
13857 // declaration.
13858 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13859 E->getOperatorLoc(), Callee->getFoundDecl()));
13860 if (!Found)
13861 return ExprError();
13862 if (Found != Callee->getFoundDecl())
13863 ChangedAnyLookups = true;
13864 UnqualLookups.addDecl(D: Found);
13865 }
13866
13867 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13868 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13869 // Mark all functions used in the rewrite as referenced. Note that when
13870 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13871 // function calls, and/or there might be a user-defined conversion sequence
13872 // applied to the operands of the <.
13873 // FIXME: this is a bit instantiation-specific.
13874 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13875 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13876 return E;
13877 }
13878
13879 return getDerived().RebuildCXXRewrittenBinaryOperator(
13880 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13881}
13882
13883template<typename Derived>
13884ExprResult
13885TreeTransform<Derived>::TransformCompoundAssignOperator(
13886 CompoundAssignOperator *E) {
13887 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13888 FPOptionsOverride NewOverrides(E->getFPFeatures());
13889 getSema().CurFPFeatures =
13890 NewOverrides.applyOverrides(getSema().getLangOpts());
13891 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13892 return getDerived().TransformBinaryOperator(E);
13893}
13894
13895template<typename Derived>
13896ExprResult TreeTransform<Derived>::
13897TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13898 // Just rebuild the common and RHS expressions and see whether we
13899 // get any changes.
13900
13901 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13902 if (commonExpr.isInvalid())
13903 return ExprError();
13904
13905 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13906 if (rhs.isInvalid())
13907 return ExprError();
13908
13909 if (!getDerived().AlwaysRebuild() &&
13910 commonExpr.get() == e->getCommon() &&
13911 rhs.get() == e->getFalseExpr())
13912 return e;
13913
13914 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13915 e->getQuestionLoc(),
13916 nullptr,
13917 e->getColonLoc(),
13918 rhs.get());
13919}
13920
13921template<typename Derived>
13922ExprResult
13923TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13924 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13925 if (Cond.isInvalid())
13926 return ExprError();
13927
13928 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13929 if (LHS.isInvalid())
13930 return ExprError();
13931
13932 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13933 if (RHS.isInvalid())
13934 return ExprError();
13935
13936 if (!getDerived().AlwaysRebuild() &&
13937 Cond.get() == E->getCond() &&
13938 LHS.get() == E->getLHS() &&
13939 RHS.get() == E->getRHS())
13940 return E;
13941
13942 return getDerived().RebuildConditionalOperator(Cond.get(),
13943 E->getQuestionLoc(),
13944 LHS.get(),
13945 E->getColonLoc(),
13946 RHS.get());
13947}
13948
13949template<typename Derived>
13950ExprResult
13951TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13952 // Implicit casts are eliminated during transformation, since they
13953 // will be recomputed by semantic analysis after transformation.
13954 return getDerived().TransformExpr(E->getSubExprAsWritten());
13955}
13956
13957template<typename Derived>
13958ExprResult
13959TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13960 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13961 if (!Type)
13962 return ExprError();
13963
13964 ExprResult SubExpr
13965 = getDerived().TransformExpr(E->getSubExprAsWritten());
13966 if (SubExpr.isInvalid())
13967 return ExprError();
13968
13969 if (!getDerived().AlwaysRebuild() &&
13970 Type == E->getTypeInfoAsWritten() &&
13971 SubExpr.get() == E->getSubExpr())
13972 return E;
13973
13974 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13975 Type,
13976 E->getRParenLoc(),
13977 SubExpr.get());
13978}
13979
13980template<typename Derived>
13981ExprResult
13982TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13983 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13984 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13985 if (!NewT)
13986 return ExprError();
13987
13988 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13989 if (Init.isInvalid())
13990 return ExprError();
13991
13992 if (!getDerived().AlwaysRebuild() &&
13993 OldT == NewT &&
13994 Init.get() == E->getInitializer())
13995 return SemaRef.MaybeBindToTemporary(E);
13996
13997 // Note: the expression type doesn't necessarily match the
13998 // type-as-written, but that's okay, because it should always be
13999 // derivable from the initializer.
14000
14001 return getDerived().RebuildCompoundLiteralExpr(
14002 E->getLParenLoc(), NewT,
14003 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14004}
14005
14006template<typename Derived>
14007ExprResult
14008TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14009 ExprResult Base = getDerived().TransformExpr(E->getBase());
14010 if (Base.isInvalid())
14011 return ExprError();
14012
14013 if (!getDerived().AlwaysRebuild() &&
14014 Base.get() == E->getBase())
14015 return E;
14016
14017 // FIXME: Bad source location
14018 SourceLocation FakeOperatorLoc =
14019 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14020 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14021 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14022 E->getAccessor());
14023}
14024
14025template <typename Derived>
14026ExprResult
14027TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14028 ExprResult Base = getDerived().TransformExpr(E->getBase());
14029 if (Base.isInvalid())
14030 return ExprError();
14031
14032 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14033 return E;
14034
14035 // FIXME: Bad source location
14036 SourceLocation FakeOperatorLoc =
14037 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14038 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14039 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14040 E->getAccessor());
14041}
14042
14043template<typename Derived>
14044ExprResult
14045TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14046 if (InitListExpr *Syntactic = E->getSyntacticForm())
14047 E = Syntactic;
14048
14049 bool InitChanged = false;
14050
14051 EnterExpressionEvaluationContext Context(
14052 getSema(), EnterExpressionEvaluationContext::InitList);
14053
14054 SmallVector<Expr*, 4> Inits;
14055 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14056 Inits, &InitChanged))
14057 return ExprError();
14058
14059 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14060 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14061 // in some cases. We can't reuse it in general, because the syntactic and
14062 // semantic forms are linked, and we can't know that semantic form will
14063 // match even if the syntactic form does.
14064 }
14065
14066 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14067 E->getRBraceLoc());
14068}
14069
14070template<typename Derived>
14071ExprResult
14072TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14073 Designation Desig;
14074
14075 // transform the initializer value
14076 ExprResult Init = getDerived().TransformExpr(E->getInit());
14077 if (Init.isInvalid())
14078 return ExprError();
14079
14080 // transform the designators.
14081 SmallVector<Expr*, 4> ArrayExprs;
14082 bool ExprChanged = false;
14083 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14084 if (D.isFieldDesignator()) {
14085 if (D.getFieldDecl()) {
14086 FieldDecl *Field = cast_or_null<FieldDecl>(
14087 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14088 if (Field != D.getFieldDecl())
14089 // Rebuild the expression when the transformed FieldDecl is
14090 // different to the already assigned FieldDecl.
14091 ExprChanged = true;
14092 if (Field->isAnonymousStructOrUnion())
14093 continue;
14094 } else {
14095 // Ensure that the designator expression is rebuilt when there isn't
14096 // a resolved FieldDecl in the designator as we don't want to assign
14097 // a FieldDecl to a pattern designator that will be instantiated again.
14098 ExprChanged = true;
14099 }
14100 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14101 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14102 continue;
14103 }
14104
14105 if (D.isArrayDesignator()) {
14106 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14107 if (Index.isInvalid())
14108 return ExprError();
14109
14110 Desig.AddDesignator(
14111 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14112
14113 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14114 ArrayExprs.push_back(Elt: Index.get());
14115 continue;
14116 }
14117
14118 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14119 ExprResult Start
14120 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14121 if (Start.isInvalid())
14122 return ExprError();
14123
14124 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14125 if (End.isInvalid())
14126 return ExprError();
14127
14128 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14129 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14130
14131 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14132 End.get() != E->getArrayRangeEnd(D);
14133
14134 ArrayExprs.push_back(Elt: Start.get());
14135 ArrayExprs.push_back(Elt: End.get());
14136 }
14137
14138 if (!getDerived().AlwaysRebuild() &&
14139 Init.get() == E->getInit() &&
14140 !ExprChanged)
14141 return E;
14142
14143 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14144 E->getEqualOrColonLoc(),
14145 E->usesGNUSyntax(), Init.get());
14146}
14147
14148// Seems that if TransformInitListExpr() only works on the syntactic form of an
14149// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14150template<typename Derived>
14151ExprResult
14152TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14153 DesignatedInitUpdateExpr *E) {
14154 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14155 "initializer");
14156 return ExprError();
14157}
14158
14159template<typename Derived>
14160ExprResult
14161TreeTransform<Derived>::TransformNoInitExpr(
14162 NoInitExpr *E) {
14163 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14164 return ExprError();
14165}
14166
14167template<typename Derived>
14168ExprResult
14169TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14170 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14171 return ExprError();
14172}
14173
14174template<typename Derived>
14175ExprResult
14176TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14177 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14178 return ExprError();
14179}
14180
14181template<typename Derived>
14182ExprResult
14183TreeTransform<Derived>::TransformImplicitValueInitExpr(
14184 ImplicitValueInitExpr *E) {
14185 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14186
14187 // FIXME: Will we ever have proper type location here? Will we actually
14188 // need to transform the type?
14189 QualType T = getDerived().TransformType(E->getType());
14190 if (T.isNull())
14191 return ExprError();
14192
14193 if (!getDerived().AlwaysRebuild() &&
14194 T == E->getType())
14195 return E;
14196
14197 return getDerived().RebuildImplicitValueInitExpr(T);
14198}
14199
14200template<typename Derived>
14201ExprResult
14202TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14203 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14204 if (!TInfo)
14205 return ExprError();
14206
14207 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14208 if (SubExpr.isInvalid())
14209 return ExprError();
14210
14211 if (!getDerived().AlwaysRebuild() &&
14212 TInfo == E->getWrittenTypeInfo() &&
14213 SubExpr.get() == E->getSubExpr())
14214 return E;
14215
14216 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14217 TInfo, E->getRParenLoc());
14218}
14219
14220template<typename Derived>
14221ExprResult
14222TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14223 bool ArgumentChanged = false;
14224 SmallVector<Expr*, 4> Inits;
14225 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14226 ArgChanged: &ArgumentChanged))
14227 return ExprError();
14228
14229 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14230 Inits,
14231 E->getRParenLoc());
14232}
14233
14234/// Transform an address-of-label expression.
14235///
14236/// By default, the transformation of an address-of-label expression always
14237/// rebuilds the expression, so that the label identifier can be resolved to
14238/// the corresponding label statement by semantic analysis.
14239template<typename Derived>
14240ExprResult
14241TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14242 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14243 E->getLabel());
14244 if (!LD)
14245 return ExprError();
14246
14247 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14248 cast<LabelDecl>(Val: LD));
14249}
14250
14251template<typename Derived>
14252ExprResult
14253TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14254 SemaRef.ActOnStartStmtExpr();
14255 StmtResult SubStmt
14256 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14257 if (SubStmt.isInvalid()) {
14258 SemaRef.ActOnStmtExprError();
14259 return ExprError();
14260 }
14261
14262 unsigned OldDepth = E->getTemplateDepth();
14263 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14264
14265 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14266 SubStmt.get() == E->getSubStmt()) {
14267 // Calling this an 'error' is unintuitive, but it does the right thing.
14268 SemaRef.ActOnStmtExprError();
14269 return SemaRef.MaybeBindToTemporary(E);
14270 }
14271
14272 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14273 E->getRParenLoc(), NewDepth);
14274}
14275
14276template<typename Derived>
14277ExprResult
14278TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14279 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14280 if (Cond.isInvalid())
14281 return ExprError();
14282
14283 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14284 if (LHS.isInvalid())
14285 return ExprError();
14286
14287 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14288 if (RHS.isInvalid())
14289 return ExprError();
14290
14291 if (!getDerived().AlwaysRebuild() &&
14292 Cond.get() == E->getCond() &&
14293 LHS.get() == E->getLHS() &&
14294 RHS.get() == E->getRHS())
14295 return E;
14296
14297 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14298 Cond.get(), LHS.get(), RHS.get(),
14299 E->getRParenLoc());
14300}
14301
14302template<typename Derived>
14303ExprResult
14304TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14305 return E;
14306}
14307
14308template<typename Derived>
14309ExprResult
14310TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14311 switch (E->getOperator()) {
14312 case OO_New:
14313 case OO_Delete:
14314 case OO_Array_New:
14315 case OO_Array_Delete:
14316 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14317
14318 case OO_Subscript:
14319 case OO_Call: {
14320 // This is a call to an object's operator().
14321 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14322
14323 // Transform the object itself.
14324 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14325 if (Object.isInvalid())
14326 return ExprError();
14327
14328 // FIXME: Poor location information. Also, if the location for the end of
14329 // the token is within a macro expansion, getLocForEndOfToken() will return
14330 // an invalid source location. If that happens and we have an otherwise
14331 // valid end location, use the valid one instead of the invalid one.
14332 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14333 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14334 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14335 FakeLParenLoc = EndLoc;
14336
14337 // Transform the call arguments.
14338 SmallVector<Expr*, 8> Args;
14339 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14340 Args))
14341 return ExprError();
14342
14343 if (E->getOperator() == OO_Subscript)
14344 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14345 Args, E->getEndLoc());
14346
14347 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14348 E->getEndLoc());
14349 }
14350
14351#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14352 case OO_##Name: \
14353 break;
14354
14355#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14356#include "clang/Basic/OperatorKinds.def"
14357
14358 case OO_Conditional:
14359 llvm_unreachable("conditional operator is not actually overloadable");
14360
14361 case OO_None:
14362 case NUM_OVERLOADED_OPERATORS:
14363 llvm_unreachable("not an overloaded operator?");
14364 }
14365
14366 ExprResult First;
14367 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14368 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14369 else
14370 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14371 if (First.isInvalid())
14372 return ExprError();
14373
14374 ExprResult Second;
14375 if (E->getNumArgs() == 2) {
14376 Second =
14377 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14378 if (Second.isInvalid())
14379 return ExprError();
14380 }
14381
14382 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14383 FPOptionsOverride NewOverrides(E->getFPFeatures());
14384 getSema().CurFPFeatures =
14385 NewOverrides.applyOverrides(getSema().getLangOpts());
14386 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14387
14388 Expr *Callee = E->getCallee();
14389 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14390 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14391 Sema::LookupOrdinaryName);
14392 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14393 return ExprError();
14394
14395 return getDerived().RebuildCXXOperatorCallExpr(
14396 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14397 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14398 }
14399
14400 UnresolvedSet<1> Functions;
14401 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14402 Callee = ICE->getSubExprAsWritten();
14403 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14404 ValueDecl *VD = cast_or_null<ValueDecl>(
14405 getDerived().TransformDecl(DR->getLocation(), DR));
14406 if (!VD)
14407 return ExprError();
14408
14409 if (!isa<CXXMethodDecl>(Val: VD))
14410 Functions.addDecl(D: VD);
14411
14412 return getDerived().RebuildCXXOperatorCallExpr(
14413 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14414 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14415}
14416
14417template<typename Derived>
14418ExprResult
14419TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14420 return getDerived().TransformCallExpr(E);
14421}
14422
14423template <typename Derived>
14424ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14425 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14426 getSema().CurContext != E->getParentContext();
14427
14428 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14429 return E;
14430
14431 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14432 E->getBeginLoc(), E->getEndLoc(),
14433 getSema().CurContext);
14434}
14435
14436template <typename Derived>
14437ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14438 return E;
14439}
14440
14441template<typename Derived>
14442ExprResult
14443TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14444 // Transform the callee.
14445 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14446 if (Callee.isInvalid())
14447 return ExprError();
14448
14449 // Transform exec config.
14450 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14451 if (EC.isInvalid())
14452 return ExprError();
14453
14454 // Transform arguments.
14455 bool ArgChanged = false;
14456 SmallVector<Expr*, 8> Args;
14457 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14458 &ArgChanged))
14459 return ExprError();
14460
14461 if (!getDerived().AlwaysRebuild() &&
14462 Callee.get() == E->getCallee() &&
14463 !ArgChanged)
14464 return SemaRef.MaybeBindToTemporary(E);
14465
14466 // FIXME: Wrong source location information for the '('.
14467 SourceLocation FakeLParenLoc
14468 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14469 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14470 Args,
14471 E->getRParenLoc(), EC.get());
14472}
14473
14474template<typename Derived>
14475ExprResult
14476TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14477 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14478 if (!Type)
14479 return ExprError();
14480
14481 ExprResult SubExpr
14482 = getDerived().TransformExpr(E->getSubExprAsWritten());
14483 if (SubExpr.isInvalid())
14484 return ExprError();
14485
14486 if (!getDerived().AlwaysRebuild() &&
14487 Type == E->getTypeInfoAsWritten() &&
14488 SubExpr.get() == E->getSubExpr())
14489 return E;
14490 return getDerived().RebuildCXXNamedCastExpr(
14491 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14492 Type, E->getAngleBrackets().getEnd(),
14493 // FIXME. this should be '(' location
14494 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14495}
14496
14497template<typename Derived>
14498ExprResult
14499TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14500 TypeSourceInfo *TSI =
14501 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14502 if (!TSI)
14503 return ExprError();
14504
14505 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14506 if (Sub.isInvalid())
14507 return ExprError();
14508
14509 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14510 Sub.get(), BCE->getEndLoc());
14511}
14512
14513template<typename Derived>
14514ExprResult
14515TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14516 return getDerived().TransformCXXNamedCastExpr(E);
14517}
14518
14519template<typename Derived>
14520ExprResult
14521TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14522 return getDerived().TransformCXXNamedCastExpr(E);
14523}
14524
14525template<typename Derived>
14526ExprResult
14527TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14528 CXXReinterpretCastExpr *E) {
14529 return getDerived().TransformCXXNamedCastExpr(E);
14530}
14531
14532template<typename Derived>
14533ExprResult
14534TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14535 return getDerived().TransformCXXNamedCastExpr(E);
14536}
14537
14538template<typename Derived>
14539ExprResult
14540TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14541 return getDerived().TransformCXXNamedCastExpr(E);
14542}
14543
14544template<typename Derived>
14545ExprResult
14546TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14547 CXXFunctionalCastExpr *E) {
14548 TypeSourceInfo *Type =
14549 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14550 if (!Type)
14551 return ExprError();
14552
14553 ExprResult SubExpr
14554 = getDerived().TransformExpr(E->getSubExprAsWritten());
14555 if (SubExpr.isInvalid())
14556 return ExprError();
14557
14558 if (!getDerived().AlwaysRebuild() &&
14559 Type == E->getTypeInfoAsWritten() &&
14560 SubExpr.get() == E->getSubExpr())
14561 return E;
14562
14563 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14564 E->getLParenLoc(),
14565 SubExpr.get(),
14566 E->getRParenLoc(),
14567 E->isListInitialization());
14568}
14569
14570template<typename Derived>
14571ExprResult
14572TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14573 if (E->isTypeOperand()) {
14574 TypeSourceInfo *TInfo
14575 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14576 if (!TInfo)
14577 return ExprError();
14578
14579 if (!getDerived().AlwaysRebuild() &&
14580 TInfo == E->getTypeOperandSourceInfo())
14581 return E;
14582
14583 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14584 TInfo, E->getEndLoc());
14585 }
14586
14587 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14588 // type. We must not unilaterally enter unevaluated context here, as then
14589 // semantic processing can re-transform an already transformed operand.
14590 Expr *Op = E->getExprOperand();
14591 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14592 if (E->isGLValue()) {
14593 QualType OpType = Op->getType();
14594 if (auto *RD = OpType->getAsCXXRecordDecl()) {
14595 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
14596 DiagID: diag::err_incomplete_typeid))
14597 return ExprError();
14598
14599 if (RD->isPolymorphic())
14600 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14601 }
14602 }
14603
14604 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14605 Sema::ReuseLambdaContextDecl);
14606
14607 ExprResult SubExpr = getDerived().TransformExpr(Op);
14608 if (SubExpr.isInvalid())
14609 return ExprError();
14610
14611 if (!getDerived().AlwaysRebuild() &&
14612 SubExpr.get() == E->getExprOperand())
14613 return E;
14614
14615 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14616 SubExpr.get(), E->getEndLoc());
14617}
14618
14619template<typename Derived>
14620ExprResult
14621TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14622 if (E->isTypeOperand()) {
14623 TypeSourceInfo *TInfo
14624 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14625 if (!TInfo)
14626 return ExprError();
14627
14628 if (!getDerived().AlwaysRebuild() &&
14629 TInfo == E->getTypeOperandSourceInfo())
14630 return E;
14631
14632 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14633 TInfo, E->getEndLoc());
14634 }
14635
14636 EnterExpressionEvaluationContext Unevaluated(
14637 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14638
14639 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14640 if (SubExpr.isInvalid())
14641 return ExprError();
14642
14643 if (!getDerived().AlwaysRebuild() &&
14644 SubExpr.get() == E->getExprOperand())
14645 return E;
14646
14647 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14648 SubExpr.get(), E->getEndLoc());
14649}
14650
14651template<typename Derived>
14652ExprResult
14653TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14654 return E;
14655}
14656
14657template<typename Derived>
14658ExprResult
14659TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14660 CXXNullPtrLiteralExpr *E) {
14661 return E;
14662}
14663
14664template<typename Derived>
14665ExprResult
14666TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14667
14668 // In lambdas, the qualifiers of the type depends of where in
14669 // the call operator `this` appear, and we do not have a good way to
14670 // rebuild this information, so we transform the type.
14671 //
14672 // In other contexts, the type of `this` may be overrided
14673 // for type deduction, so we need to recompute it.
14674 //
14675 // Always recompute the type if we're in the body of a lambda, and
14676 // 'this' is dependent on a lambda's explicit object parameter; we
14677 // also need to always rebuild the expression in this case to clear
14678 // the flag.
14679 QualType T = [&]() {
14680 auto &S = getSema();
14681 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14682 return S.getCurrentThisType();
14683 if (S.getCurLambda())
14684 return getDerived().TransformType(E->getType());
14685 return S.getCurrentThisType();
14686 }();
14687
14688 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
14689 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
14690 // Mark it referenced in the new context regardless.
14691 // FIXME: this is a bit instantiation-specific.
14692 getSema().MarkThisReferenced(E);
14693 return E;
14694 }
14695
14696 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14697}
14698
14699template<typename Derived>
14700ExprResult
14701TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14702 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14703 if (SubExpr.isInvalid())
14704 return ExprError();
14705
14706 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14707
14708 if (!getDerived().AlwaysRebuild() &&
14709 SubExpr.get() == E->getSubExpr())
14710 return E;
14711
14712 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14713 E->isThrownVariableInScope());
14714}
14715
14716template<typename Derived>
14717ExprResult
14718TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14719 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14720 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14721 if (!Param)
14722 return ExprError();
14723
14724 ExprResult InitRes;
14725 if (E->hasRewrittenInit()) {
14726 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14727 if (InitRes.isInvalid())
14728 return ExprError();
14729 }
14730
14731 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14732 E->getUsedContext() == SemaRef.CurContext &&
14733 InitRes.get() == E->getRewrittenExpr())
14734 return E;
14735
14736 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14737 InitRes.get());
14738}
14739
14740template<typename Derived>
14741ExprResult
14742TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14743 FieldDecl *Field = cast_or_null<FieldDecl>(
14744 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14745 if (!Field)
14746 return ExprError();
14747
14748 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14749 E->getUsedContext() == SemaRef.CurContext)
14750 return E;
14751
14752 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14753}
14754
14755template<typename Derived>
14756ExprResult
14757TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14758 CXXScalarValueInitExpr *E) {
14759 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14760 if (!T)
14761 return ExprError();
14762
14763 if (!getDerived().AlwaysRebuild() &&
14764 T == E->getTypeSourceInfo())
14765 return E;
14766
14767 return getDerived().RebuildCXXScalarValueInitExpr(T,
14768 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14769 E->getRParenLoc());
14770}
14771
14772template<typename Derived>
14773ExprResult
14774TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14775 // Transform the type that we're allocating
14776 TypeSourceInfo *AllocTypeInfo =
14777 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14778 if (!AllocTypeInfo)
14779 return ExprError();
14780
14781 // Transform the size of the array we're allocating (if any).
14782 std::optional<Expr *> ArraySize;
14783 if (E->isArray()) {
14784 ExprResult NewArraySize;
14785 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14786 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14787 if (NewArraySize.isInvalid())
14788 return ExprError();
14789 }
14790 ArraySize = NewArraySize.get();
14791 }
14792
14793 // Transform the placement arguments (if any).
14794 bool ArgumentChanged = false;
14795 SmallVector<Expr*, 8> PlacementArgs;
14796 if (getDerived().TransformExprs(E->getPlacementArgs(),
14797 E->getNumPlacementArgs(), true,
14798 PlacementArgs, &ArgumentChanged))
14799 return ExprError();
14800
14801 // Transform the initializer (if any).
14802 Expr *OldInit = E->getInitializer();
14803 ExprResult NewInit;
14804 if (OldInit)
14805 NewInit = getDerived().TransformInitializer(OldInit, true);
14806 if (NewInit.isInvalid())
14807 return ExprError();
14808
14809 // Transform new operator and delete operator.
14810 FunctionDecl *OperatorNew = nullptr;
14811 if (E->getOperatorNew()) {
14812 OperatorNew = cast_or_null<FunctionDecl>(
14813 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14814 if (!OperatorNew)
14815 return ExprError();
14816 }
14817
14818 FunctionDecl *OperatorDelete = nullptr;
14819 if (E->getOperatorDelete()) {
14820 OperatorDelete = cast_or_null<FunctionDecl>(
14821 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14822 if (!OperatorDelete)
14823 return ExprError();
14824 }
14825
14826 if (!getDerived().AlwaysRebuild() &&
14827 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14828 ArraySize == E->getArraySize() &&
14829 NewInit.get() == OldInit &&
14830 OperatorNew == E->getOperatorNew() &&
14831 OperatorDelete == E->getOperatorDelete() &&
14832 !ArgumentChanged) {
14833 // Mark any declarations we need as referenced.
14834 // FIXME: instantiation-specific.
14835 if (OperatorNew)
14836 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14837 if (OperatorDelete)
14838 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14839
14840 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14841 QualType ElementType
14842 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14843 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
14844 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
14845 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14846 }
14847 }
14848
14849 return E;
14850 }
14851
14852 QualType AllocType = AllocTypeInfo->getType();
14853 if (!ArraySize) {
14854 // If no array size was specified, but the new expression was
14855 // instantiated with an array type (e.g., "new T" where T is
14856 // instantiated with "int[4]"), extract the outer bound from the
14857 // array type as our array size. We do this with constant and
14858 // dependently-sized array types.
14859 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14860 if (!ArrayT) {
14861 // Do nothing
14862 } else if (const ConstantArrayType *ConsArrayT
14863 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14864 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14865 type: SemaRef.Context.getSizeType(),
14866 /*FIXME:*/ l: E->getBeginLoc());
14867 AllocType = ConsArrayT->getElementType();
14868 } else if (const DependentSizedArrayType *DepArrayT
14869 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14870 if (DepArrayT->getSizeExpr()) {
14871 ArraySize = DepArrayT->getSizeExpr();
14872 AllocType = DepArrayT->getElementType();
14873 }
14874 }
14875 }
14876
14877 return getDerived().RebuildCXXNewExpr(
14878 E->getBeginLoc(), E->isGlobalNew(),
14879 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14880 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14881 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14882}
14883
14884template<typename Derived>
14885ExprResult
14886TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14887 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14888 if (Operand.isInvalid())
14889 return ExprError();
14890
14891 // Transform the delete operator, if known.
14892 FunctionDecl *OperatorDelete = nullptr;
14893 if (E->getOperatorDelete()) {
14894 OperatorDelete = cast_or_null<FunctionDecl>(
14895 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14896 if (!OperatorDelete)
14897 return ExprError();
14898 }
14899
14900 if (!getDerived().AlwaysRebuild() &&
14901 Operand.get() == E->getArgument() &&
14902 OperatorDelete == E->getOperatorDelete()) {
14903 // Mark any declarations we need as referenced.
14904 // FIXME: instantiation-specific.
14905 if (OperatorDelete)
14906 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14907
14908 if (!E->getArgument()->isTypeDependent()) {
14909 QualType Destroyed = SemaRef.Context.getBaseElementType(
14910 QT: E->getDestroyedType());
14911 if (auto *Record = Destroyed->getAsCXXRecordDecl())
14912 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14913 Func: SemaRef.LookupDestructor(Class: Record));
14914 }
14915
14916 return E;
14917 }
14918
14919 return getDerived().RebuildCXXDeleteExpr(
14920 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14921}
14922
14923template<typename Derived>
14924ExprResult
14925TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14926 CXXPseudoDestructorExpr *E) {
14927 ExprResult Base = getDerived().TransformExpr(E->getBase());
14928 if (Base.isInvalid())
14929 return ExprError();
14930
14931 ParsedType ObjectTypePtr;
14932 bool MayBePseudoDestructor = false;
14933 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14934 OpLoc: E->getOperatorLoc(),
14935 OpKind: E->isArrow()? tok::arrow : tok::period,
14936 ObjectType&: ObjectTypePtr,
14937 MayBePseudoDestructor);
14938 if (Base.isInvalid())
14939 return ExprError();
14940
14941 QualType ObjectType = ObjectTypePtr.get();
14942 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14943 if (QualifierLoc) {
14944 QualifierLoc
14945 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14946 if (!QualifierLoc)
14947 return ExprError();
14948 }
14949 CXXScopeSpec SS;
14950 SS.Adopt(Other: QualifierLoc);
14951
14952 PseudoDestructorTypeStorage Destroyed;
14953 if (E->getDestroyedTypeInfo()) {
14954 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
14955 E->getDestroyedTypeInfo(), ObjectType,
14956 /*FirstQualifierInScope=*/nullptr);
14957 if (!DestroyedTypeInfo)
14958 return ExprError();
14959 Destroyed = DestroyedTypeInfo;
14960 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14961 // We aren't likely to be able to resolve the identifier down to a type
14962 // now anyway, so just retain the identifier.
14963 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14964 E->getDestroyedTypeLoc());
14965 } else {
14966 // Look for a destructor known with the given name.
14967 ParsedType T = SemaRef.getDestructorName(
14968 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14969 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14970 if (!T)
14971 return ExprError();
14972
14973 Destroyed
14974 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14975 Loc: E->getDestroyedTypeLoc());
14976 }
14977
14978 TypeSourceInfo *ScopeTypeInfo = nullptr;
14979 if (E->getScopeTypeInfo()) {
14980 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14981 E->getScopeTypeInfo(), ObjectType, nullptr);
14982 if (!ScopeTypeInfo)
14983 return ExprError();
14984 }
14985
14986 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14987 E->getOperatorLoc(),
14988 E->isArrow(),
14989 SS,
14990 ScopeTypeInfo,
14991 E->getColonColonLoc(),
14992 E->getTildeLoc(),
14993 Destroyed);
14994}
14995
14996template <typename Derived>
14997bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14998 bool RequiresADL,
14999 LookupResult &R) {
15000 // Transform all the decls.
15001 bool AllEmptyPacks = true;
15002 for (auto *OldD : Old->decls()) {
15003 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15004 if (!InstD) {
15005 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15006 // This can happen because of dependent hiding.
15007 if (isa<UsingShadowDecl>(Val: OldD))
15008 continue;
15009 else {
15010 R.clear();
15011 return true;
15012 }
15013 }
15014
15015 // Expand using pack declarations.
15016 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15017 ArrayRef<NamedDecl*> Decls = SingleDecl;
15018 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15019 Decls = UPD->expansions();
15020
15021 // Expand using declarations.
15022 for (auto *D : Decls) {
15023 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15024 for (auto *SD : UD->shadows())
15025 R.addDecl(D: SD);
15026 } else {
15027 R.addDecl(D);
15028 }
15029 }
15030
15031 AllEmptyPacks &= Decls.empty();
15032 }
15033
15034 // C++ [temp.res]/8.4.2:
15035 // The program is ill-formed, no diagnostic required, if [...] lookup for
15036 // a name in the template definition found a using-declaration, but the
15037 // lookup in the corresponding scope in the instantiation odoes not find
15038 // any declarations because the using-declaration was a pack expansion and
15039 // the corresponding pack is empty
15040 if (AllEmptyPacks && !RequiresADL) {
15041 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15042 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15043 return true;
15044 }
15045
15046 // Resolve a kind, but don't do any further analysis. If it's
15047 // ambiguous, the callee needs to deal with it.
15048 R.resolveKind();
15049
15050 if (Old->hasTemplateKeyword() && !R.empty()) {
15051 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15052 getSema().FilterAcceptableTemplateNames(R,
15053 /*AllowFunctionTemplates=*/true,
15054 /*AllowDependent=*/true);
15055 if (R.empty()) {
15056 // If a 'template' keyword was used, a lookup that finds only non-template
15057 // names is an error.
15058 getSema().Diag(R.getNameLoc(),
15059 diag::err_template_kw_refers_to_non_template)
15060 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15061 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15062 getSema().Diag(FoundDecl->getLocation(),
15063 diag::note_template_kw_refers_to_non_template)
15064 << R.getLookupName();
15065 return true;
15066 }
15067 }
15068
15069 return false;
15070}
15071
15072template <typename Derived>
15073ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15074 UnresolvedLookupExpr *Old) {
15075 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15076}
15077
15078template <typename Derived>
15079ExprResult
15080TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15081 bool IsAddressOfOperand) {
15082 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15083 Sema::LookupOrdinaryName);
15084
15085 // Transform the declaration set.
15086 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15087 return ExprError();
15088
15089 // Rebuild the nested-name qualifier, if present.
15090 CXXScopeSpec SS;
15091 if (Old->getQualifierLoc()) {
15092 NestedNameSpecifierLoc QualifierLoc
15093 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15094 if (!QualifierLoc)
15095 return ExprError();
15096
15097 SS.Adopt(Other: QualifierLoc);
15098 }
15099
15100 if (Old->getNamingClass()) {
15101 CXXRecordDecl *NamingClass
15102 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15103 Old->getNameLoc(),
15104 Old->getNamingClass()));
15105 if (!NamingClass) {
15106 R.clear();
15107 return ExprError();
15108 }
15109
15110 R.setNamingClass(NamingClass);
15111 }
15112
15113 // Rebuild the template arguments, if any.
15114 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15115 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15116 if (Old->hasExplicitTemplateArgs() &&
15117 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15118 Old->getNumTemplateArgs(),
15119 TransArgs)) {
15120 R.clear();
15121 return ExprError();
15122 }
15123
15124 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15125 // a non-static data member is named in an unevaluated operand, or when
15126 // a member is named in a dependent class scope function template explicit
15127 // specialization that is neither declared static nor with an explicit object
15128 // parameter.
15129 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15130 return SemaRef.BuildPossibleImplicitMemberExpr(
15131 SS, TemplateKWLoc, R,
15132 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15133 /*S=*/S: nullptr);
15134
15135 // If we have neither explicit template arguments, nor the template keyword,
15136 // it's a normal declaration name or member reference.
15137 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15138 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15139
15140 // If we have template arguments, then rebuild the template-id expression.
15141 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15142 Old->requiresADL(), &TransArgs);
15143}
15144
15145template<typename Derived>
15146ExprResult
15147TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15148 bool ArgChanged = false;
15149 SmallVector<TypeSourceInfo *, 4> Args;
15150 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15151 TypeSourceInfo *From = E->getArg(I);
15152 TypeLoc FromTL = From->getTypeLoc();
15153 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15154 TypeLocBuilder TLB;
15155 TLB.reserve(Requested: FromTL.getFullDataSize());
15156 QualType To = getDerived().TransformType(TLB, FromTL);
15157 if (To.isNull())
15158 return ExprError();
15159
15160 if (To == From->getType())
15161 Args.push_back(Elt: From);
15162 else {
15163 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15164 ArgChanged = true;
15165 }
15166 continue;
15167 }
15168
15169 ArgChanged = true;
15170
15171 // We have a pack expansion. Instantiate it.
15172 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15173 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15174 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15175 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15176
15177 // Determine whether the set of unexpanded parameter packs can and should
15178 // be expanded.
15179 bool Expand = true;
15180 bool RetainExpansion = false;
15181 UnsignedOrNone OrigNumExpansions =
15182 ExpansionTL.getTypePtr()->getNumExpansions();
15183 UnsignedOrNone NumExpansions = OrigNumExpansions;
15184 if (getDerived().TryExpandParameterPacks(
15185 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15186 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15187 RetainExpansion, NumExpansions))
15188 return ExprError();
15189
15190 if (!Expand) {
15191 // The transform has determined that we should perform a simple
15192 // transformation on the pack expansion, producing another pack
15193 // expansion.
15194 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15195
15196 TypeLocBuilder TLB;
15197 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15198
15199 QualType To = getDerived().TransformType(TLB, PatternTL);
15200 if (To.isNull())
15201 return ExprError();
15202
15203 To = getDerived().RebuildPackExpansionType(To,
15204 PatternTL.getSourceRange(),
15205 ExpansionTL.getEllipsisLoc(),
15206 NumExpansions);
15207 if (To.isNull())
15208 return ExprError();
15209
15210 PackExpansionTypeLoc ToExpansionTL
15211 = TLB.push<PackExpansionTypeLoc>(T: To);
15212 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15213 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15214 continue;
15215 }
15216
15217 // Expand the pack expansion by substituting for each argument in the
15218 // pack(s).
15219 for (unsigned I = 0; I != *NumExpansions; ++I) {
15220 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15221 TypeLocBuilder TLB;
15222 TLB.reserve(Requested: PatternTL.getFullDataSize());
15223 QualType To = getDerived().TransformType(TLB, PatternTL);
15224 if (To.isNull())
15225 return ExprError();
15226
15227 if (To->containsUnexpandedParameterPack()) {
15228 To = getDerived().RebuildPackExpansionType(To,
15229 PatternTL.getSourceRange(),
15230 ExpansionTL.getEllipsisLoc(),
15231 NumExpansions);
15232 if (To.isNull())
15233 return ExprError();
15234
15235 PackExpansionTypeLoc ToExpansionTL
15236 = TLB.push<PackExpansionTypeLoc>(T: To);
15237 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15238 }
15239
15240 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15241 }
15242
15243 if (!RetainExpansion)
15244 continue;
15245
15246 // If we're supposed to retain a pack expansion, do so by temporarily
15247 // forgetting the partially-substituted parameter pack.
15248 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15249
15250 TypeLocBuilder TLB;
15251 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15252
15253 QualType To = getDerived().TransformType(TLB, PatternTL);
15254 if (To.isNull())
15255 return ExprError();
15256
15257 To = getDerived().RebuildPackExpansionType(To,
15258 PatternTL.getSourceRange(),
15259 ExpansionTL.getEllipsisLoc(),
15260 NumExpansions);
15261 if (To.isNull())
15262 return ExprError();
15263
15264 PackExpansionTypeLoc ToExpansionTL
15265 = TLB.push<PackExpansionTypeLoc>(T: To);
15266 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15267 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15268 }
15269
15270 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15271 return E;
15272
15273 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15274 E->getEndLoc());
15275}
15276
15277template<typename Derived>
15278ExprResult
15279TreeTransform<Derived>::TransformConceptSpecializationExpr(
15280 ConceptSpecializationExpr *E) {
15281 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15282 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15283 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15284 Old->NumTemplateArgs, TransArgs))
15285 return ExprError();
15286
15287 return getDerived().RebuildConceptSpecializationExpr(
15288 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15289 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
15290 &TransArgs);
15291}
15292
15293template<typename Derived>
15294ExprResult
15295TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15296 SmallVector<ParmVarDecl*, 4> TransParams;
15297 SmallVector<QualType, 4> TransParamTypes;
15298 Sema::ExtParameterInfoBuilder ExtParamInfos;
15299
15300 // C++2a [expr.prim.req]p2
15301 // Expressions appearing within a requirement-body are unevaluated operands.
15302 EnterExpressionEvaluationContext Ctx(
15303 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15304 Sema::ReuseLambdaContextDecl);
15305
15306 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15307 C&: getSema().Context, DC: getSema().CurContext,
15308 StartLoc: E->getBody()->getBeginLoc());
15309
15310 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15311
15312 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15313 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15314 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15315
15316 for (ParmVarDecl *Param : TransParams)
15317 if (Param)
15318 Param->setDeclContext(Body);
15319
15320 // On failure to transform, TransformRequiresTypeParams returns an expression
15321 // in the event that the transformation of the type params failed in some way.
15322 // It is expected that this will result in a 'not satisfied' Requires clause
15323 // when instantiating.
15324 if (!TypeParamResult.isUnset())
15325 return TypeParamResult;
15326
15327 SmallVector<concepts::Requirement *, 4> TransReqs;
15328 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15329 TransReqs))
15330 return ExprError();
15331
15332 for (concepts::Requirement *Req : TransReqs) {
15333 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15334 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15335 ER->getReturnTypeRequirement()
15336 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15337 ->setDeclContext(Body);
15338 }
15339 }
15340 }
15341
15342 return getDerived().RebuildRequiresExpr(
15343 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15344 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15345}
15346
15347template<typename Derived>
15348bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15349 ArrayRef<concepts::Requirement *> Reqs,
15350 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15351 for (concepts::Requirement *Req : Reqs) {
15352 concepts::Requirement *TransReq = nullptr;
15353 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15354 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15355 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15356 TransReq = getDerived().TransformExprRequirement(ExprReq);
15357 else
15358 TransReq = getDerived().TransformNestedRequirement(
15359 cast<concepts::NestedRequirement>(Val: Req));
15360 if (!TransReq)
15361 return true;
15362 Transformed.push_back(Elt: TransReq);
15363 }
15364 return false;
15365}
15366
15367template<typename Derived>
15368concepts::TypeRequirement *
15369TreeTransform<Derived>::TransformTypeRequirement(
15370 concepts::TypeRequirement *Req) {
15371 if (Req->isSubstitutionFailure()) {
15372 if (getDerived().AlwaysRebuild())
15373 return getDerived().RebuildTypeRequirement(
15374 Req->getSubstitutionDiagnostic());
15375 return Req;
15376 }
15377 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15378 if (!TransType)
15379 return nullptr;
15380 return getDerived().RebuildTypeRequirement(TransType);
15381}
15382
15383template<typename Derived>
15384concepts::ExprRequirement *
15385TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15386 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15387 if (Req->isExprSubstitutionFailure())
15388 TransExpr = Req->getExprSubstitutionDiagnostic();
15389 else {
15390 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15391 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15392 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15393 if (TransExprRes.isInvalid())
15394 return nullptr;
15395 TransExpr = TransExprRes.get();
15396 }
15397
15398 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15399 const auto &RetReq = Req->getReturnTypeRequirement();
15400 if (RetReq.isEmpty())
15401 TransRetReq.emplace();
15402 else if (RetReq.isSubstitutionFailure())
15403 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15404 else if (RetReq.isTypeConstraint()) {
15405 TemplateParameterList *OrigTPL =
15406 RetReq.getTypeConstraintTemplateParameterList();
15407 TemplateParameterList *TPL =
15408 getDerived().TransformTemplateParameterList(OrigTPL);
15409 if (!TPL)
15410 return nullptr;
15411 TransRetReq.emplace(args&: TPL);
15412 }
15413 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15414 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15415 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15416 Req->getNoexceptLoc(),
15417 std::move(*TransRetReq));
15418 return getDerived().RebuildExprRequirement(
15419 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15420 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15421}
15422
15423template<typename Derived>
15424concepts::NestedRequirement *
15425TreeTransform<Derived>::TransformNestedRequirement(
15426 concepts::NestedRequirement *Req) {
15427 if (Req->hasInvalidConstraint()) {
15428 if (getDerived().AlwaysRebuild())
15429 return getDerived().RebuildNestedRequirement(
15430 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15431 return Req;
15432 }
15433 ExprResult TransConstraint =
15434 getDerived().TransformExpr(Req->getConstraintExpr());
15435 if (TransConstraint.isInvalid())
15436 return nullptr;
15437 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15438}
15439
15440template<typename Derived>
15441ExprResult
15442TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15443 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15444 if (!T)
15445 return ExprError();
15446
15447 if (!getDerived().AlwaysRebuild() &&
15448 T == E->getQueriedTypeSourceInfo())
15449 return E;
15450
15451 ExprResult SubExpr;
15452 {
15453 EnterExpressionEvaluationContext Unevaluated(
15454 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15455 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15456 if (SubExpr.isInvalid())
15457 return ExprError();
15458 }
15459
15460 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15461 SubExpr.get(), E->getEndLoc());
15462}
15463
15464template<typename Derived>
15465ExprResult
15466TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15467 ExprResult SubExpr;
15468 {
15469 EnterExpressionEvaluationContext Unevaluated(
15470 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15471 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15472 if (SubExpr.isInvalid())
15473 return ExprError();
15474
15475 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15476 return E;
15477 }
15478
15479 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15480 SubExpr.get(), E->getEndLoc());
15481}
15482
15483template <typename Derived>
15484ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15485 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15486 TypeSourceInfo **RecoveryTSI) {
15487 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15488 DRE, AddrTaken, RecoveryTSI);
15489
15490 // Propagate both errors and recovered types, which return ExprEmpty.
15491 if (!NewDRE.isUsable())
15492 return NewDRE;
15493
15494 // We got an expr, wrap it up in parens.
15495 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15496 return PE;
15497 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15498 PE->getRParen());
15499}
15500
15501template <typename Derived>
15502ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15503 DependentScopeDeclRefExpr *E) {
15504 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15505 nullptr);
15506}
15507
15508template <typename Derived>
15509ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15510 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15511 TypeSourceInfo **RecoveryTSI) {
15512 assert(E->getQualifierLoc());
15513 NestedNameSpecifierLoc QualifierLoc =
15514 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15515 if (!QualifierLoc)
15516 return ExprError();
15517 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15518
15519 // TODO: If this is a conversion-function-id, verify that the
15520 // destination type name (if present) resolves the same way after
15521 // instantiation as it did in the local scope.
15522
15523 DeclarationNameInfo NameInfo =
15524 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15525 if (!NameInfo.getName())
15526 return ExprError();
15527
15528 if (!E->hasExplicitTemplateArgs()) {
15529 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15530 // Note: it is sufficient to compare the Name component of NameInfo:
15531 // if name has not changed, DNLoc has not changed either.
15532 NameInfo.getName() == E->getDeclName())
15533 return E;
15534
15535 return getDerived().RebuildDependentScopeDeclRefExpr(
15536 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15537 IsAddressOfOperand, RecoveryTSI);
15538 }
15539
15540 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15541 if (getDerived().TransformTemplateArguments(
15542 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15543 return ExprError();
15544
15545 return getDerived().RebuildDependentScopeDeclRefExpr(
15546 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15547 RecoveryTSI);
15548}
15549
15550template<typename Derived>
15551ExprResult
15552TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15553 // CXXConstructExprs other than for list-initialization and
15554 // CXXTemporaryObjectExpr are always implicit, so when we have
15555 // a 1-argument construction we just transform that argument.
15556 if (getDerived().AllowSkippingCXXConstructExpr() &&
15557 ((E->getNumArgs() == 1 ||
15558 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15559 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15560 !E->isListInitialization()))
15561 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15562 /*DirectInit*/ false);
15563
15564 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15565
15566 QualType T = getDerived().TransformType(E->getType());
15567 if (T.isNull())
15568 return ExprError();
15569
15570 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15571 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15572 if (!Constructor)
15573 return ExprError();
15574
15575 bool ArgumentChanged = false;
15576 SmallVector<Expr*, 8> Args;
15577 {
15578 EnterExpressionEvaluationContext Context(
15579 getSema(), EnterExpressionEvaluationContext::InitList,
15580 E->isListInitialization());
15581 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15582 &ArgumentChanged))
15583 return ExprError();
15584 }
15585
15586 if (!getDerived().AlwaysRebuild() &&
15587 T == E->getType() &&
15588 Constructor == E->getConstructor() &&
15589 !ArgumentChanged) {
15590 // Mark the constructor as referenced.
15591 // FIXME: Instantiation-specific
15592 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15593 return E;
15594 }
15595
15596 return getDerived().RebuildCXXConstructExpr(
15597 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15598 E->hadMultipleCandidates(), E->isListInitialization(),
15599 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15600 E->getConstructionKind(), E->getParenOrBraceRange());
15601}
15602
15603template<typename Derived>
15604ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15605 CXXInheritedCtorInitExpr *E) {
15606 QualType T = getDerived().TransformType(E->getType());
15607 if (T.isNull())
15608 return ExprError();
15609
15610 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15611 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15612 if (!Constructor)
15613 return ExprError();
15614
15615 if (!getDerived().AlwaysRebuild() &&
15616 T == E->getType() &&
15617 Constructor == E->getConstructor()) {
15618 // Mark the constructor as referenced.
15619 // FIXME: Instantiation-specific
15620 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15621 return E;
15622 }
15623
15624 return getDerived().RebuildCXXInheritedCtorInitExpr(
15625 T, E->getLocation(), Constructor,
15626 E->constructsVBase(), E->inheritedFromVBase());
15627}
15628
15629/// Transform a C++ temporary-binding expression.
15630///
15631/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15632/// transform the subexpression and return that.
15633template<typename Derived>
15634ExprResult
15635TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15636 if (auto *Dtor = E->getTemporary()->getDestructor())
15637 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15638 Func: const_cast<CXXDestructorDecl *>(Dtor));
15639 return getDerived().TransformExpr(E->getSubExpr());
15640}
15641
15642/// Transform a C++ expression that contains cleanups that should
15643/// be run after the expression is evaluated.
15644///
15645/// Since ExprWithCleanups nodes are implicitly generated, we
15646/// just transform the subexpression and return that.
15647template<typename Derived>
15648ExprResult
15649TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15650 return getDerived().TransformExpr(E->getSubExpr());
15651}
15652
15653template<typename Derived>
15654ExprResult
15655TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15656 CXXTemporaryObjectExpr *E) {
15657 TypeSourceInfo *T =
15658 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15659 if (!T)
15660 return ExprError();
15661
15662 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15663 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15664 if (!Constructor)
15665 return ExprError();
15666
15667 bool ArgumentChanged = false;
15668 SmallVector<Expr*, 8> Args;
15669 Args.reserve(N: E->getNumArgs());
15670 {
15671 EnterExpressionEvaluationContext Context(
15672 getSema(), EnterExpressionEvaluationContext::InitList,
15673 E->isListInitialization());
15674 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15675 ArgChanged: &ArgumentChanged))
15676 return ExprError();
15677
15678 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15679 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15680 if (Res.isInvalid())
15681 return ExprError();
15682 Args = {Res.get()};
15683 }
15684 }
15685
15686 if (!getDerived().AlwaysRebuild() &&
15687 T == E->getTypeSourceInfo() &&
15688 Constructor == E->getConstructor() &&
15689 !ArgumentChanged) {
15690 // FIXME: Instantiation-specific
15691 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15692 return SemaRef.MaybeBindToTemporary(E);
15693 }
15694
15695 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15696 return getDerived().RebuildCXXTemporaryObjectExpr(
15697 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15698}
15699
15700template<typename Derived>
15701ExprResult
15702TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15703 // Transform any init-capture expressions before entering the scope of the
15704 // lambda body, because they are not semantically within that scope.
15705 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15706 struct TransformedInitCapture {
15707 // The location of the ... if the result is retaining a pack expansion.
15708 SourceLocation EllipsisLoc;
15709 // Zero or more expansions of the init-capture.
15710 SmallVector<InitCaptureInfoTy, 4> Expansions;
15711 };
15712 SmallVector<TransformedInitCapture, 4> InitCaptures;
15713 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15714 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15715 CEnd = E->capture_end();
15716 C != CEnd; ++C) {
15717 if (!E->isInitCapture(Capture: C))
15718 continue;
15719
15720 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15721 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15722
15723 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15724 UnsignedOrNone NumExpansions) {
15725 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15726 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15727
15728 if (NewExprInitResult.isInvalid()) {
15729 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15730 return;
15731 }
15732 Expr *NewExprInit = NewExprInitResult.get();
15733
15734 QualType NewInitCaptureType =
15735 getSema().buildLambdaInitCaptureInitialization(
15736 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15737 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15738 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15739 VarDecl::CInit,
15740 NewExprInit);
15741 Result.Expansions.push_back(
15742 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15743 };
15744
15745 // If this is an init-capture pack, consider expanding the pack now.
15746 if (OldVD->isParameterPack()) {
15747 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15748 ->getTypeLoc()
15749 .castAs<PackExpansionTypeLoc>();
15750 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15751 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15752
15753 // Determine whether the set of unexpanded parameter packs can and should
15754 // be expanded.
15755 bool Expand = true;
15756 bool RetainExpansion = false;
15757 UnsignedOrNone OrigNumExpansions =
15758 ExpansionTL.getTypePtr()->getNumExpansions();
15759 UnsignedOrNone NumExpansions = OrigNumExpansions;
15760 if (getDerived().TryExpandParameterPacks(
15761 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
15762 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15763 RetainExpansion, NumExpansions))
15764 return ExprError();
15765 assert(!RetainExpansion && "Should not need to retain expansion after a "
15766 "capture since it cannot be extended");
15767 if (Expand) {
15768 for (unsigned I = 0; I != *NumExpansions; ++I) {
15769 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15770 SubstInitCapture(SourceLocation(), std::nullopt);
15771 }
15772 } else {
15773 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15774 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15775 }
15776 } else {
15777 SubstInitCapture(SourceLocation(), std::nullopt);
15778 }
15779 }
15780
15781 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15782 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15783
15784 // Create the local class that will describe the lambda.
15785
15786 // FIXME: DependencyKind below is wrong when substituting inside a templated
15787 // context that isn't a DeclContext (such as a variable template), or when
15788 // substituting an unevaluated lambda inside of a function's parameter's type
15789 // - as parameter types are not instantiated from within a function's DC. We
15790 // use evaluation contexts to distinguish the function parameter case.
15791 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15792 CXXRecordDecl::LDK_Unknown;
15793 DeclContext *DC = getSema().CurContext;
15794 // A RequiresExprBodyDecl is not interesting for dependencies.
15795 // For the following case,
15796 //
15797 // template <typename>
15798 // concept C = requires { [] {}; };
15799 //
15800 // template <class F>
15801 // struct Widget;
15802 //
15803 // template <C F>
15804 // struct Widget<F> {};
15805 //
15806 // While we are substituting Widget<F>, the parent of DC would be
15807 // the template specialization itself. Thus, the lambda expression
15808 // will be deemed as dependent even if there are no dependent template
15809 // arguments.
15810 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15811 while (DC->isRequiresExprBody())
15812 DC = DC->getParent();
15813 if ((getSema().isUnevaluatedContext() ||
15814 getSema().isConstantEvaluatedContext()) &&
15815 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
15816 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
15817 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15818 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15819
15820 CXXRecordDecl *OldClass = E->getLambdaClass();
15821 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15822 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15823 E->getCaptureDefault());
15824 getDerived().transformedLocalDecl(OldClass, {Class});
15825
15826 CXXMethodDecl *NewCallOperator =
15827 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15828
15829 // Enter the scope of the lambda.
15830 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15831 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15832 E->hasExplicitParameters(), E->isMutable());
15833
15834 // Introduce the context of the call operator.
15835 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15836 /*NewThisContext*/false);
15837
15838 bool Invalid = false;
15839
15840 // Transform captures.
15841 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15842 CEnd = E->capture_end();
15843 C != CEnd; ++C) {
15844 // When we hit the first implicit capture, tell Sema that we've finished
15845 // the list of explicit captures.
15846 if (C->isImplicit())
15847 break;
15848
15849 // Capturing 'this' is trivial.
15850 if (C->capturesThis()) {
15851 // If this is a lambda that is part of a default member initialiser
15852 // and which we're instantiating outside the class that 'this' is
15853 // supposed to refer to, adjust the type of 'this' accordingly.
15854 //
15855 // Otherwise, leave the type of 'this' as-is.
15856 Sema::CXXThisScopeRAII ThisScope(
15857 getSema(),
15858 dyn_cast_if_present<CXXRecordDecl>(
15859 getSema().getFunctionLevelDeclContext()),
15860 Qualifiers());
15861 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15862 /*BuildAndDiagnose*/ true, nullptr,
15863 C->getCaptureKind() == LCK_StarThis);
15864 continue;
15865 }
15866 // Captured expression will be recaptured during captured variables
15867 // rebuilding.
15868 if (C->capturesVLAType())
15869 continue;
15870
15871 // Rebuild init-captures, including the implied field declaration.
15872 if (E->isInitCapture(Capture: C)) {
15873 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15874
15875 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15876 llvm::SmallVector<Decl*, 4> NewVDs;
15877
15878 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15879 ExprResult Init = Info.first;
15880 QualType InitQualType = Info.second;
15881 if (Init.isInvalid() || InitQualType.isNull()) {
15882 Invalid = true;
15883 break;
15884 }
15885 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15886 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15887 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15888 getSema().CurContext);
15889 if (!NewVD) {
15890 Invalid = true;
15891 break;
15892 }
15893 NewVDs.push_back(Elt: NewVD);
15894 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15895 // Cases we want to tackle:
15896 // ([C(Pack)] {}, ...)
15897 // But rule out cases e.g.
15898 // [...C = Pack()] {}
15899 if (NewC.EllipsisLoc.isInvalid())
15900 LSI->ContainsUnexpandedParameterPack |=
15901 Init.get()->containsUnexpandedParameterPack();
15902 }
15903
15904 if (Invalid)
15905 break;
15906
15907 getDerived().transformedLocalDecl(OldVD, NewVDs);
15908 continue;
15909 }
15910
15911 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15912
15913 // Determine the capture kind for Sema.
15914 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15915 : C->getCaptureKind() == LCK_ByCopy
15916 ? TryCaptureKind::ExplicitByVal
15917 : TryCaptureKind::ExplicitByRef;
15918 SourceLocation EllipsisLoc;
15919 if (C->isPackExpansion()) {
15920 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15921 bool ShouldExpand = false;
15922 bool RetainExpansion = false;
15923 UnsignedOrNone NumExpansions = std::nullopt;
15924 if (getDerived().TryExpandParameterPacks(
15925 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
15926 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
15927 RetainExpansion, NumExpansions)) {
15928 Invalid = true;
15929 continue;
15930 }
15931
15932 if (ShouldExpand) {
15933 // The transform has determined that we should perform an expansion;
15934 // transform and capture each of the arguments.
15935 // expansion of the pattern. Do so.
15936 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
15937 for (unsigned I = 0; I != *NumExpansions; ++I) {
15938 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15939 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15940 getDerived().TransformDecl(C->getLocation(), Pack));
15941 if (!CapturedVar) {
15942 Invalid = true;
15943 continue;
15944 }
15945
15946 // Capture the transformed variable.
15947 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15948 }
15949
15950 // FIXME: Retain a pack expansion if RetainExpansion is true.
15951
15952 continue;
15953 }
15954
15955 EllipsisLoc = C->getEllipsisLoc();
15956 }
15957
15958 // Transform the captured variable.
15959 auto *CapturedVar = cast_or_null<ValueDecl>(
15960 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15961 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15962 Invalid = true;
15963 continue;
15964 }
15965
15966 // This is not an init-capture; however it contains an unexpanded pack e.g.
15967 // ([Pack] {}(), ...)
15968 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15969 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15970
15971 // Capture the transformed variable.
15972 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15973 EllipsisLoc);
15974 }
15975 getSema().finishLambdaExplicitCaptures(LSI);
15976
15977 // Transform the template parameters, and add them to the current
15978 // instantiation scope. The null case is handled correctly.
15979 auto TPL = getDerived().TransformTemplateParameterList(
15980 E->getTemplateParameterList());
15981 LSI->GLTemplateParameterList = TPL;
15982 if (TPL) {
15983 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15984 TPL);
15985 LSI->ContainsUnexpandedParameterPack |=
15986 TPL->containsUnexpandedParameterPack();
15987 }
15988
15989 TypeLocBuilder NewCallOpTLBuilder;
15990 TypeLoc OldCallOpTypeLoc =
15991 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15992 QualType NewCallOpType =
15993 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15994 if (NewCallOpType.isNull())
15995 return ExprError();
15996 LSI->ContainsUnexpandedParameterPack |=
15997 NewCallOpType->containsUnexpandedParameterPack();
15998 TypeSourceInfo *NewCallOpTSI =
15999 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16000
16001 // The type may be an AttributedType or some other kind of sugar;
16002 // get the actual underlying FunctionProtoType.
16003 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16004 assert(FPTL && "Not a FunctionProtoType?");
16005
16006 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16007 if (!TRC.ArgPackSubstIndex)
16008 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
16009
16010 getSema().CompleteLambdaCallOperator(
16011 NewCallOperator, E->getCallOperator()->getLocation(),
16012 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16013 E->getCallOperator()->getConstexprKind(),
16014 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16015 E->hasExplicitResultType());
16016
16017 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16018 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16019
16020 {
16021 // Number the lambda for linkage purposes if necessary.
16022 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16023
16024 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16025 if (getDerived().ReplacingOriginal()) {
16026 Numbering = OldClass->getLambdaNumbering();
16027 }
16028
16029 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16030 }
16031
16032 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16033 // evaluation context even if we're not transforming the function body.
16034 getSema().PushExpressionEvaluationContextForFunction(
16035 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16036 E->getCallOperator());
16037
16038 StmtResult Body;
16039 {
16040 Sema::NonSFINAEContext _(getSema());
16041 Sema::CodeSynthesisContext C;
16042 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16043 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16044 getSema().pushCodeSynthesisContext(C);
16045
16046 // Instantiate the body of the lambda expression.
16047 Body = Invalid ? StmtError()
16048 : getDerived().TransformLambdaBody(E, E->getBody());
16049
16050 getSema().popCodeSynthesisContext();
16051 }
16052
16053 // ActOnLambda* will pop the function scope for us.
16054 FuncScopeCleanup.disable();
16055
16056 if (Body.isInvalid()) {
16057 SavedContext.pop();
16058 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16059 /*IsInstantiation=*/true);
16060 return ExprError();
16061 }
16062
16063 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16064 /*IsInstantiation=*/true,
16065 /*RetainFunctionScopeInfo=*/true);
16066 SavedContext.pop();
16067
16068 // Recompute the dependency of the lambda so that we can defer the lambda call
16069 // construction until after we have all the necessary template arguments. For
16070 // example, given
16071 //
16072 // template <class> struct S {
16073 // template <class U>
16074 // using Type = decltype([](U){}(42.0));
16075 // };
16076 // void foo() {
16077 // using T = S<int>::Type<float>;
16078 // ^~~~~~
16079 // }
16080 //
16081 // We would end up here from instantiating S<int> when ensuring its
16082 // completeness. That would transform the lambda call expression regardless of
16083 // the absence of the corresponding argument for U.
16084 //
16085 // Going ahead with unsubstituted type U makes things worse: we would soon
16086 // compare the argument type (which is float) against the parameter U
16087 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16088 // error suggesting unmatched types 'U' and 'float'!
16089 //
16090 // That said, everything will be fine if we defer that semantic checking.
16091 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16092 // dependent. Since the CallExpr's dependency boils down to the lambda's
16093 // dependency in this case, we can harness that by recomputing the dependency
16094 // from the instantiation arguments.
16095 //
16096 // FIXME: Creating the type of a lambda requires us to have a dependency
16097 // value, which happens before its substitution. We update its dependency
16098 // *after* the substitution in case we can't decide the dependency
16099 // so early, e.g. because we want to see if any of the *substituted*
16100 // parameters are dependent.
16101 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16102 Class->setLambdaDependencyKind(DependencyKind);
16103
16104 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16105 Body.get()->getEndLoc(), LSI);
16106}
16107
16108template<typename Derived>
16109StmtResult
16110TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16111 return TransformStmt(S);
16112}
16113
16114template<typename Derived>
16115StmtResult
16116TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16117 // Transform captures.
16118 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16119 CEnd = E->capture_end();
16120 C != CEnd; ++C) {
16121 // When we hit the first implicit capture, tell Sema that we've finished
16122 // the list of explicit captures.
16123 if (!C->isImplicit())
16124 continue;
16125
16126 // Capturing 'this' is trivial.
16127 if (C->capturesThis()) {
16128 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16129 /*BuildAndDiagnose*/ true, nullptr,
16130 C->getCaptureKind() == LCK_StarThis);
16131 continue;
16132 }
16133 // Captured expression will be recaptured during captured variables
16134 // rebuilding.
16135 if (C->capturesVLAType())
16136 continue;
16137
16138 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16139 assert(!E->isInitCapture(C) && "implicit init-capture?");
16140
16141 // Transform the captured variable.
16142 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16143 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16144 if (!CapturedVar || CapturedVar->isInvalidDecl())
16145 return StmtError();
16146
16147 // Capture the transformed variable.
16148 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16149 }
16150
16151 return S;
16152}
16153
16154template<typename Derived>
16155ExprResult
16156TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16157 CXXUnresolvedConstructExpr *E) {
16158 TypeSourceInfo *T =
16159 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16160 if (!T)
16161 return ExprError();
16162
16163 bool ArgumentChanged = false;
16164 SmallVector<Expr*, 8> Args;
16165 Args.reserve(N: E->getNumArgs());
16166 {
16167 EnterExpressionEvaluationContext Context(
16168 getSema(), EnterExpressionEvaluationContext::InitList,
16169 E->isListInitialization());
16170 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16171 &ArgumentChanged))
16172 return ExprError();
16173 }
16174
16175 if (!getDerived().AlwaysRebuild() &&
16176 T == E->getTypeSourceInfo() &&
16177 !ArgumentChanged)
16178 return E;
16179
16180 // FIXME: we're faking the locations of the commas
16181 return getDerived().RebuildCXXUnresolvedConstructExpr(
16182 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16183}
16184
16185template<typename Derived>
16186ExprResult
16187TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16188 CXXDependentScopeMemberExpr *E) {
16189 // Transform the base of the expression.
16190 ExprResult Base((Expr*) nullptr);
16191 Expr *OldBase;
16192 QualType BaseType;
16193 QualType ObjectType;
16194 if (!E->isImplicitAccess()) {
16195 OldBase = E->getBase();
16196 Base = getDerived().TransformExpr(OldBase);
16197 if (Base.isInvalid())
16198 return ExprError();
16199
16200 // Start the member reference and compute the object's type.
16201 ParsedType ObjectTy;
16202 bool MayBePseudoDestructor = false;
16203 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16204 OpLoc: E->getOperatorLoc(),
16205 OpKind: E->isArrow()? tok::arrow : tok::period,
16206 ObjectType&: ObjectTy,
16207 MayBePseudoDestructor);
16208 if (Base.isInvalid())
16209 return ExprError();
16210
16211 ObjectType = ObjectTy.get();
16212 BaseType = ((Expr*) Base.get())->getType();
16213 } else {
16214 OldBase = nullptr;
16215 BaseType = getDerived().TransformType(E->getBaseType());
16216 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16217 }
16218
16219 // Transform the first part of the nested-name-specifier that qualifies
16220 // the member name.
16221 NamedDecl *FirstQualifierInScope
16222 = getDerived().TransformFirstQualifierInScope(
16223 E->getFirstQualifierFoundInScope(),
16224 E->getQualifierLoc().getBeginLoc());
16225
16226 NestedNameSpecifierLoc QualifierLoc;
16227 if (E->getQualifier()) {
16228 QualifierLoc
16229 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16230 ObjectType,
16231 FirstQualifierInScope);
16232 if (!QualifierLoc)
16233 return ExprError();
16234 }
16235
16236 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16237
16238 // TODO: If this is a conversion-function-id, verify that the
16239 // destination type name (if present) resolves the same way after
16240 // instantiation as it did in the local scope.
16241
16242 DeclarationNameInfo NameInfo
16243 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16244 if (!NameInfo.getName())
16245 return ExprError();
16246
16247 if (!E->hasExplicitTemplateArgs()) {
16248 // This is a reference to a member without an explicitly-specified
16249 // template argument list. Optimize for this common case.
16250 if (!getDerived().AlwaysRebuild() &&
16251 Base.get() == OldBase &&
16252 BaseType == E->getBaseType() &&
16253 QualifierLoc == E->getQualifierLoc() &&
16254 NameInfo.getName() == E->getMember() &&
16255 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16256 return E;
16257
16258 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16259 BaseType,
16260 E->isArrow(),
16261 E->getOperatorLoc(),
16262 QualifierLoc,
16263 TemplateKWLoc,
16264 FirstQualifierInScope,
16265 NameInfo,
16266 /*TemplateArgs*/nullptr);
16267 }
16268
16269 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16270 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16271 E->getNumTemplateArgs(),
16272 TransArgs))
16273 return ExprError();
16274
16275 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16276 BaseType,
16277 E->isArrow(),
16278 E->getOperatorLoc(),
16279 QualifierLoc,
16280 TemplateKWLoc,
16281 FirstQualifierInScope,
16282 NameInfo,
16283 &TransArgs);
16284}
16285
16286template <typename Derived>
16287ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16288 UnresolvedMemberExpr *Old) {
16289 // Transform the base of the expression.
16290 ExprResult Base((Expr *)nullptr);
16291 QualType BaseType;
16292 if (!Old->isImplicitAccess()) {
16293 Base = getDerived().TransformExpr(Old->getBase());
16294 if (Base.isInvalid())
16295 return ExprError();
16296 Base =
16297 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16298 if (Base.isInvalid())
16299 return ExprError();
16300 BaseType = Base.get()->getType();
16301 } else {
16302 BaseType = getDerived().TransformType(Old->getBaseType());
16303 }
16304
16305 NestedNameSpecifierLoc QualifierLoc;
16306 if (Old->getQualifierLoc()) {
16307 QualifierLoc =
16308 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16309 if (!QualifierLoc)
16310 return ExprError();
16311 }
16312
16313 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16314
16315 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16316
16317 // Transform the declaration set.
16318 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16319 return ExprError();
16320
16321 // Determine the naming class.
16322 if (Old->getNamingClass()) {
16323 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16324 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16325 if (!NamingClass)
16326 return ExprError();
16327
16328 R.setNamingClass(NamingClass);
16329 }
16330
16331 TemplateArgumentListInfo TransArgs;
16332 if (Old->hasExplicitTemplateArgs()) {
16333 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16334 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16335 if (getDerived().TransformTemplateArguments(
16336 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16337 return ExprError();
16338 }
16339
16340 // FIXME: to do this check properly, we will need to preserve the
16341 // first-qualifier-in-scope here, just in case we had a dependent
16342 // base (and therefore couldn't do the check) and a
16343 // nested-name-qualifier (and therefore could do the lookup).
16344 NamedDecl *FirstQualifierInScope = nullptr;
16345
16346 return getDerived().RebuildUnresolvedMemberExpr(
16347 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16348 TemplateKWLoc, FirstQualifierInScope, R,
16349 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16350}
16351
16352template<typename Derived>
16353ExprResult
16354TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16355 EnterExpressionEvaluationContext Unevaluated(
16356 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16357 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16358 if (SubExpr.isInvalid())
16359 return ExprError();
16360
16361 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16362 return E;
16363
16364 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16365}
16366
16367template<typename Derived>
16368ExprResult
16369TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16370 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16371 if (Pattern.isInvalid())
16372 return ExprError();
16373
16374 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16375 return E;
16376
16377 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16378 E->getNumExpansions());
16379}
16380
16381template <typename Derived>
16382UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16383 ArrayRef<TemplateArgument> PackArgs) {
16384 UnsignedOrNone Result = 0u;
16385 for (const TemplateArgument &Arg : PackArgs) {
16386 if (!Arg.isPackExpansion()) {
16387 Result = *Result + 1;
16388 continue;
16389 }
16390
16391 TemplateArgumentLoc ArgLoc;
16392 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16393
16394 // Find the pattern of the pack expansion.
16395 SourceLocation Ellipsis;
16396 UnsignedOrNone OrigNumExpansions = std::nullopt;
16397 TemplateArgumentLoc Pattern =
16398 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16399 OrigNumExpansions);
16400
16401 // Substitute under the pack expansion. Do not expand the pack (yet).
16402 TemplateArgumentLoc OutPattern;
16403 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16404 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16405 /*Uneval*/ true))
16406 return 1u;
16407
16408 // See if we can determine the number of arguments from the result.
16409 UnsignedOrNone NumExpansions =
16410 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16411 if (!NumExpansions) {
16412 // No: we must be in an alias template expansion, and we're going to
16413 // need to actually expand the packs.
16414 Result = std::nullopt;
16415 break;
16416 }
16417
16418 Result = *Result + *NumExpansions;
16419 }
16420 return Result;
16421}
16422
16423template<typename Derived>
16424ExprResult
16425TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16426 // If E is not value-dependent, then nothing will change when we transform it.
16427 // Note: This is an instantiation-centric view.
16428 if (!E->isValueDependent())
16429 return E;
16430
16431 EnterExpressionEvaluationContext Unevaluated(
16432 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16433
16434 ArrayRef<TemplateArgument> PackArgs;
16435 TemplateArgument ArgStorage;
16436
16437 // Find the argument list to transform.
16438 if (E->isPartiallySubstituted()) {
16439 PackArgs = E->getPartialArguments();
16440 } else if (E->isValueDependent()) {
16441 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16442 bool ShouldExpand = false;
16443 bool RetainExpansion = false;
16444 UnsignedOrNone NumExpansions = std::nullopt;
16445 if (getDerived().TryExpandParameterPacks(
16446 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16447 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16448 RetainExpansion, NumExpansions))
16449 return ExprError();
16450
16451 // If we need to expand the pack, build a template argument from it and
16452 // expand that.
16453 if (ShouldExpand) {
16454 auto *Pack = E->getPack();
16455 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16456 ArgStorage = getSema().Context.getPackExpansionType(
16457 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16458 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16459 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16460 } else {
16461 auto *VD = cast<ValueDecl>(Val: Pack);
16462 ExprResult DRE = getSema().BuildDeclRefExpr(
16463 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16464 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16465 E->getPackLoc());
16466 if (DRE.isInvalid())
16467 return ExprError();
16468 ArgStorage = TemplateArgument(
16469 new (getSema().Context)
16470 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16471 /*IsCanonical=*/false);
16472 }
16473 PackArgs = ArgStorage;
16474 }
16475 }
16476
16477 // If we're not expanding the pack, just transform the decl.
16478 if (!PackArgs.size()) {
16479 auto *Pack = cast_or_null<NamedDecl>(
16480 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16481 if (!Pack)
16482 return ExprError();
16483 return getDerived().RebuildSizeOfPackExpr(
16484 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16485 std::nullopt, {});
16486 }
16487
16488 // Try to compute the result without performing a partial substitution.
16489 UnsignedOrNone Result =
16490 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16491
16492 // Common case: we could determine the number of expansions without
16493 // substituting.
16494 if (Result)
16495 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16496 E->getPackLoc(),
16497 E->getRParenLoc(), *Result, {});
16498
16499 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16500 E->getPackLoc());
16501 {
16502 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16503 typedef TemplateArgumentLocInventIterator<
16504 Derived, const TemplateArgument*> PackLocIterator;
16505 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16506 PackLocIterator(*this, PackArgs.end()),
16507 TransformedPackArgs, /*Uneval*/true))
16508 return ExprError();
16509 }
16510
16511 // Check whether we managed to fully-expand the pack.
16512 // FIXME: Is it possible for us to do so and not hit the early exit path?
16513 SmallVector<TemplateArgument, 8> Args;
16514 bool PartialSubstitution = false;
16515 for (auto &Loc : TransformedPackArgs.arguments()) {
16516 Args.push_back(Elt: Loc.getArgument());
16517 if (Loc.getArgument().isPackExpansion())
16518 PartialSubstitution = true;
16519 }
16520
16521 if (PartialSubstitution)
16522 return getDerived().RebuildSizeOfPackExpr(
16523 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16524 std::nullopt, Args);
16525
16526 return getDerived().RebuildSizeOfPackExpr(
16527 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16528 /*Length=*/static_cast<unsigned>(Args.size()),
16529 /*PartialArgs=*/{});
16530}
16531
16532template <typename Derived>
16533ExprResult
16534TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16535 if (!E->isValueDependent())
16536 return E;
16537
16538 // Transform the index
16539 ExprResult IndexExpr;
16540 {
16541 EnterExpressionEvaluationContext ConstantContext(
16542 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16543 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16544 if (IndexExpr.isInvalid())
16545 return ExprError();
16546 }
16547
16548 SmallVector<Expr *, 5> ExpandedExprs;
16549 bool FullySubstituted = true;
16550 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16551 Expr *Pattern = E->getPackIdExpression();
16552 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16553 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16554 Unexpanded);
16555 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16556
16557 // Determine whether the set of unexpanded parameter packs can and should
16558 // be expanded.
16559 bool ShouldExpand = true;
16560 bool RetainExpansion = false;
16561 UnsignedOrNone OrigNumExpansions = std::nullopt,
16562 NumExpansions = std::nullopt;
16563 if (getDerived().TryExpandParameterPacks(
16564 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16565 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16566 RetainExpansion, NumExpansions))
16567 return true;
16568 if (!ShouldExpand) {
16569 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16570 ExprResult Pack = getDerived().TransformExpr(Pattern);
16571 if (Pack.isInvalid())
16572 return ExprError();
16573 return getDerived().RebuildPackIndexingExpr(
16574 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16575 {}, /*FullySubstituted=*/false);
16576 }
16577 for (unsigned I = 0; I != *NumExpansions; ++I) {
16578 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16579 ExprResult Out = getDerived().TransformExpr(Pattern);
16580 if (Out.isInvalid())
16581 return true;
16582 if (Out.get()->containsUnexpandedParameterPack()) {
16583 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16584 OrigNumExpansions);
16585 if (Out.isInvalid())
16586 return true;
16587 FullySubstituted = false;
16588 }
16589 ExpandedExprs.push_back(Elt: Out.get());
16590 }
16591 // If we're supposed to retain a pack expansion, do so by temporarily
16592 // forgetting the partially-substituted parameter pack.
16593 if (RetainExpansion) {
16594 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16595
16596 ExprResult Out = getDerived().TransformExpr(Pattern);
16597 if (Out.isInvalid())
16598 return true;
16599
16600 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16601 OrigNumExpansions);
16602 if (Out.isInvalid())
16603 return true;
16604 FullySubstituted = false;
16605 ExpandedExprs.push_back(Elt: Out.get());
16606 }
16607 } else if (!E->expandsToEmptyPack()) {
16608 if (getDerived().TransformExprs(E->getExpressions().data(),
16609 E->getExpressions().size(), false,
16610 ExpandedExprs))
16611 return ExprError();
16612 }
16613
16614 return getDerived().RebuildPackIndexingExpr(
16615 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16616 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16617}
16618
16619template <typename Derived>
16620ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16621 SubstNonTypeTemplateParmPackExpr *E) {
16622 if (!getSema().ArgPackSubstIndex)
16623 // We aren't expanding the parameter pack, so just return ourselves.
16624 return E;
16625
16626 TemplateArgument Pack = E->getArgumentPack();
16627 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
16628 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16629 E->getAssociatedDecl(), E->getParameterPack(),
16630 E->getParameterPackLocation(), Arg, SemaRef.getPackIndex(Pack),
16631 E->getFinal());
16632}
16633
16634template <typename Derived>
16635ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16636 SubstNonTypeTemplateParmExpr *E) {
16637 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
16638 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
16639 if (Replacement.isInvalid())
16640 return true;
16641
16642 Decl *AssociatedDecl =
16643 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
16644 if (!AssociatedDecl)
16645 return true;
16646
16647 if (Replacement.get() == OrigReplacement &&
16648 AssociatedDecl == E->getAssociatedDecl())
16649 return E;
16650
16651 auto getParamAndType = [E](Decl *AssociatedDecl)
16652 -> std::tuple<NonTypeTemplateParmDecl *, QualType> {
16653 auto [PDecl, Arg] =
16654 getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex());
16655 auto *Param = cast<NonTypeTemplateParmDecl>(Val: PDecl);
16656 if (Arg.isNull())
16657 return {Param, Param->getType()};
16658 if (UnsignedOrNone PackIndex = E->getPackIndex())
16659 Arg = Arg.getPackAsArray()[*PackIndex];
16660 return {Param, Arg.getNonTypeTemplateArgumentType()};
16661 };
16662
16663 // If the replacement expression did not change, and the parameter type
16664 // did not change, we can skip the semantic action because it would
16665 // produce the same result anyway.
16666 if (auto [Param, ParamType] = getParamAndType(AssociatedDecl);
16667 !SemaRef.Context.hasSameType(
16668 ParamType, std::get<1>(getParamAndType(E->getAssociatedDecl()))) ||
16669 Replacement.get() != OrigReplacement) {
16670 // When transforming the replacement expression previously, all Sema
16671 // specific annotations, such as implicit casts, are discarded. Calling the
16672 // corresponding sema action is necessary to recover those. Otherwise,
16673 // equivalency of the result would be lost.
16674 TemplateArgument SugaredConverted, CanonicalConverted;
16675 Replacement = SemaRef.CheckTemplateArgument(
16676 Param, ParamType, Replacement.get(), SugaredConverted,
16677 CanonicalConverted,
16678 /*StrictCheck=*/false, Sema::CTAK_Specified);
16679 if (Replacement.isInvalid())
16680 return true;
16681 } else {
16682 // Otherwise, the same expression would have been produced.
16683 Replacement = E->getReplacement();
16684 }
16685
16686 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16687 AssociatedDecl, E->getParameter(), E->getNameLoc(),
16688 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
16689 E->getPackIndex(), E->getFinal());
16690}
16691
16692template<typename Derived>
16693ExprResult
16694TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16695 // Default behavior is to do nothing with this transformation.
16696 return E;
16697}
16698
16699template<typename Derived>
16700ExprResult
16701TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16702 MaterializeTemporaryExpr *E) {
16703 return getDerived().TransformExpr(E->getSubExpr());
16704}
16705
16706template<typename Derived>
16707ExprResult
16708TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16709 UnresolvedLookupExpr *Callee = nullptr;
16710 if (Expr *OldCallee = E->getCallee()) {
16711 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16712 if (CalleeResult.isInvalid())
16713 return ExprError();
16714 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16715 }
16716
16717 Expr *Pattern = E->getPattern();
16718
16719 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16720 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16721 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16722
16723 // Determine whether the set of unexpanded parameter packs can and should
16724 // be expanded.
16725 bool Expand = true;
16726 bool RetainExpansion = false;
16727 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16728 NumExpansions = OrigNumExpansions;
16729 if (getDerived().TryExpandParameterPacks(
16730 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16731 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16732 NumExpansions))
16733 return true;
16734
16735 if (!Expand) {
16736 // Do not expand any packs here, just transform and rebuild a fold
16737 // expression.
16738 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16739
16740 ExprResult LHS =
16741 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16742 if (LHS.isInvalid())
16743 return true;
16744
16745 ExprResult RHS =
16746 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16747 if (RHS.isInvalid())
16748 return true;
16749
16750 if (!getDerived().AlwaysRebuild() &&
16751 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16752 return E;
16753
16754 return getDerived().RebuildCXXFoldExpr(
16755 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16756 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16757 }
16758
16759 // Formally a fold expression expands to nested parenthesized expressions.
16760 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16761 // them.
16762 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16763 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16764 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16765 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16766 << E->getSourceRange();
16767 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16768 return ExprError();
16769 }
16770
16771 // The transform has determined that we should perform an elementwise
16772 // expansion of the pattern. Do so.
16773 ExprResult Result = getDerived().TransformExpr(E->getInit());
16774 if (Result.isInvalid())
16775 return true;
16776 bool LeftFold = E->isLeftFold();
16777
16778 // If we're retaining an expansion for a right fold, it is the innermost
16779 // component and takes the init (if any).
16780 if (!LeftFold && RetainExpansion) {
16781 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16782
16783 ExprResult Out = getDerived().TransformExpr(Pattern);
16784 if (Out.isInvalid())
16785 return true;
16786
16787 Result = getDerived().RebuildCXXFoldExpr(
16788 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16789 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16790 if (Result.isInvalid())
16791 return true;
16792 }
16793
16794 bool WarnedOnComparison = false;
16795 for (unsigned I = 0; I != *NumExpansions; ++I) {
16796 Sema::ArgPackSubstIndexRAII SubstIndex(
16797 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16798 ExprResult Out = getDerived().TransformExpr(Pattern);
16799 if (Out.isInvalid())
16800 return true;
16801
16802 if (Out.get()->containsUnexpandedParameterPack()) {
16803 // We still have a pack; retain a pack expansion for this slice.
16804 Result = getDerived().RebuildCXXFoldExpr(
16805 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16806 E->getOperator(), E->getEllipsisLoc(),
16807 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16808 OrigNumExpansions);
16809 } else if (Result.isUsable()) {
16810 // We've got down to a single element; build a binary operator.
16811 Expr *LHS = LeftFold ? Result.get() : Out.get();
16812 Expr *RHS = LeftFold ? Out.get() : Result.get();
16813 if (Callee) {
16814 UnresolvedSet<16> Functions;
16815 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16816 Result = getDerived().RebuildCXXOperatorCallExpr(
16817 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16818 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16819 Functions, LHS, RHS);
16820 } else {
16821 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16822 E->getOperator(), LHS, RHS,
16823 /*ForFoldExpresion=*/true);
16824 if (!WarnedOnComparison && Result.isUsable()) {
16825 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16826 BO && BO->isComparisonOp()) {
16827 WarnedOnComparison = true;
16828 SemaRef.Diag(Loc: BO->getBeginLoc(),
16829 DiagID: diag::warn_comparison_in_fold_expression)
16830 << BO->getOpcodeStr();
16831 }
16832 }
16833 }
16834 } else
16835 Result = Out;
16836
16837 if (Result.isInvalid())
16838 return true;
16839 }
16840
16841 // If we're retaining an expansion for a left fold, it is the outermost
16842 // component and takes the complete expansion so far as its init (if any).
16843 if (LeftFold && RetainExpansion) {
16844 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16845
16846 ExprResult Out = getDerived().TransformExpr(Pattern);
16847 if (Out.isInvalid())
16848 return true;
16849
16850 Result = getDerived().RebuildCXXFoldExpr(
16851 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16852 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16853 if (Result.isInvalid())
16854 return true;
16855 }
16856
16857 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16858 PE->setIsProducedByFoldExpansion();
16859
16860 // If we had no init and an empty pack, and we're not retaining an expansion,
16861 // then produce a fallback value or error.
16862 if (Result.isUnset())
16863 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16864 E->getOperator());
16865 return Result;
16866}
16867
16868template <typename Derived>
16869ExprResult
16870TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16871 SmallVector<Expr *, 4> TransformedInits;
16872 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16873
16874 QualType T = getDerived().TransformType(E->getType());
16875
16876 bool ArgChanged = false;
16877
16878 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16879 TransformedInits, &ArgChanged))
16880 return ExprError();
16881
16882 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16883 return E;
16884
16885 return getDerived().RebuildCXXParenListInitExpr(
16886 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16887 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16888}
16889
16890template<typename Derived>
16891ExprResult
16892TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16893 CXXStdInitializerListExpr *E) {
16894 return getDerived().TransformExpr(E->getSubExpr());
16895}
16896
16897template<typename Derived>
16898ExprResult
16899TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16900 return SemaRef.MaybeBindToTemporary(E);
16901}
16902
16903template<typename Derived>
16904ExprResult
16905TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16906 return E;
16907}
16908
16909template<typename Derived>
16910ExprResult
16911TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16912 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16913 if (SubExpr.isInvalid())
16914 return ExprError();
16915
16916 if (!getDerived().AlwaysRebuild() &&
16917 SubExpr.get() == E->getSubExpr())
16918 return E;
16919
16920 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16921}
16922
16923template<typename Derived>
16924ExprResult
16925TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16926 // Transform each of the elements.
16927 SmallVector<Expr *, 8> Elements;
16928 bool ArgChanged = false;
16929 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16930 /*IsCall=*/false, Elements, &ArgChanged))
16931 return ExprError();
16932
16933 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16934 return SemaRef.MaybeBindToTemporary(E);
16935
16936 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16937 Elements.data(),
16938 Elements.size());
16939}
16940
16941template<typename Derived>
16942ExprResult
16943TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16944 ObjCDictionaryLiteral *E) {
16945 // Transform each of the elements.
16946 SmallVector<ObjCDictionaryElement, 8> Elements;
16947 bool ArgChanged = false;
16948 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16949 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
16950
16951 if (OrigElement.isPackExpansion()) {
16952 // This key/value element is a pack expansion.
16953 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16954 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16955 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16956 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16957
16958 // Determine whether the set of unexpanded parameter packs can
16959 // and should be expanded.
16960 bool Expand = true;
16961 bool RetainExpansion = false;
16962 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16963 UnsignedOrNone NumExpansions = OrigNumExpansions;
16964 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16965 OrigElement.Value->getEndLoc());
16966 if (getDerived().TryExpandParameterPacks(
16967 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
16968 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16969 NumExpansions))
16970 return ExprError();
16971
16972 if (!Expand) {
16973 // The transform has determined that we should perform a simple
16974 // transformation on the pack expansion, producing another pack
16975 // expansion.
16976 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16977 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16978 if (Key.isInvalid())
16979 return ExprError();
16980
16981 if (Key.get() != OrigElement.Key)
16982 ArgChanged = true;
16983
16984 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16985 if (Value.isInvalid())
16986 return ExprError();
16987
16988 if (Value.get() != OrigElement.Value)
16989 ArgChanged = true;
16990
16991 ObjCDictionaryElement Expansion = {
16992 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
16993 };
16994 Elements.push_back(Elt: Expansion);
16995 continue;
16996 }
16997
16998 // Record right away that the argument was changed. This needs
16999 // to happen even if the array expands to nothing.
17000 ArgChanged = true;
17001
17002 // The transform has determined that we should perform an elementwise
17003 // expansion of the pattern. Do so.
17004 for (unsigned I = 0; I != *NumExpansions; ++I) {
17005 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17006 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17007 if (Key.isInvalid())
17008 return ExprError();
17009
17010 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17011 if (Value.isInvalid())
17012 return ExprError();
17013
17014 ObjCDictionaryElement Element = {
17015 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17016 };
17017
17018 // If any unexpanded parameter packs remain, we still have a
17019 // pack expansion.
17020 // FIXME: Can this really happen?
17021 if (Key.get()->containsUnexpandedParameterPack() ||
17022 Value.get()->containsUnexpandedParameterPack())
17023 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17024
17025 Elements.push_back(Elt: Element);
17026 }
17027
17028 // FIXME: Retain a pack expansion if RetainExpansion is true.
17029
17030 // We've finished with this pack expansion.
17031 continue;
17032 }
17033
17034 // Transform and check key.
17035 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17036 if (Key.isInvalid())
17037 return ExprError();
17038
17039 if (Key.get() != OrigElement.Key)
17040 ArgChanged = true;
17041
17042 // Transform and check value.
17043 ExprResult Value
17044 = getDerived().TransformExpr(OrigElement.Value);
17045 if (Value.isInvalid())
17046 return ExprError();
17047
17048 if (Value.get() != OrigElement.Value)
17049 ArgChanged = true;
17050
17051 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17052 .NumExpansions: std::nullopt};
17053 Elements.push_back(Elt: Element);
17054 }
17055
17056 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17057 return SemaRef.MaybeBindToTemporary(E);
17058
17059 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17060 Elements);
17061}
17062
17063template<typename Derived>
17064ExprResult
17065TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17066 TypeSourceInfo *EncodedTypeInfo
17067 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17068 if (!EncodedTypeInfo)
17069 return ExprError();
17070
17071 if (!getDerived().AlwaysRebuild() &&
17072 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17073 return E;
17074
17075 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17076 EncodedTypeInfo,
17077 E->getRParenLoc());
17078}
17079
17080template<typename Derived>
17081ExprResult TreeTransform<Derived>::
17082TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17083 // This is a kind of implicit conversion, and it needs to get dropped
17084 // and recomputed for the same general reasons that ImplicitCastExprs
17085 // do, as well a more specific one: this expression is only valid when
17086 // it appears *immediately* as an argument expression.
17087 return getDerived().TransformExpr(E->getSubExpr());
17088}
17089
17090template<typename Derived>
17091ExprResult TreeTransform<Derived>::
17092TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17093 TypeSourceInfo *TSInfo
17094 = getDerived().TransformType(E->getTypeInfoAsWritten());
17095 if (!TSInfo)
17096 return ExprError();
17097
17098 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17099 if (Result.isInvalid())
17100 return ExprError();
17101
17102 if (!getDerived().AlwaysRebuild() &&
17103 TSInfo == E->getTypeInfoAsWritten() &&
17104 Result.get() == E->getSubExpr())
17105 return E;
17106
17107 return SemaRef.ObjC().BuildObjCBridgedCast(
17108 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17109 SubExpr: Result.get());
17110}
17111
17112template <typename Derived>
17113ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17114 ObjCAvailabilityCheckExpr *E) {
17115 return E;
17116}
17117
17118template<typename Derived>
17119ExprResult
17120TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17121 // Transform arguments.
17122 bool ArgChanged = false;
17123 SmallVector<Expr*, 8> Args;
17124 Args.reserve(N: E->getNumArgs());
17125 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17126 &ArgChanged))
17127 return ExprError();
17128
17129 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17130 // Class message: transform the receiver type.
17131 TypeSourceInfo *ReceiverTypeInfo
17132 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17133 if (!ReceiverTypeInfo)
17134 return ExprError();
17135
17136 // If nothing changed, just retain the existing message send.
17137 if (!getDerived().AlwaysRebuild() &&
17138 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17139 return SemaRef.MaybeBindToTemporary(E);
17140
17141 // Build a new class message send.
17142 SmallVector<SourceLocation, 16> SelLocs;
17143 E->getSelectorLocs(SelLocs);
17144 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17145 E->getSelector(),
17146 SelLocs,
17147 E->getMethodDecl(),
17148 E->getLeftLoc(),
17149 Args,
17150 E->getRightLoc());
17151 }
17152 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17153 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17154 if (!E->getMethodDecl())
17155 return ExprError();
17156
17157 // Build a new class message send to 'super'.
17158 SmallVector<SourceLocation, 16> SelLocs;
17159 E->getSelectorLocs(SelLocs);
17160 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17161 E->getSelector(),
17162 SelLocs,
17163 E->getReceiverType(),
17164 E->getMethodDecl(),
17165 E->getLeftLoc(),
17166 Args,
17167 E->getRightLoc());
17168 }
17169
17170 // Instance message: transform the receiver
17171 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17172 "Only class and instance messages may be instantiated");
17173 ExprResult Receiver
17174 = getDerived().TransformExpr(E->getInstanceReceiver());
17175 if (Receiver.isInvalid())
17176 return ExprError();
17177
17178 // If nothing changed, just retain the existing message send.
17179 if (!getDerived().AlwaysRebuild() &&
17180 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17181 return SemaRef.MaybeBindToTemporary(E);
17182
17183 // Build a new instance message send.
17184 SmallVector<SourceLocation, 16> SelLocs;
17185 E->getSelectorLocs(SelLocs);
17186 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17187 E->getSelector(),
17188 SelLocs,
17189 E->getMethodDecl(),
17190 E->getLeftLoc(),
17191 Args,
17192 E->getRightLoc());
17193}
17194
17195template<typename Derived>
17196ExprResult
17197TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17198 return E;
17199}
17200
17201template<typename Derived>
17202ExprResult
17203TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17204 return E;
17205}
17206
17207template<typename Derived>
17208ExprResult
17209TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17210 // Transform the base expression.
17211 ExprResult Base = getDerived().TransformExpr(E->getBase());
17212 if (Base.isInvalid())
17213 return ExprError();
17214
17215 // We don't need to transform the ivar; it will never change.
17216
17217 // If nothing changed, just retain the existing expression.
17218 if (!getDerived().AlwaysRebuild() &&
17219 Base.get() == E->getBase())
17220 return E;
17221
17222 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17223 E->getLocation(),
17224 E->isArrow(), E->isFreeIvar());
17225}
17226
17227template<typename Derived>
17228ExprResult
17229TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17230 // 'super' and types never change. Property never changes. Just
17231 // retain the existing expression.
17232 if (!E->isObjectReceiver())
17233 return E;
17234
17235 // Transform the base expression.
17236 ExprResult Base = getDerived().TransformExpr(E->getBase());
17237 if (Base.isInvalid())
17238 return ExprError();
17239
17240 // We don't need to transform the property; it will never change.
17241
17242 // If nothing changed, just retain the existing expression.
17243 if (!getDerived().AlwaysRebuild() &&
17244 Base.get() == E->getBase())
17245 return E;
17246
17247 if (E->isExplicitProperty())
17248 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17249 E->getExplicitProperty(),
17250 E->getLocation());
17251
17252 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17253 SemaRef.Context.PseudoObjectTy,
17254 E->getImplicitPropertyGetter(),
17255 E->getImplicitPropertySetter(),
17256 E->getLocation());
17257}
17258
17259template<typename Derived>
17260ExprResult
17261TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17262 // Transform the base expression.
17263 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17264 if (Base.isInvalid())
17265 return ExprError();
17266
17267 // Transform the key expression.
17268 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17269 if (Key.isInvalid())
17270 return ExprError();
17271
17272 // If nothing changed, just retain the existing expression.
17273 if (!getDerived().AlwaysRebuild() &&
17274 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17275 return E;
17276
17277 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17278 Base.get(), Key.get(),
17279 E->getAtIndexMethodDecl(),
17280 E->setAtIndexMethodDecl());
17281}
17282
17283template<typename Derived>
17284ExprResult
17285TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17286 // Transform the base expression.
17287 ExprResult Base = getDerived().TransformExpr(E->getBase());
17288 if (Base.isInvalid())
17289 return ExprError();
17290
17291 // If nothing changed, just retain the existing expression.
17292 if (!getDerived().AlwaysRebuild() &&
17293 Base.get() == E->getBase())
17294 return E;
17295
17296 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17297 E->getOpLoc(),
17298 E->isArrow());
17299}
17300
17301template<typename Derived>
17302ExprResult
17303TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17304 bool ArgumentChanged = false;
17305 SmallVector<Expr*, 8> SubExprs;
17306 SubExprs.reserve(N: E->getNumSubExprs());
17307 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17308 SubExprs, &ArgumentChanged))
17309 return ExprError();
17310
17311 if (!getDerived().AlwaysRebuild() &&
17312 !ArgumentChanged)
17313 return E;
17314
17315 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17316 SubExprs,
17317 E->getRParenLoc());
17318}
17319
17320template<typename Derived>
17321ExprResult
17322TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17323 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17324 if (SrcExpr.isInvalid())
17325 return ExprError();
17326
17327 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17328 if (!Type)
17329 return ExprError();
17330
17331 if (!getDerived().AlwaysRebuild() &&
17332 Type == E->getTypeSourceInfo() &&
17333 SrcExpr.get() == E->getSrcExpr())
17334 return E;
17335
17336 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17337 SrcExpr.get(), Type,
17338 E->getRParenLoc());
17339}
17340
17341template<typename Derived>
17342ExprResult
17343TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17344 BlockDecl *oldBlock = E->getBlockDecl();
17345
17346 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17347 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17348
17349 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17350 blockScope->TheDecl->setBlockMissingReturnType(
17351 oldBlock->blockMissingReturnType());
17352
17353 SmallVector<ParmVarDecl*, 4> params;
17354 SmallVector<QualType, 4> paramTypes;
17355
17356 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17357
17358 // Parameter substitution.
17359 Sema::ExtParameterInfoBuilder extParamInfos;
17360 if (getDerived().TransformFunctionTypeParams(
17361 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17362 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17363 extParamInfos)) {
17364 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17365 return ExprError();
17366 }
17367
17368 QualType exprResultType =
17369 getDerived().TransformType(exprFunctionType->getReturnType());
17370
17371 auto epi = exprFunctionType->getExtProtoInfo();
17372 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17373
17374 QualType functionType =
17375 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17376 blockScope->FunctionType = functionType;
17377
17378 // Set the parameters on the block decl.
17379 if (!params.empty())
17380 blockScope->TheDecl->setParams(params);
17381
17382 if (!oldBlock->blockMissingReturnType()) {
17383 blockScope->HasImplicitReturnType = false;
17384 blockScope->ReturnType = exprResultType;
17385 }
17386
17387 // Transform the body
17388 StmtResult body = getDerived().TransformStmt(E->getBody());
17389 if (body.isInvalid()) {
17390 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17391 return ExprError();
17392 }
17393
17394#ifndef NDEBUG
17395 // In builds with assertions, make sure that we captured everything we
17396 // captured before.
17397 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17398 for (const auto &I : oldBlock->captures()) {
17399 VarDecl *oldCapture = I.getVariable();
17400
17401 // Ignore parameter packs.
17402 if (oldCapture->isParameterPack())
17403 continue;
17404
17405 VarDecl *newCapture =
17406 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17407 oldCapture));
17408 assert(blockScope->CaptureMap.count(newCapture));
17409 }
17410
17411 // The this pointer may not be captured by the instantiated block, even when
17412 // it's captured by the original block, if the expression causing the
17413 // capture is in the discarded branch of a constexpr if statement.
17414 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17415 "this pointer isn't captured in the old block");
17416 }
17417#endif
17418
17419 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17420 /*Scope=*/CurScope: nullptr);
17421}
17422
17423template<typename Derived>
17424ExprResult
17425TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17426 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17427 if (SrcExpr.isInvalid())
17428 return ExprError();
17429
17430 QualType Type = getDerived().TransformType(E->getType());
17431
17432 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17433 RParenLoc: E->getRParenLoc());
17434}
17435
17436template<typename Derived>
17437ExprResult
17438TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17439 bool ArgumentChanged = false;
17440 SmallVector<Expr*, 8> SubExprs;
17441 SubExprs.reserve(N: E->getNumSubExprs());
17442 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17443 SubExprs, &ArgumentChanged))
17444 return ExprError();
17445
17446 if (!getDerived().AlwaysRebuild() &&
17447 !ArgumentChanged)
17448 return E;
17449
17450 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17451 E->getOp(), E->getRParenLoc());
17452}
17453
17454//===----------------------------------------------------------------------===//
17455// Type reconstruction
17456//===----------------------------------------------------------------------===//
17457
17458template<typename Derived>
17459QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17460 SourceLocation Star) {
17461 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17462 Entity: getDerived().getBaseEntity());
17463}
17464
17465template<typename Derived>
17466QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17467 SourceLocation Star) {
17468 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17469 Entity: getDerived().getBaseEntity());
17470}
17471
17472template<typename Derived>
17473QualType
17474TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17475 bool WrittenAsLValue,
17476 SourceLocation Sigil) {
17477 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17478 Loc: Sigil, Entity: getDerived().getBaseEntity());
17479}
17480
17481template <typename Derived>
17482QualType TreeTransform<Derived>::RebuildMemberPointerType(
17483 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17484 SourceLocation Sigil) {
17485 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17486 Entity: getDerived().getBaseEntity());
17487}
17488
17489template<typename Derived>
17490QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17491 const ObjCTypeParamDecl *Decl,
17492 SourceLocation ProtocolLAngleLoc,
17493 ArrayRef<ObjCProtocolDecl *> Protocols,
17494 ArrayRef<SourceLocation> ProtocolLocs,
17495 SourceLocation ProtocolRAngleLoc) {
17496 return SemaRef.ObjC().BuildObjCTypeParamType(
17497 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17498 /*FailOnError=*/FailOnError: true);
17499}
17500
17501template<typename Derived>
17502QualType TreeTransform<Derived>::RebuildObjCObjectType(
17503 QualType BaseType,
17504 SourceLocation Loc,
17505 SourceLocation TypeArgsLAngleLoc,
17506 ArrayRef<TypeSourceInfo *> TypeArgs,
17507 SourceLocation TypeArgsRAngleLoc,
17508 SourceLocation ProtocolLAngleLoc,
17509 ArrayRef<ObjCProtocolDecl *> Protocols,
17510 ArrayRef<SourceLocation> ProtocolLocs,
17511 SourceLocation ProtocolRAngleLoc) {
17512 return SemaRef.ObjC().BuildObjCObjectType(
17513 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17514 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17515 /*FailOnError=*/FailOnError: true,
17516 /*Rebuilding=*/Rebuilding: true);
17517}
17518
17519template<typename Derived>
17520QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17521 QualType PointeeType,
17522 SourceLocation Star) {
17523 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17524}
17525
17526template <typename Derived>
17527QualType TreeTransform<Derived>::RebuildArrayType(
17528 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17529 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17530 if (SizeExpr || !Size)
17531 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17532 Quals: IndexTypeQuals, Brackets: BracketsRange,
17533 Entity: getDerived().getBaseEntity());
17534
17535 QualType Types[] = {
17536 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17537 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17538 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17539 };
17540 QualType SizeType;
17541 for (const auto &T : Types)
17542 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17543 SizeType = T;
17544 break;
17545 }
17546
17547 // Note that we can return a VariableArrayType here in the case where
17548 // the element type was a dependent VariableArrayType.
17549 IntegerLiteral *ArraySize
17550 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17551 /*FIXME*/l: BracketsRange.getBegin());
17552 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17553 Quals: IndexTypeQuals, Brackets: BracketsRange,
17554 Entity: getDerived().getBaseEntity());
17555}
17556
17557template <typename Derived>
17558QualType TreeTransform<Derived>::RebuildConstantArrayType(
17559 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17560 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17561 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17562 IndexTypeQuals, BracketsRange);
17563}
17564
17565template <typename Derived>
17566QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17567 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17568 SourceRange BracketsRange) {
17569 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17570 IndexTypeQuals, BracketsRange);
17571}
17572
17573template <typename Derived>
17574QualType TreeTransform<Derived>::RebuildVariableArrayType(
17575 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17576 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17577 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17578 SizeExpr,
17579 IndexTypeQuals, BracketsRange);
17580}
17581
17582template <typename Derived>
17583QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17584 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17585 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17586 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17587 SizeExpr,
17588 IndexTypeQuals, BracketsRange);
17589}
17590
17591template <typename Derived>
17592QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17593 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17594 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17595 AttrLoc: AttributeLoc);
17596}
17597
17598template <typename Derived>
17599QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17600 unsigned NumElements,
17601 VectorKind VecKind) {
17602 // FIXME: semantic checking!
17603 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17604}
17605
17606template <typename Derived>
17607QualType TreeTransform<Derived>::RebuildDependentVectorType(
17608 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17609 VectorKind VecKind) {
17610 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17611}
17612
17613template<typename Derived>
17614QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17615 unsigned NumElements,
17616 SourceLocation AttributeLoc) {
17617 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17618 NumElements, true);
17619 IntegerLiteral *VectorSize
17620 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17621 l: AttributeLoc);
17622 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17623}
17624
17625template<typename Derived>
17626QualType
17627TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17628 Expr *SizeExpr,
17629 SourceLocation AttributeLoc) {
17630 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17631}
17632
17633template <typename Derived>
17634QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17635 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17636 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17637 NumColumns);
17638}
17639
17640template <typename Derived>
17641QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17642 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17643 SourceLocation AttributeLoc) {
17644 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17645 AttrLoc: AttributeLoc);
17646}
17647
17648template <typename Derived>
17649QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17650 QualType T, MutableArrayRef<QualType> ParamTypes,
17651 const FunctionProtoType::ExtProtoInfo &EPI) {
17652 return SemaRef.BuildFunctionType(T, ParamTypes,
17653 Loc: getDerived().getBaseLocation(),
17654 Entity: getDerived().getBaseEntity(),
17655 EPI);
17656}
17657
17658template<typename Derived>
17659QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17660 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17661}
17662
17663template <typename Derived>
17664QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
17665 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
17666 SourceLocation NameLoc, Decl *D) {
17667 assert(D && "no decl found");
17668 if (D->isInvalidDecl()) return QualType();
17669
17670 // FIXME: Doesn't account for ObjCInterfaceDecl!
17671 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17672 // A valid resolved using typename pack expansion decl can have multiple
17673 // UsingDecls, but they must each have exactly one type, and it must be
17674 // the same type in every case. But we must have at least one expansion!
17675 if (UPD->expansions().empty()) {
17676 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
17677 << UPD->isCXXClassMember() << UPD;
17678 return QualType();
17679 }
17680
17681 // We might still have some unresolved types. Try to pick a resolved type
17682 // if we can. The final instantiation will check that the remaining
17683 // unresolved types instantiate to the type we pick.
17684 QualType FallbackT;
17685 QualType T;
17686 for (auto *E : UPD->expansions()) {
17687 QualType ThisT =
17688 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
17689 if (ThisT.isNull())
17690 continue;
17691 if (ThisT->getAs<UnresolvedUsingType>())
17692 FallbackT = ThisT;
17693 else if (T.isNull())
17694 T = ThisT;
17695 else
17696 assert(getSema().Context.hasSameType(ThisT, T) &&
17697 "mismatched resolved types in using pack expansion");
17698 }
17699 return T.isNull() ? FallbackT : T;
17700 }
17701 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17702 assert(Using->hasTypename() &&
17703 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17704
17705 // A valid resolved using typename decl points to exactly one type decl.
17706 assert(++Using->shadow_begin() == Using->shadow_end());
17707
17708 UsingShadowDecl *Shadow = *Using->shadow_begin();
17709 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
17710 return QualType();
17711 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
17712 }
17713 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17714 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17715 return SemaRef.Context.getUnresolvedUsingType(
17716 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
17717}
17718
17719template <typename Derived>
17720QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17721 TypeOfKind Kind) {
17722 return SemaRef.BuildTypeofExprType(E, Kind);
17723}
17724
17725template<typename Derived>
17726QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17727 TypeOfKind Kind) {
17728 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17729}
17730
17731template <typename Derived>
17732QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17733 return SemaRef.BuildDecltypeType(E);
17734}
17735
17736template <typename Derived>
17737QualType TreeTransform<Derived>::RebuildPackIndexingType(
17738 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17739 SourceLocation EllipsisLoc, bool FullySubstituted,
17740 ArrayRef<QualType> Expansions) {
17741 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17742 FullySubstituted, Expansions);
17743}
17744
17745template<typename Derived>
17746QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17747 UnaryTransformType::UTTKind UKind,
17748 SourceLocation Loc) {
17749 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17750}
17751
17752template <typename Derived>
17753QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17754 ElaboratedTypeKeyword Keyword, TemplateName Template,
17755 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
17756 return SemaRef.CheckTemplateIdType(
17757 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
17758 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
17759}
17760
17761template<typename Derived>
17762QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17763 SourceLocation KWLoc) {
17764 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17765}
17766
17767template<typename Derived>
17768QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17769 SourceLocation KWLoc,
17770 bool isReadPipe) {
17771 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17772 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17773}
17774
17775template <typename Derived>
17776QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17777 unsigned NumBits,
17778 SourceLocation Loc) {
17779 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17780 NumBits, true);
17781 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17782 type: SemaRef.Context.IntTy, l: Loc);
17783 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17784}
17785
17786template <typename Derived>
17787QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17788 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17789 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17790}
17791
17792template <typename Derived>
17793TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17794 bool TemplateKW,
17795 TemplateName Name) {
17796 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17797 Template: Name);
17798}
17799
17800template <typename Derived>
17801TemplateName TreeTransform<Derived>::RebuildTemplateName(
17802 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
17803 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
17804 UnqualifiedId TemplateName;
17805 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17806 Sema::TemplateTy Template;
17807 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17808 TemplateName, ParsedType::make(P: ObjectType),
17809 /*EnteringContext=*/false, Template,
17810 AllowInjectedClassName);
17811 return Template.get();
17812}
17813
17814template<typename Derived>
17815TemplateName
17816TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17817 SourceLocation TemplateKWLoc,
17818 OverloadedOperatorKind Operator,
17819 SourceLocation NameLoc,
17820 QualType ObjectType,
17821 bool AllowInjectedClassName) {
17822 UnqualifiedId Name;
17823 // FIXME: Bogus location information.
17824 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17825 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17826 Sema::TemplateTy Template;
17827 getSema().ActOnTemplateName(
17828 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17829 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17830 return Template.get();
17831}
17832
17833template <typename Derived>
17834ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17835 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17836 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17837 Expr *Second) {
17838 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17839
17840 if (First->getObjectKind() == OK_ObjCProperty) {
17841 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17842 if (BinaryOperator::isAssignmentOp(Opc))
17843 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17844 Opcode: Opc, LHS: First, RHS: Second);
17845 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17846 if (Result.isInvalid())
17847 return ExprError();
17848 First = Result.get();
17849 }
17850
17851 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17852 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17853 if (Result.isInvalid())
17854 return ExprError();
17855 Second = Result.get();
17856 }
17857
17858 // Determine whether this should be a builtin operation.
17859 if (Op == OO_Subscript) {
17860 if (!First->getType()->isOverloadableType() &&
17861 !Second->getType()->isOverloadableType())
17862 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17863 OpLoc);
17864 } else if (Op == OO_Arrow) {
17865 // It is possible that the type refers to a RecoveryExpr created earlier
17866 // in the tree transformation.
17867 if (First->getType()->isDependentType())
17868 return ExprError();
17869 // -> is never a builtin operation.
17870 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17871 } else if (Second == nullptr || isPostIncDec) {
17872 if (!First->getType()->isOverloadableType() ||
17873 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17874 // The argument is not of overloadable type, or this is an expression
17875 // of the form &Class::member, so try to create a built-in unary
17876 // operation.
17877 UnaryOperatorKind Opc
17878 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17879
17880 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17881 }
17882 } else {
17883 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17884 !First->getType()->isOverloadableType() &&
17885 !Second->getType()->isOverloadableType()) {
17886 // Neither of the arguments is type-dependent or has an overloadable
17887 // type, so try to create a built-in binary operation.
17888 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17889 ExprResult Result
17890 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17891 if (Result.isInvalid())
17892 return ExprError();
17893
17894 return Result;
17895 }
17896 }
17897
17898 // Create the overloaded operator invocation for unary operators.
17899 if (!Second || isPostIncDec) {
17900 UnaryOperatorKind Opc
17901 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17902 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
17903 RequiresADL);
17904 }
17905
17906 // Create the overloaded operator invocation for binary operators.
17907 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17908 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
17909 LHS: First, RHS: Second, RequiresADL);
17910 if (Result.isInvalid())
17911 return ExprError();
17912
17913 return Result;
17914}
17915
17916template<typename Derived>
17917ExprResult
17918TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17919 SourceLocation OperatorLoc,
17920 bool isArrow,
17921 CXXScopeSpec &SS,
17922 TypeSourceInfo *ScopeType,
17923 SourceLocation CCLoc,
17924 SourceLocation TildeLoc,
17925 PseudoDestructorTypeStorage Destroyed) {
17926 QualType CanonicalBaseType = Base->getType().getCanonicalType();
17927 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17928 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
17929 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
17930 !cast<PointerType>(Val&: CanonicalBaseType)
17931 ->getPointeeType()
17932 ->getAsCanonical<RecordType>())) {
17933 // This pseudo-destructor expression is still a pseudo-destructor.
17934 return SemaRef.BuildPseudoDestructorExpr(
17935 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
17936 CCLoc, TildeLoc, DestroyedType: Destroyed);
17937 }
17938
17939 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17940 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17941 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
17942 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17943 NameInfo.setNamedTypeInfo(DestroyedType);
17944
17945 // The scope type is now known to be a valid nested name specifier
17946 // component. Tack it on to the nested name specifier.
17947 if (ScopeType) {
17948 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
17949 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17950 diag::err_expected_class_or_namespace)
17951 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17952 return ExprError();
17953 }
17954 SS.clear();
17955 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
17956 }
17957
17958 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17959 return getSema().BuildMemberReferenceExpr(
17960 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
17961 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
17962 /*TemplateArgs*/ nullptr,
17963 /*S*/ nullptr);
17964}
17965
17966template<typename Derived>
17967StmtResult
17968TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17969 SourceLocation Loc = S->getBeginLoc();
17970 CapturedDecl *CD = S->getCapturedDecl();
17971 unsigned NumParams = CD->getNumParams();
17972 unsigned ContextParamPos = CD->getContextParamPosition();
17973 SmallVector<Sema::CapturedParamNameType, 4> Params;
17974 for (unsigned I = 0; I < NumParams; ++I) {
17975 if (I != ContextParamPos) {
17976 Params.push_back(
17977 Elt: std::make_pair(
17978 CD->getParam(i: I)->getName(),
17979 getDerived().TransformType(CD->getParam(i: I)->getType())));
17980 } else {
17981 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
17982 }
17983 }
17984 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17985 S->getCapturedRegionKind(), Params);
17986 StmtResult Body;
17987 {
17988 Sema::CompoundScopeRAII CompoundScope(getSema());
17989 Body = getDerived().TransformStmt(S->getCapturedStmt());
17990 }
17991
17992 if (Body.isInvalid()) {
17993 getSema().ActOnCapturedRegionError();
17994 return StmtError();
17995 }
17996
17997 return getSema().ActOnCapturedRegionEnd(Body.get());
17998}
17999
18000template <typename Derived>
18001StmtResult
18002TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18003 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18004 // function definition or instantiation of a function template specialization
18005 // and will therefore never appear in a dependent context.
18006 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18007 "context");
18008}
18009
18010template <typename Derived>
18011ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18012 // We can transform the base expression and allow argument resolution to fill
18013 // in the rest.
18014 return getDerived().TransformExpr(E->getArgLValue());
18015}
18016
18017} // end namespace clang
18018
18019#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18020