1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16#include "CoroutineStmtBuilder.h"
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/ExprConcepts.h"
24#include "clang/AST/ExprObjC.h"
25#include "clang/AST/ExprOpenMP.h"
26#include "clang/AST/OpenMPClause.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
30#include "clang/AST/StmtOpenACC.h"
31#include "clang/AST/StmtOpenMP.h"
32#include "clang/AST/StmtSYCL.h"
33#include "clang/Basic/DiagnosticParse.h"
34#include "clang/Basic/OpenMPKinds.h"
35#include "clang/Sema/Designator.h"
36#include "clang/Sema/EnterExpressionEvaluationContext.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Ownership.h"
39#include "clang/Sema/ParsedTemplate.h"
40#include "clang/Sema/ScopeInfo.h"
41#include "clang/Sema/SemaDiagnostic.h"
42#include "clang/Sema/SemaHLSL.h"
43#include "clang/Sema/SemaInternal.h"
44#include "clang/Sema/SemaObjC.h"
45#include "clang/Sema/SemaOpenACC.h"
46#include "clang/Sema/SemaOpenMP.h"
47#include "clang/Sema/SemaPseudoObject.h"
48#include "clang/Sema/SemaSYCL.h"
49#include "clang/Sema/Template.h"
50#include "llvm/ADT/ArrayRef.h"
51#include "llvm/Support/ErrorHandling.h"
52#include <algorithm>
53#include <optional>
54
55using namespace llvm::omp;
56
57namespace clang {
58using namespace sema;
59
60// This helper class is used to facilitate pack expansion during tree transform.
61struct UnexpandedInfo {
62 SourceLocation Ellipsis;
63 UnsignedOrNone OrigNumExpansions = std::nullopt;
64
65 bool Expand = false;
66 bool RetainExpansion = false;
67 UnsignedOrNone NumExpansions = std::nullopt;
68 bool ExpandUnderForgetSubstitions = false;
69};
70
71/// A semantic tree transformation that allows one to transform one
72/// abstract syntax tree into another.
73///
74/// A new tree transformation is defined by creating a new subclass \c X of
75/// \c TreeTransform<X> and then overriding certain operations to provide
76/// behavior specific to that transformation. For example, template
77/// instantiation is implemented as a tree transformation where the
78/// transformation of TemplateTypeParmType nodes involves substituting the
79/// template arguments for their corresponding template parameters; a similar
80/// transformation is performed for non-type template parameters and
81/// template template parameters.
82///
83/// This tree-transformation template uses static polymorphism to allow
84/// subclasses to customize any of its operations. Thus, a subclass can
85/// override any of the transformation or rebuild operators by providing an
86/// operation with the same signature as the default implementation. The
87/// overriding function should not be virtual.
88///
89/// Semantic tree transformations are split into two stages, either of which
90/// can be replaced by a subclass. The "transform" step transforms an AST node
91/// or the parts of an AST node using the various transformation functions,
92/// then passes the pieces on to the "rebuild" step, which constructs a new AST
93/// node of the appropriate kind from the pieces. The default transformation
94/// routines recursively transform the operands to composite AST nodes (e.g.,
95/// the pointee type of a PointerType node) and, if any of those operand nodes
96/// were changed by the transformation, invokes the rebuild operation to create
97/// a new AST node.
98///
99/// Subclasses can customize the transformation at various levels. The
100/// most coarse-grained transformations involve replacing TransformType(),
101/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
102/// TransformTemplateName(), or TransformTemplateArgument() with entirely
103/// new implementations.
104///
105/// For more fine-grained transformations, subclasses can replace any of the
106/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
107/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
108/// replacing TransformTemplateTypeParmType() allows template instantiation
109/// to substitute template arguments for their corresponding template
110/// parameters. Additionally, subclasses can override the \c RebuildXXX
111/// functions to control how AST nodes are rebuilt when their operands change.
112/// By default, \c TreeTransform will invoke semantic analysis to rebuild
113/// AST nodes. However, certain other tree transformations (e.g, cloning) may
114/// be able to use more efficient rebuild steps.
115///
116/// There are a handful of other functions that can be overridden, allowing one
117/// to avoid traversing nodes that don't need any transformation
118/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
119/// operands have not changed (\c AlwaysRebuild()), and customize the
120/// default locations and entity names used for type-checking
121/// (\c getBaseLocation(), \c getBaseEntity()).
122template<typename Derived>
123class TreeTransform {
124 /// Private RAII object that helps us forget and then re-remember
125 /// the template argument corresponding to a partially-substituted parameter
126 /// pack.
127 class ForgetPartiallySubstitutedPackRAII {
128 Derived &Self;
129 TemplateArgument Old;
130 // Set the pack expansion index to -1 to avoid pack substitution and
131 // indicate that parameter packs should be instantiated as themselves.
132 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
133
134 public:
135 ForgetPartiallySubstitutedPackRAII(Derived &Self)
136 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
137 Old = Self.ForgetPartiallySubstitutedPack();
138 }
139
140 ~ForgetPartiallySubstitutedPackRAII() {
141 Self.RememberPartiallySubstitutedPack(Old);
142 }
143 ForgetPartiallySubstitutedPackRAII(
144 const ForgetPartiallySubstitutedPackRAII &) = delete;
145 ForgetPartiallySubstitutedPackRAII &
146 operator=(const ForgetPartiallySubstitutedPackRAII &) = delete;
147 };
148
149protected:
150 Sema &SemaRef;
151
152 /// The set of local declarations that have been transformed, for
153 /// cases where we are forced to build new declarations within the transformer
154 /// rather than in the subclass (e.g., lambda closure types).
155 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
156
157public:
158 /// Initializes a new tree transformer.
159 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
160
161 /// Retrieves a reference to the derived class.
162 Derived &getDerived() { return static_cast<Derived&>(*this); }
163
164 /// Retrieves a reference to the derived class.
165 const Derived &getDerived() const {
166 return static_cast<const Derived&>(*this);
167 }
168
169 static inline ExprResult Owned(Expr *E) { return E; }
170 static inline StmtResult Owned(Stmt *S) { return S; }
171
172 /// Retrieves a reference to the semantic analysis object used for
173 /// this tree transform.
174 Sema &getSema() const { return SemaRef; }
175
176 /// Whether the transformation should always rebuild AST nodes, even
177 /// if none of the children have changed.
178 ///
179 /// Subclasses may override this function to specify when the transformation
180 /// should rebuild all AST nodes.
181 ///
182 /// We must always rebuild all AST nodes when performing variadic template
183 /// pack expansion, in order to avoid violating the AST invariant that each
184 /// statement node appears at most once in its containing declaration.
185 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
186
187 /// Whether the transformation is forming an expression or statement that
188 /// replaces the original. In this case, we'll reuse mangling numbers from
189 /// existing lambdas.
190 bool ReplacingOriginal() { return false; }
191
192 /// Wether CXXConstructExpr can be skipped when they are implicit.
193 /// They will be reconstructed when used if needed.
194 /// This is useful when the user that cause rebuilding of the
195 /// CXXConstructExpr is outside of the expression at which the TreeTransform
196 /// started.
197 bool AllowSkippingCXXConstructExpr() { return true; }
198
199 /// Returns the location of the entity being transformed, if that
200 /// information was not available elsewhere in the AST.
201 ///
202 /// By default, returns no source-location information. Subclasses can
203 /// provide an alternative implementation that provides better location
204 /// information.
205 SourceLocation getBaseLocation() { return SourceLocation(); }
206
207 /// Returns the name of the entity being transformed, if that
208 /// information was not available elsewhere in the AST.
209 ///
210 /// By default, returns an empty name. Subclasses can provide an alternative
211 /// implementation with a more precise name.
212 DeclarationName getBaseEntity() { return DeclarationName(); }
213
214 /// Sets the "base" location and entity when that
215 /// information is known based on another transformation.
216 ///
217 /// By default, the source location and entity are ignored. Subclasses can
218 /// override this function to provide a customized implementation.
219 void setBase(SourceLocation Loc, DeclarationName Entity) { }
220
221 /// RAII object that temporarily sets the base location and entity
222 /// used for reporting diagnostics in types.
223 class TemporaryBase {
224 TreeTransform &Self;
225 SourceLocation OldLocation;
226 DeclarationName OldEntity;
227
228 public:
229 TemporaryBase(TreeTransform &Self, SourceLocation Location,
230 DeclarationName Entity) : Self(Self) {
231 OldLocation = Self.getDerived().getBaseLocation();
232 OldEntity = Self.getDerived().getBaseEntity();
233
234 if (Location.isValid())
235 Self.getDerived().setBase(Location, Entity);
236 }
237
238 ~TemporaryBase() {
239 Self.getDerived().setBase(OldLocation, OldEntity);
240 }
241 TemporaryBase(const TemporaryBase &) = delete;
242 TemporaryBase &operator=(const TemporaryBase &) = delete;
243 };
244
245 /// Determine whether the given type \p T has already been
246 /// transformed.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine
249 /// to short-circuit evaluation when it is known that a given type will
250 /// not change. For example, template instantiation need not traverse
251 /// non-dependent types.
252 bool AlreadyTransformed(QualType T) {
253 return T.isNull();
254 }
255
256 /// Transform a template parameter depth level.
257 ///
258 /// During a transformation that transforms template parameters, this maps
259 /// an old template parameter depth to a new depth.
260 unsigned TransformTemplateDepth(unsigned Depth) {
261 return Depth;
262 }
263
264 /// Determine whether the given call argument should be dropped, e.g.,
265 /// because it is a default argument.
266 ///
267 /// Subclasses can provide an alternative implementation of this routine to
268 /// determine which kinds of call arguments get dropped. By default,
269 /// CXXDefaultArgument nodes are dropped (prior to transformation).
270 bool DropCallArgument(Expr *E) {
271 return E->isDefaultArgument();
272 }
273
274 /// Determine whether we should expand a pack expansion with the
275 /// given set of parameter packs into separate arguments by repeatedly
276 /// transforming the pattern.
277 ///
278 /// By default, the transformer never tries to expand pack expansions.
279 /// Subclasses can override this routine to provide different behavior.
280 ///
281 /// \param EllipsisLoc The location of the ellipsis that identifies the
282 /// pack expansion.
283 ///
284 /// \param PatternRange The source range that covers the entire pattern of
285 /// the pack expansion.
286 ///
287 /// \param Unexpanded The set of unexpanded parameter packs within the
288 /// pattern.
289 ///
290 /// \param ShouldExpand Will be set to \c true if the transformer should
291 /// expand the corresponding pack expansions into separate arguments. When
292 /// set, \c NumExpansions must also be set.
293 ///
294 /// \param RetainExpansion Whether the caller should add an unexpanded
295 /// pack expansion after all of the expanded arguments. This is used
296 /// when extending explicitly-specified template argument packs per
297 /// C++0x [temp.arg.explicit]p9.
298 ///
299 /// \param NumExpansions The number of separate arguments that will be in
300 /// the expanded form of the corresponding pack expansion. This is both an
301 /// input and an output parameter, which can be set by the caller if the
302 /// number of expansions is known a priori (e.g., due to a prior substitution)
303 /// and will be set by the callee when the number of expansions is known.
304 /// The callee must set this value when \c ShouldExpand is \c true; it may
305 /// set this value in other cases.
306 ///
307 /// \returns true if an error occurred (e.g., because the parameter packs
308 /// are to be instantiated with arguments of different lengths), false
309 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
310 /// must be set.
311 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
312 SourceRange PatternRange,
313 ArrayRef<UnexpandedParameterPack> Unexpanded,
314 bool FailOnPackProducingTemplates,
315 bool &ShouldExpand, bool &RetainExpansion,
316 UnsignedOrNone &NumExpansions) {
317 ShouldExpand = false;
318 return false;
319 }
320
321 /// "Forget" about the partially-substituted pack template argument,
322 /// when performing an instantiation that must preserve the parameter pack
323 /// use.
324 ///
325 /// This routine is meant to be overridden by the template instantiator.
326 TemplateArgument ForgetPartiallySubstitutedPack() {
327 return TemplateArgument();
328 }
329
330 /// "Remember" the partially-substituted pack template argument
331 /// after performing an instantiation that must preserve the parameter pack
332 /// use.
333 ///
334 /// This routine is meant to be overridden by the template instantiator.
335 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
336
337 /// "Forget" the template substitution to allow transforming the AST without
338 /// any template instantiations. This is used to expand template packs when
339 /// their size is not known in advance (e.g. for builtins that produce type
340 /// packs).
341 MultiLevelTemplateArgumentList ForgetSubstitution() { return {}; }
342 void RememberSubstitution(MultiLevelTemplateArgumentList) {}
343
344private:
345 struct ForgetSubstitutionRAII {
346 Derived &Self;
347 MultiLevelTemplateArgumentList Old;
348
349 public:
350 ForgetSubstitutionRAII(Derived &Self) : Self(Self) {
351 Old = Self.ForgetSubstitution();
352 }
353
354 ~ForgetSubstitutionRAII() { Self.RememberSubstitution(std::move(Old)); }
355 };
356
357public:
358 /// Note to the derived class when a function parameter pack is
359 /// being expanded.
360 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
361
362 /// Transforms the given type into another type.
363 ///
364 /// By default, this routine transforms a type by creating a
365 /// TypeSourceInfo for it and delegating to the appropriate
366 /// function. This is expensive, but we don't mind, because
367 /// this method is deprecated anyway; all users should be
368 /// switched to storing TypeSourceInfos.
369 ///
370 /// \returns the transformed type.
371 QualType TransformType(QualType T);
372
373 /// Transforms the given type-with-location into a new
374 /// type-with-location.
375 ///
376 /// By default, this routine transforms a type by delegating to the
377 /// appropriate TransformXXXType to build a new type. Subclasses
378 /// may override this function (to take over all type
379 /// transformations) or some set of the TransformXXXType functions
380 /// to alter the transformation.
381 TypeSourceInfo *TransformType(TypeSourceInfo *TSI);
382
383 /// Transform the given type-with-location into a new
384 /// type, collecting location information in the given builder
385 /// as necessary.
386 ///
387 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
388
389 /// Transform a type that is permitted to produce a
390 /// DeducedTemplateSpecializationType.
391 ///
392 /// This is used in the (relatively rare) contexts where it is acceptable
393 /// for transformation to produce a class template type with deduced
394 /// template arguments.
395 /// @{
396 QualType TransformTypeWithDeducedTST(QualType T);
397 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *TSI);
398 /// @}
399
400 /// The reason why the value of a statement is not discarded, if any.
401 enum class StmtDiscardKind {
402 Discarded,
403 NotDiscarded,
404 StmtExprResult,
405 };
406
407 /// Transform the given statement.
408 ///
409 /// By default, this routine transforms a statement by delegating to the
410 /// appropriate TransformXXXStmt function to transform a specific kind of
411 /// statement or the TransformExpr() function to transform an expression.
412 /// Subclasses may override this function to transform statements using some
413 /// other mechanism.
414 ///
415 /// \returns the transformed statement.
416 StmtResult TransformStmt(Stmt *S,
417 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
418
419 /// Transform the given statement.
420 ///
421 /// By default, this routine transforms a statement by delegating to the
422 /// appropriate TransformOMPXXXClause function to transform a specific kind
423 /// of clause. Subclasses may override this function to transform statements
424 /// using some other mechanism.
425 ///
426 /// \returns the transformed OpenMP clause.
427 OMPClause *TransformOMPClause(OMPClause *S);
428
429 /// Transform the given attribute.
430 ///
431 /// By default, this routine transforms a statement by delegating to the
432 /// appropriate TransformXXXAttr function to transform a specific kind
433 /// of attribute. Subclasses may override this function to transform
434 /// attributed statements/types using some other mechanism.
435 ///
436 /// \returns the transformed attribute
437 const Attr *TransformAttr(const Attr *S);
438
439 // Transform the given statement attribute.
440 //
441 // Delegates to the appropriate TransformXXXAttr function to transform a
442 // specific kind of statement attribute. Unlike the non-statement taking
443 // version of this, this implements all attributes, not just pragmas.
444 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
445 const Attr *A);
446
447 // Transform the specified attribute.
448 //
449 // Subclasses should override the transformation of attributes with a pragma
450 // spelling to transform expressions stored within the attribute.
451 //
452 // \returns the transformed attribute.
453#define ATTR(X) \
454 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
455#include "clang/Basic/AttrList.inc"
456
457 // Transform the specified attribute.
458 //
459 // Subclasses should override the transformation of attributes to do
460 // transformation and checking of statement attributes. By default, this
461 // delegates to the non-statement taking version.
462 //
463 // \returns the transformed attribute.
464#define ATTR(X) \
465 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
466 const X##Attr *A) { \
467 return getDerived().Transform##X##Attr(A); \
468 }
469#include "clang/Basic/AttrList.inc"
470
471 /// Transform the given expression.
472 ///
473 /// By default, this routine transforms an expression by delegating to the
474 /// appropriate TransformXXXExpr function to build a new expression.
475 /// Subclasses may override this function to transform expressions using some
476 /// other mechanism.
477 ///
478 /// \returns the transformed expression.
479 ExprResult TransformExpr(Expr *E);
480
481 /// Transform the given initializer.
482 ///
483 /// By default, this routine transforms an initializer by stripping off the
484 /// semantic nodes added by initialization, then passing the result to
485 /// TransformExpr or TransformExprs.
486 ///
487 /// \returns the transformed initializer.
488 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
489
490 /// Transform the given list of expressions.
491 ///
492 /// This routine transforms a list of expressions by invoking
493 /// \c TransformExpr() for each subexpression. However, it also provides
494 /// support for variadic templates by expanding any pack expansions (if the
495 /// derived class permits such expansion) along the way. When pack expansions
496 /// are present, the number of outputs may not equal the number of inputs.
497 ///
498 /// \param Inputs The set of expressions to be transformed.
499 ///
500 /// \param NumInputs The number of expressions in \c Inputs.
501 ///
502 /// \param IsCall If \c true, then this transform is being performed on
503 /// function-call arguments, and any arguments that should be dropped, will
504 /// be.
505 ///
506 /// \param Outputs The transformed input expressions will be added to this
507 /// vector.
508 ///
509 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
510 /// due to transformation.
511 ///
512 /// \returns true if an error occurred, false otherwise.
513 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
514 SmallVectorImpl<Expr *> &Outputs,
515 bool *ArgChanged = nullptr);
516
517 /// Transform the given declaration, which is referenced from a type
518 /// or expression.
519 ///
520 /// By default, acts as the identity function on declarations, unless the
521 /// transformer has had to transform the declaration itself. Subclasses
522 /// may override this function to provide alternate behavior.
523 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
524 llvm::DenseMap<Decl *, Decl *>::iterator Known
525 = TransformedLocalDecls.find(Val: D);
526 if (Known != TransformedLocalDecls.end())
527 return Known->second;
528
529 return D;
530 }
531
532 /// Transform the specified condition.
533 ///
534 /// By default, this transforms the variable and expression and rebuilds
535 /// the condition.
536 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
537 Expr *Expr,
538 Sema::ConditionKind Kind);
539
540 /// Transform the attributes associated with the given declaration and
541 /// place them on the new declaration.
542 ///
543 /// By default, this operation does nothing. Subclasses may override this
544 /// behavior to transform attributes.
545 void transformAttrs(Decl *Old, Decl *New) { }
546
547 /// Note that a local declaration has been transformed by this
548 /// transformer.
549 ///
550 /// Local declarations are typically transformed via a call to
551 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
552 /// the transformer itself has to transform the declarations. This routine
553 /// can be overridden by a subclass that keeps track of such mappings.
554 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
555 assert(New.size() == 1 &&
556 "must override transformedLocalDecl if performing pack expansion");
557 TransformedLocalDecls[Old] = New.front();
558 }
559
560 /// Transform the definition of the given declaration.
561 ///
562 /// By default, invokes TransformDecl() to transform the declaration.
563 /// Subclasses may override this function to provide alternate behavior.
564 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
565 return getDerived().TransformDecl(Loc, D);
566 }
567
568 /// Transform the given declaration, which was the first part of a
569 /// nested-name-specifier in a member access expression.
570 ///
571 /// This specific declaration transformation only applies to the first
572 /// identifier in a nested-name-specifier of a member access expression, e.g.,
573 /// the \c T in \c x->T::member
574 ///
575 /// By default, invokes TransformDecl() to transform the declaration.
576 /// Subclasses may override this function to provide alternate behavior.
577 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
578 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
579 }
580
581 /// Transform the set of declarations in an OverloadExpr.
582 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
583 LookupResult &R);
584
585 /// Transform the given nested-name-specifier with source-location
586 /// information.
587 ///
588 /// By default, transforms all of the types and declarations within the
589 /// nested-name-specifier. Subclasses may override this function to provide
590 /// alternate behavior.
591 NestedNameSpecifierLoc
592 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
593 QualType ObjectType = QualType(),
594 NamedDecl *FirstQualifierInScope = nullptr);
595
596 /// Transform the given declaration name.
597 ///
598 /// By default, transforms the types of conversion function, constructor,
599 /// and destructor names and then (if needed) rebuilds the declaration name.
600 /// Identifiers and selectors are returned unmodified. Subclasses may
601 /// override this function to provide alternate behavior.
602 DeclarationNameInfo
603 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
604
605 bool TransformRequiresExprRequirements(
606 ArrayRef<concepts::Requirement *> Reqs,
607 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
608 concepts::TypeRequirement *
609 TransformTypeRequirement(concepts::TypeRequirement *Req);
610 concepts::ExprRequirement *
611 TransformExprRequirement(concepts::ExprRequirement *Req);
612 concepts::NestedRequirement *
613 TransformNestedRequirement(concepts::NestedRequirement *Req);
614
615 /// Transform the given template name.
616 ///
617 /// \param SS The nested-name-specifier that qualifies the template
618 /// name. This nested-name-specifier must already have been transformed.
619 ///
620 /// \param Name The template name to transform.
621 ///
622 /// \param NameLoc The source location of the template name.
623 ///
624 /// \param ObjectType If we're translating a template name within a member
625 /// access expression, this is the type of the object whose member template
626 /// is being referenced.
627 ///
628 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
629 /// also refers to a name within the current (lexical) scope, this is the
630 /// declaration it refers to.
631 ///
632 /// By default, transforms the template name by transforming the declarations
633 /// and nested-name-specifiers that occur within the template name.
634 /// Subclasses may override this function to provide alternate behavior.
635 TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
636 SourceLocation TemplateKWLoc,
637 TemplateName Name, SourceLocation NameLoc,
638 QualType ObjectType = QualType(),
639 NamedDecl *FirstQualifierInScope = nullptr,
640 bool AllowInjectedClassName = false);
641
642 /// Transform the given template argument.
643 ///
644 /// By default, this operation transforms the type, expression, or
645 /// declaration stored within the template argument and constructs a
646 /// new template argument from the transformed result. Subclasses may
647 /// override this function to provide alternate behavior.
648 ///
649 /// Returns true if there was an error.
650 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
651 TemplateArgumentLoc &Output,
652 bool Uneval = false);
653
654 TemplateArgument TransformNamedTemplateTemplateArgument(
655 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
656 TemplateName Name, SourceLocation NameLoc);
657
658 /// Transform the given set of template arguments.
659 ///
660 /// By default, this operation transforms all of the template arguments
661 /// in the input set using \c TransformTemplateArgument(), and appends
662 /// the transformed arguments to the output list.
663 ///
664 /// Note that this overload of \c TransformTemplateArguments() is merely
665 /// a convenience function. Subclasses that wish to override this behavior
666 /// should override the iterator-based member template version.
667 ///
668 /// \param Inputs The set of template arguments to be transformed.
669 ///
670 /// \param NumInputs The number of template arguments in \p Inputs.
671 ///
672 /// \param Outputs The set of transformed template arguments output by this
673 /// routine.
674 ///
675 /// Returns true if an error occurred.
676 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
677 unsigned NumInputs,
678 TemplateArgumentListInfo &Outputs,
679 bool Uneval = false) {
680 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
681 Uneval);
682 }
683
684 /// Transform the given set of template arguments.
685 ///
686 /// By default, this operation transforms all of the template arguments
687 /// in the input set using \c TransformTemplateArgument(), and appends
688 /// the transformed arguments to the output list.
689 ///
690 /// \param First An iterator to the first template argument.
691 ///
692 /// \param Last An iterator one step past the last template argument.
693 ///
694 /// \param Outputs The set of transformed template arguments output by this
695 /// routine.
696 ///
697 /// Returns true if an error occurred.
698 template<typename InputIterator>
699 bool TransformTemplateArguments(InputIterator First,
700 InputIterator Last,
701 TemplateArgumentListInfo &Outputs,
702 bool Uneval = false);
703
704 template <typename InputIterator>
705 bool TransformConceptTemplateArguments(InputIterator First,
706 InputIterator Last,
707 TemplateArgumentListInfo &Outputs,
708 bool Uneval = false);
709
710 /// Checks if the argument pack from \p In will need to be expanded and does
711 /// the necessary prework.
712 /// Whether the expansion is needed is captured in Info.Expand.
713 ///
714 /// - When the expansion is required, \p Out will be a template pattern that
715 /// would need to be expanded.
716 /// - When the expansion must not happen, \p Out will be a pack that must be
717 /// returned to the outputs directly.
718 ///
719 /// \return true iff the error occurred
720 bool PreparePackForExpansion(TemplateArgumentLoc In, bool Uneval,
721 TemplateArgumentLoc &Out, UnexpandedInfo &Info);
722
723 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
724 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
725 TemplateArgumentLoc &ArgLoc);
726
727 /// Fakes up a TypeSourceInfo for a type.
728 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
729 return SemaRef.Context.getTrivialTypeSourceInfo(T,
730 Loc: getDerived().getBaseLocation());
731 }
732
733#define ABSTRACT_TYPELOC(CLASS, PARENT)
734#define TYPELOC(CLASS, PARENT) \
735 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
736#include "clang/AST/TypeLocNodes.def"
737
738 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
739 TemplateTypeParmTypeLoc TL,
740 bool SuppressObjCLifetime);
741 QualType
742 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
743 SubstTemplateTypeParmPackTypeLoc TL,
744 bool SuppressObjCLifetime);
745
746 template<typename Fn>
747 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
748 FunctionProtoTypeLoc TL,
749 CXXRecordDecl *ThisContext,
750 Qualifiers ThisTypeQuals,
751 Fn TransformExceptionSpec);
752
753 bool TransformExceptionSpec(SourceLocation Loc,
754 FunctionProtoType::ExceptionSpecInfo &ESI,
755 SmallVectorImpl<QualType> &Exceptions,
756 bool &Changed);
757
758 StmtResult TransformSEHHandler(Stmt *Handler);
759
760 QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
761 TemplateSpecializationTypeLoc TL,
762 QualType ObjectType,
763 NamedDecl *FirstQualifierInScope,
764 bool AllowInjectedClassName);
765
766 QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
767
768 /// Transforms the parameters of a function type into the
769 /// given vectors.
770 ///
771 /// The result vectors should be kept in sync; null entries in the
772 /// variables vector are acceptable.
773 ///
774 /// LastParamTransformed, if non-null, will be set to the index of the last
775 /// parameter on which transformation was started. In the event of an error,
776 /// this will contain the parameter which failed to instantiate.
777 ///
778 /// Return true on error.
779 bool TransformFunctionTypeParams(
780 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
781 const QualType *ParamTypes,
782 const FunctionProtoType::ExtParameterInfo *ParamInfos,
783 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
784 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
785
786 bool TransformFunctionTypeParams(
787 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
788 const QualType *ParamTypes,
789 const FunctionProtoType::ExtParameterInfo *ParamInfos,
790 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
791 Sema::ExtParameterInfoBuilder &PInfos) {
792 return getDerived().TransformFunctionTypeParams(
793 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
794 }
795
796 /// Transforms the parameters of a requires expresison into the given vectors.
797 ///
798 /// The result vectors should be kept in sync; null entries in the
799 /// variables vector are acceptable.
800 ///
801 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
802 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
803 /// which are cases where transformation shouldn't continue.
804 ExprResult TransformRequiresTypeParams(
805 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
806 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
807 SmallVectorImpl<QualType> &PTypes,
808 SmallVectorImpl<ParmVarDecl *> &TransParams,
809 Sema::ExtParameterInfoBuilder &PInfos) {
810 if (getDerived().TransformFunctionTypeParams(
811 KWLoc, Params, /*ParamTypes=*/nullptr,
812 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
813 return ExprError();
814
815 return ExprResult{};
816 }
817
818 /// Transforms a single function-type parameter. Return null
819 /// on error.
820 ///
821 /// \param indexAdjustment - A number to add to the parameter's
822 /// scope index; can be negative
823 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
824 int indexAdjustment,
825 UnsignedOrNone NumExpansions,
826 bool ExpectParameterPack);
827
828 /// Transform the body of a lambda-expression.
829 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
830 /// Alternative implementation of TransformLambdaBody that skips transforming
831 /// the body.
832 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
833
834 CXXRecordDecl::LambdaDependencyKind
835 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
836 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
837 LSI->Lambda->getLambdaDependencyKind());
838 }
839
840 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
841
842 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
843 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
844
845 TemplateParameterList *TransformTemplateParameterList(
846 TemplateParameterList *TPL) {
847 return TPL;
848 }
849
850 ExprResult TransformAddressOfOperand(Expr *E);
851
852 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
853 bool IsAddressOfOperand,
854 TypeSourceInfo **RecoveryTSI);
855
856 ExprResult TransformParenDependentScopeDeclRefExpr(
857 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
858 TypeSourceInfo **RecoveryTSI);
859
860 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
861 bool IsAddressOfOperand);
862
863 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
864
865 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
866
867// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
868// amount of stack usage with clang.
869#define STMT(Node, Parent) \
870 LLVM_ATTRIBUTE_NOINLINE \
871 StmtResult Transform##Node(Node *S);
872#define VALUESTMT(Node, Parent) \
873 LLVM_ATTRIBUTE_NOINLINE \
874 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
875#define EXPR(Node, Parent) \
876 LLVM_ATTRIBUTE_NOINLINE \
877 ExprResult Transform##Node(Node *E);
878#define ABSTRACT_STMT(Stmt)
879#include "clang/AST/StmtNodes.inc"
880
881#define GEN_CLANG_CLAUSE_CLASS
882#define CLAUSE_CLASS(Enum, Str, Class) \
883 LLVM_ATTRIBUTE_NOINLINE \
884 OMPClause *Transform##Class(Class *S);
885#include "llvm/Frontend/OpenMP/OMP.inc"
886
887 /// Build a new qualified type given its unqualified type and type location.
888 ///
889 /// By default, this routine adds type qualifiers only to types that can
890 /// have qualifiers, and silently suppresses those qualifiers that are not
891 /// permitted. Subclasses may override this routine to provide different
892 /// behavior.
893 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
894
895 /// Build a new pointer type given its pointee type.
896 ///
897 /// By default, performs semantic analysis when building the pointer type.
898 /// Subclasses may override this routine to provide different behavior.
899 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
900
901 /// Build a new block pointer type given its pointee type.
902 ///
903 /// By default, performs semantic analysis when building the block pointer
904 /// type. Subclasses may override this routine to provide different behavior.
905 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
906
907 /// Build a new reference type given the type it references.
908 ///
909 /// By default, performs semantic analysis when building the
910 /// reference type. Subclasses may override this routine to provide
911 /// different behavior.
912 ///
913 /// \param LValue whether the type was written with an lvalue sigil
914 /// or an rvalue sigil.
915 QualType RebuildReferenceType(QualType ReferentType,
916 bool LValue,
917 SourceLocation Sigil);
918
919 /// Build a new member pointer type given the pointee type and the
920 /// qualifier it refers into.
921 ///
922 /// By default, performs semantic analysis when building the member pointer
923 /// type. Subclasses may override this routine to provide different behavior.
924 QualType RebuildMemberPointerType(QualType PointeeType,
925 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
926 SourceLocation Sigil);
927
928 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
929 SourceLocation ProtocolLAngleLoc,
930 ArrayRef<ObjCProtocolDecl *> Protocols,
931 ArrayRef<SourceLocation> ProtocolLocs,
932 SourceLocation ProtocolRAngleLoc);
933
934 /// Build an Objective-C object type.
935 ///
936 /// By default, performs semantic analysis when building the object type.
937 /// Subclasses may override this routine to provide different behavior.
938 QualType RebuildObjCObjectType(QualType BaseType,
939 SourceLocation Loc,
940 SourceLocation TypeArgsLAngleLoc,
941 ArrayRef<TypeSourceInfo *> TypeArgs,
942 SourceLocation TypeArgsRAngleLoc,
943 SourceLocation ProtocolLAngleLoc,
944 ArrayRef<ObjCProtocolDecl *> Protocols,
945 ArrayRef<SourceLocation> ProtocolLocs,
946 SourceLocation ProtocolRAngleLoc);
947
948 /// Build a new Objective-C object pointer type given the pointee type.
949 ///
950 /// By default, directly builds the pointer type, with no additional semantic
951 /// analysis.
952 QualType RebuildObjCObjectPointerType(QualType PointeeType,
953 SourceLocation Star);
954
955 /// Build a new array type given the element type, size
956 /// modifier, size of the array (if known), size expression, and index type
957 /// qualifiers.
958 ///
959 /// By default, performs semantic analysis when building the array type.
960 /// Subclasses may override this routine to provide different behavior.
961 /// Also by default, all of the other Rebuild*Array
962 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
963 const llvm::APInt *Size, Expr *SizeExpr,
964 unsigned IndexTypeQuals, SourceRange BracketsRange);
965
966 /// Build a new constant array type given the element type, size
967 /// modifier, (known) size of the array, and index type qualifiers.
968 ///
969 /// By default, performs semantic analysis when building the array type.
970 /// Subclasses may override this routine to provide different behavior.
971 QualType RebuildConstantArrayType(QualType ElementType,
972 ArraySizeModifier SizeMod,
973 const llvm::APInt &Size, Expr *SizeExpr,
974 unsigned IndexTypeQuals,
975 SourceRange BracketsRange);
976
977 /// Build a new incomplete array type given the element type, size
978 /// modifier, and index type qualifiers.
979 ///
980 /// By default, performs semantic analysis when building the array type.
981 /// Subclasses may override this routine to provide different behavior.
982 QualType RebuildIncompleteArrayType(QualType ElementType,
983 ArraySizeModifier SizeMod,
984 unsigned IndexTypeQuals,
985 SourceRange BracketsRange);
986
987 /// Build a new variable-length array type given the element type,
988 /// size modifier, size expression, and index type qualifiers.
989 ///
990 /// By default, performs semantic analysis when building the array type.
991 /// Subclasses may override this routine to provide different behavior.
992 QualType RebuildVariableArrayType(QualType ElementType,
993 ArraySizeModifier SizeMod, Expr *SizeExpr,
994 unsigned IndexTypeQuals,
995 SourceRange BracketsRange);
996
997 /// Build a new dependent-sized array type given the element type,
998 /// size modifier, size expression, and index type qualifiers.
999 ///
1000 /// By default, performs semantic analysis when building the array type.
1001 /// Subclasses may override this routine to provide different behavior.
1002 QualType RebuildDependentSizedArrayType(QualType ElementType,
1003 ArraySizeModifier SizeMod,
1004 Expr *SizeExpr,
1005 unsigned IndexTypeQuals,
1006 SourceRange BracketsRange);
1007
1008 /// Build a new vector type given the element type and
1009 /// number of elements.
1010 ///
1011 /// By default, performs semantic analysis when building the vector type.
1012 /// Subclasses may override this routine to provide different behavior.
1013 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1014 VectorKind VecKind);
1015
1016 /// Build a new potentially dependently-sized extended vector type
1017 /// given the element type and number of elements.
1018 ///
1019 /// By default, performs semantic analysis when building the vector type.
1020 /// Subclasses may override this routine to provide different behavior.
1021 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1022 SourceLocation AttributeLoc, VectorKind);
1023
1024 /// Build a new extended vector type given the element type and
1025 /// number of elements.
1026 ///
1027 /// By default, performs semantic analysis when building the vector type.
1028 /// Subclasses may override this routine to provide different behavior.
1029 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1030 SourceLocation AttributeLoc);
1031
1032 /// Build a new potentially dependently-sized extended vector type
1033 /// given the element type and number of elements.
1034 ///
1035 /// By default, performs semantic analysis when building the vector type.
1036 /// Subclasses may override this routine to provide different behavior.
1037 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1038 Expr *SizeExpr,
1039 SourceLocation AttributeLoc);
1040
1041 /// Build a new matrix type given the element type and dimensions.
1042 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1043 unsigned NumColumns);
1044
1045 /// Build a new matrix type given the type and dependently-defined
1046 /// dimensions.
1047 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1048 Expr *ColumnExpr,
1049 SourceLocation AttributeLoc);
1050
1051 /// Build a new DependentAddressSpaceType or return the pointee
1052 /// type variable with the correct address space (retrieved from
1053 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1054 /// where the address space remains dependent.
1055 ///
1056 /// By default, performs semantic analysis when building the type with address
1057 /// space applied. Subclasses may override this routine to provide different
1058 /// behavior.
1059 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1060 Expr *AddrSpaceExpr,
1061 SourceLocation AttributeLoc);
1062
1063 /// Build a new function type.
1064 ///
1065 /// By default, performs semantic analysis when building the function type.
1066 /// Subclasses may override this routine to provide different behavior.
1067 QualType RebuildFunctionProtoType(QualType T,
1068 MutableArrayRef<QualType> ParamTypes,
1069 const FunctionProtoType::ExtProtoInfo &EPI);
1070
1071 /// Build a new unprototyped function type.
1072 QualType RebuildFunctionNoProtoType(QualType ResultType);
1073
1074 /// Rebuild an unresolved typename type, given the decl that
1075 /// the UnresolvedUsingTypenameDecl was transformed to.
1076 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1077 NestedNameSpecifier Qualifier,
1078 SourceLocation NameLoc, Decl *D);
1079
1080 /// Build a new type found via an alias.
1081 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1082 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1083 QualType UnderlyingType) {
1084 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1085 }
1086
1087 /// Build a new typedef type.
1088 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1089 NestedNameSpecifier Qualifier,
1090 TypedefNameDecl *Typedef) {
1091 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1092 }
1093
1094 /// Build a new MacroDefined type.
1095 QualType RebuildMacroQualifiedType(QualType T,
1096 const IdentifierInfo *MacroII) {
1097 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1098 }
1099
1100 /// Build a new class/struct/union/enum type.
1101 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1102 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1103 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1104 /*OwnsTag=*/OwnsTag: false);
1105 }
1106 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1107 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1108 }
1109
1110 /// Build a new typeof(expr) type.
1111 ///
1112 /// By default, performs semantic analysis when building the typeof type.
1113 /// Subclasses may override this routine to provide different behavior.
1114 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1115 TypeOfKind Kind);
1116
1117 /// Build a new typeof(type) type.
1118 ///
1119 /// By default, builds a new TypeOfType with the given underlying type.
1120 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1121
1122 /// Build a new unary transform type.
1123 QualType RebuildUnaryTransformType(QualType BaseType,
1124 UnaryTransformType::UTTKind UKind,
1125 SourceLocation Loc);
1126
1127 /// Build a new C++11 decltype type.
1128 ///
1129 /// By default, performs semantic analysis when building the decltype type.
1130 /// Subclasses may override this routine to provide different behavior.
1131 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1132
1133 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1134 SourceLocation Loc,
1135 SourceLocation EllipsisLoc,
1136 bool FullySubstituted,
1137 ArrayRef<QualType> Expansions = {});
1138
1139 /// Build a new C++11 auto type.
1140 ///
1141 /// By default, builds a new AutoType with the given deduced type.
1142 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1143 AutoTypeKeyword Keyword,
1144 ConceptDecl *TypeConstraintConcept,
1145 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1146 return SemaRef.Context.getAutoType(
1147 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1148 }
1149
1150 /// By default, builds a new DeducedTemplateSpecializationType with the given
1151 /// deduced type.
1152 QualType RebuildDeducedTemplateSpecializationType(
1153 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1154 TemplateName Template) {
1155 return SemaRef.Context.getDeducedTemplateSpecializationType(
1156 DK, DeducedAsType, Keyword, Template);
1157 }
1158
1159 /// Build a new template specialization type.
1160 ///
1161 /// By default, performs semantic analysis when building the template
1162 /// specialization type. Subclasses may override this routine to provide
1163 /// different behavior.
1164 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1165 TemplateName Template,
1166 SourceLocation TemplateLoc,
1167 TemplateArgumentListInfo &Args);
1168
1169 /// Build a new parenthesized type.
1170 ///
1171 /// By default, builds a new ParenType type from the inner type.
1172 /// Subclasses may override this routine to provide different behavior.
1173 QualType RebuildParenType(QualType InnerType) {
1174 return SemaRef.BuildParenType(T: InnerType);
1175 }
1176
1177 /// Build a new typename type that refers to an identifier.
1178 ///
1179 /// By default, performs semantic analysis when building the typename type
1180 /// (or elaborated type). Subclasses may override this routine to provide
1181 /// different behavior.
1182 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1183 SourceLocation KeywordLoc,
1184 NestedNameSpecifierLoc QualifierLoc,
1185 const IdentifierInfo *Id,
1186 SourceLocation IdLoc,
1187 bool DeducedTSTContext) {
1188 CXXScopeSpec SS;
1189 SS.Adopt(Other: QualifierLoc);
1190
1191 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1192 // If the name is still dependent, just build a new dependent name type.
1193 if (!SemaRef.computeDeclContext(SS))
1194 return SemaRef.Context.getDependentNameType(Keyword,
1195 NNS: QualifierLoc.getNestedNameSpecifier(),
1196 Name: Id);
1197 }
1198
1199 if (Keyword == ElaboratedTypeKeyword::None ||
1200 Keyword == ElaboratedTypeKeyword::Typename) {
1201 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1202 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1203 }
1204
1205 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1206
1207 // We had a dependent elaborated-type-specifier that has been transformed
1208 // into a non-dependent elaborated-type-specifier. Find the tag we're
1209 // referring to.
1210 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1211 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1212 if (!DC)
1213 return QualType();
1214
1215 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1216 return QualType();
1217
1218 TagDecl *Tag = nullptr;
1219 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1220 switch (Result.getResultKind()) {
1221 case LookupResultKind::NotFound:
1222 case LookupResultKind::NotFoundInCurrentInstantiation:
1223 break;
1224
1225 case LookupResultKind::Found:
1226 Tag = Result.getAsSingle<TagDecl>();
1227 break;
1228
1229 case LookupResultKind::FoundOverloaded:
1230 case LookupResultKind::FoundUnresolvedValue:
1231 llvm_unreachable("Tag lookup cannot find non-tags");
1232
1233 case LookupResultKind::Ambiguous:
1234 // Let the LookupResult structure handle ambiguities.
1235 return QualType();
1236 }
1237
1238 if (!Tag) {
1239 // Check where the name exists but isn't a tag type and use that to emit
1240 // better diagnostics.
1241 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1242 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1243 switch (Result.getResultKind()) {
1244 case LookupResultKind::Found:
1245 case LookupResultKind::FoundOverloaded:
1246 case LookupResultKind::FoundUnresolvedValue: {
1247 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1248 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1249 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1250 << SomeDecl << NTK << Kind;
1251 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1252 break;
1253 }
1254 default:
1255 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1256 << Kind << Id << DC << QualifierLoc.getSourceRange();
1257 break;
1258 }
1259 return QualType();
1260 }
1261 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1262 NewTagLoc: IdLoc, Name: Id)) {
1263 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1264 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1265 return QualType();
1266 }
1267 return getDerived().RebuildTagType(
1268 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1269 }
1270
1271 /// Build a new pack expansion type.
1272 ///
1273 /// By default, builds a new PackExpansionType type from the given pattern.
1274 /// Subclasses may override this routine to provide different behavior.
1275 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1276 SourceLocation EllipsisLoc,
1277 UnsignedOrNone NumExpansions) {
1278 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1279 NumExpansions);
1280 }
1281
1282 /// Build a new atomic type given its value type.
1283 ///
1284 /// By default, performs semantic analysis when building the atomic type.
1285 /// Subclasses may override this routine to provide different behavior.
1286 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1287
1288 /// Build a new pipe type given its value type.
1289 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1290 bool isReadPipe);
1291
1292 /// Build a bit-precise int given its value type.
1293 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1294 SourceLocation Loc);
1295
1296 /// Build a dependent bit-precise int given its value type.
1297 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1298 SourceLocation Loc);
1299
1300 /// Build a new template name given a nested name specifier, a flag
1301 /// indicating whether the "template" keyword was provided, and the template
1302 /// that the template name refers to.
1303 ///
1304 /// By default, builds the new template name directly. Subclasses may override
1305 /// this routine to provide different behavior.
1306 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1307 TemplateName Name);
1308
1309 /// Build a new template name given a nested name specifier and the
1310 /// name that is referred to as a template.
1311 ///
1312 /// By default, performs semantic analysis to determine whether the name can
1313 /// be resolved to a specific template, then builds the appropriate kind of
1314 /// template name. Subclasses may override this routine to provide different
1315 /// behavior.
1316 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1317 SourceLocation TemplateKWLoc,
1318 const IdentifierInfo &Name,
1319 SourceLocation NameLoc, QualType ObjectType,
1320 bool AllowInjectedClassName);
1321
1322 /// Build a new template name given a nested name specifier and the
1323 /// overloaded operator name that is referred to as a template.
1324 ///
1325 /// By default, performs semantic analysis to determine whether the name can
1326 /// be resolved to a specific template, then builds the appropriate kind of
1327 /// template name. Subclasses may override this routine to provide different
1328 /// behavior.
1329 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1330 SourceLocation TemplateKWLoc,
1331 OverloadedOperatorKind Operator,
1332 SourceLocation NameLoc, QualType ObjectType,
1333 bool AllowInjectedClassName);
1334
1335 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1336 SourceLocation TemplateKWLoc,
1337 IdentifierOrOverloadedOperator IO,
1338 SourceLocation NameLoc, QualType ObjectType,
1339 bool AllowInjectedClassName);
1340
1341 /// Build a new template name given a template template parameter pack
1342 /// and the
1343 ///
1344 /// By default, performs semantic analysis to determine whether the name can
1345 /// be resolved to a specific template, then builds the appropriate kind of
1346 /// template name. Subclasses may override this routine to provide different
1347 /// behavior.
1348 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1349 Decl *AssociatedDecl, unsigned Index,
1350 bool Final) {
1351 return getSema().Context.getSubstTemplateTemplateParmPack(
1352 ArgPack, AssociatedDecl, Index, Final);
1353 }
1354
1355 /// Build a new compound statement.
1356 ///
1357 /// By default, performs semantic analysis to build the new statement.
1358 /// Subclasses may override this routine to provide different behavior.
1359 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1360 MultiStmtArg Statements,
1361 SourceLocation RBraceLoc,
1362 bool IsStmtExpr) {
1363 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1364 IsStmtExpr);
1365 }
1366
1367 /// Build a new case statement.
1368 ///
1369 /// By default, performs semantic analysis to build the new statement.
1370 /// Subclasses may override this routine to provide different behavior.
1371 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1372 Expr *LHS,
1373 SourceLocation EllipsisLoc,
1374 Expr *RHS,
1375 SourceLocation ColonLoc) {
1376 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1377 ColonLoc);
1378 }
1379
1380 /// Attach the body to a new case statement.
1381 ///
1382 /// By default, performs semantic analysis to build the new statement.
1383 /// Subclasses may override this routine to provide different behavior.
1384 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1385 getSema().ActOnCaseStmtBody(S, Body);
1386 return S;
1387 }
1388
1389 /// Build a new default statement.
1390 ///
1391 /// By default, performs semantic analysis to build the new statement.
1392 /// Subclasses may override this routine to provide different behavior.
1393 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1394 SourceLocation ColonLoc,
1395 Stmt *SubStmt) {
1396 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1397 /*CurScope=*/nullptr);
1398 }
1399
1400 /// Build a new label statement.
1401 ///
1402 /// By default, performs semantic analysis to build the new statement.
1403 /// Subclasses may override this routine to provide different behavior.
1404 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1405 SourceLocation ColonLoc, Stmt *SubStmt) {
1406 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1407 }
1408
1409 /// Build a new attributed statement.
1410 ///
1411 /// By default, performs semantic analysis to build the new statement.
1412 /// Subclasses may override this routine to provide different behavior.
1413 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1414 ArrayRef<const Attr *> Attrs,
1415 Stmt *SubStmt) {
1416 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1417 return StmtError();
1418 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1419 }
1420
1421 /// Build a new "if" statement.
1422 ///
1423 /// By default, performs semantic analysis to build the new statement.
1424 /// Subclasses may override this routine to provide different behavior.
1425 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1426 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1427 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1428 SourceLocation ElseLoc, Stmt *Else) {
1429 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1430 Then, ElseLoc, Else);
1431 }
1432
1433 /// Start building a new switch statement.
1434 ///
1435 /// By default, performs semantic analysis to build the new statement.
1436 /// Subclasses may override this routine to provide different behavior.
1437 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1438 SourceLocation LParenLoc, Stmt *Init,
1439 Sema::ConditionResult Cond,
1440 SourceLocation RParenLoc) {
1441 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1442 RParenLoc);
1443 }
1444
1445 /// Attach the body to the switch statement.
1446 ///
1447 /// By default, performs semantic analysis to build the new statement.
1448 /// Subclasses may override this routine to provide different behavior.
1449 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1450 Stmt *Switch, Stmt *Body) {
1451 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1452 }
1453
1454 /// Build a new while statement.
1455 ///
1456 /// By default, performs semantic analysis to build the new statement.
1457 /// Subclasses may override this routine to provide different behavior.
1458 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1459 Sema::ConditionResult Cond,
1460 SourceLocation RParenLoc, Stmt *Body) {
1461 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1462 }
1463
1464 /// Build a new do-while statement.
1465 ///
1466 /// By default, performs semantic analysis to build the new statement.
1467 /// Subclasses may override this routine to provide different behavior.
1468 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1469 SourceLocation WhileLoc, SourceLocation LParenLoc,
1470 Expr *Cond, SourceLocation RParenLoc) {
1471 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1472 Cond, RParenLoc);
1473 }
1474
1475 /// Build a new for statement.
1476 ///
1477 /// By default, performs semantic analysis to build the new statement.
1478 /// Subclasses may override this routine to provide different behavior.
1479 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1480 Stmt *Init, Sema::ConditionResult Cond,
1481 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1482 Stmt *Body) {
1483 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1484 Inc, RParenLoc, Body);
1485 }
1486
1487 /// Build a new goto statement.
1488 ///
1489 /// By default, performs semantic analysis to build the new statement.
1490 /// Subclasses may override this routine to provide different behavior.
1491 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1492 LabelDecl *Label) {
1493 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1494 }
1495
1496 /// Build a new indirect goto statement.
1497 ///
1498 /// By default, performs semantic analysis to build the new statement.
1499 /// Subclasses may override this routine to provide different behavior.
1500 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1501 SourceLocation StarLoc,
1502 Expr *Target) {
1503 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1504 }
1505
1506 /// Build a new return statement.
1507 ///
1508 /// By default, performs semantic analysis to build the new statement.
1509 /// Subclasses may override this routine to provide different behavior.
1510 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1511 return getSema().BuildReturnStmt(ReturnLoc, Result);
1512 }
1513
1514 /// Build a new declaration statement.
1515 ///
1516 /// By default, performs semantic analysis to build the new statement.
1517 /// Subclasses may override this routine to provide different behavior.
1518 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1519 SourceLocation StartLoc, SourceLocation EndLoc) {
1520 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1521 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1522 }
1523
1524 /// Build a new inline asm statement.
1525 ///
1526 /// By default, performs semantic analysis to build the new statement.
1527 /// Subclasses may override this routine to provide different behavior.
1528 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1529 bool IsVolatile, unsigned NumOutputs,
1530 unsigned NumInputs, IdentifierInfo **Names,
1531 MultiExprArg Constraints, MultiExprArg Exprs,
1532 Expr *AsmString, MultiExprArg Clobbers,
1533 unsigned NumLabels,
1534 SourceLocation RParenLoc) {
1535 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1536 NumInputs, Names, Constraints, Exprs,
1537 AsmString, Clobbers, NumLabels, RParenLoc);
1538 }
1539
1540 /// Build a new MS style inline asm statement.
1541 ///
1542 /// By default, performs semantic analysis to build the new statement.
1543 /// Subclasses may override this routine to provide different behavior.
1544 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1545 ArrayRef<Token> AsmToks,
1546 StringRef AsmString,
1547 unsigned NumOutputs, unsigned NumInputs,
1548 ArrayRef<StringRef> Constraints,
1549 ArrayRef<StringRef> Clobbers,
1550 ArrayRef<Expr*> Exprs,
1551 SourceLocation EndLoc) {
1552 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1553 NumOutputs, NumInputs,
1554 Constraints, Clobbers, Exprs, EndLoc);
1555 }
1556
1557 /// Build a new co_return statement.
1558 ///
1559 /// By default, performs semantic analysis to build the new statement.
1560 /// Subclasses may override this routine to provide different behavior.
1561 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1562 bool IsImplicit) {
1563 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1564 }
1565
1566 /// Build a new co_await expression.
1567 ///
1568 /// By default, performs semantic analysis to build the new expression.
1569 /// Subclasses may override this routine to provide different behavior.
1570 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1571 UnresolvedLookupExpr *OpCoawaitLookup,
1572 bool IsImplicit) {
1573 // This function rebuilds a coawait-expr given its operator.
1574 // For an explicit coawait-expr, the rebuild involves the full set
1575 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1576 // including calling await_transform().
1577 // For an implicit coawait-expr, we need to rebuild the "operator
1578 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1579 // This mirrors how the implicit CoawaitExpr is originally created
1580 // in Sema::ActOnCoroutineBodyStart().
1581 if (IsImplicit) {
1582 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1583 CoawaitLoc, Operand, OpCoawaitLookup);
1584 if (Suspend.isInvalid())
1585 return ExprError();
1586 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1587 Suspend.get(), true);
1588 }
1589
1590 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1591 OpCoawaitLookup);
1592 }
1593
1594 /// Build a new co_await expression.
1595 ///
1596 /// By default, performs semantic analysis to build the new expression.
1597 /// Subclasses may override this routine to provide different behavior.
1598 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1599 Expr *Result,
1600 UnresolvedLookupExpr *Lookup) {
1601 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1602 }
1603
1604 /// Build a new co_yield expression.
1605 ///
1606 /// By default, performs semantic analysis to build the new expression.
1607 /// Subclasses may override this routine to provide different behavior.
1608 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1609 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1610 }
1611
1612 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1613 return getSema().BuildCoroutineBodyStmt(Args);
1614 }
1615
1616 /// Build a new Objective-C \@try statement.
1617 ///
1618 /// By default, performs semantic analysis to build the new statement.
1619 /// Subclasses may override this routine to provide different behavior.
1620 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1621 Stmt *TryBody,
1622 MultiStmtArg CatchStmts,
1623 Stmt *Finally) {
1624 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1625 Finally);
1626 }
1627
1628 /// Rebuild an Objective-C exception declaration.
1629 ///
1630 /// By default, performs semantic analysis to build the new declaration.
1631 /// Subclasses may override this routine to provide different behavior.
1632 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1633 TypeSourceInfo *TInfo, QualType T) {
1634 return getSema().ObjC().BuildObjCExceptionDecl(
1635 TInfo, T, ExceptionDecl->getInnerLocStart(),
1636 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1637 }
1638
1639 /// Build a new Objective-C \@catch statement.
1640 ///
1641 /// By default, performs semantic analysis to build the new statement.
1642 /// Subclasses may override this routine to provide different behavior.
1643 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1644 SourceLocation RParenLoc,
1645 VarDecl *Var,
1646 Stmt *Body) {
1647 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1648 }
1649
1650 /// Build a new Objective-C \@finally statement.
1651 ///
1652 /// By default, performs semantic analysis to build the new statement.
1653 /// Subclasses may override this routine to provide different behavior.
1654 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1655 Stmt *Body) {
1656 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1657 }
1658
1659 /// Build a new Objective-C \@throw statement.
1660 ///
1661 /// By default, performs semantic analysis to build the new statement.
1662 /// Subclasses may override this routine to provide different behavior.
1663 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1664 Expr *Operand) {
1665 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1666 }
1667
1668 /// Build a new OpenMP Canonical loop.
1669 ///
1670 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1671 /// OMPCanonicalLoop.
1672 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1673 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1674 }
1675
1676 /// Build a new OpenMP executable directive.
1677 ///
1678 /// By default, performs semantic analysis to build the new statement.
1679 /// Subclasses may override this routine to provide different behavior.
1680 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1681 DeclarationNameInfo DirName,
1682 OpenMPDirectiveKind CancelRegion,
1683 ArrayRef<OMPClause *> Clauses,
1684 Stmt *AStmt, SourceLocation StartLoc,
1685 SourceLocation EndLoc) {
1686
1687 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1688 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1689 }
1690
1691 /// Build a new OpenMP informational directive.
1692 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1693 DeclarationNameInfo DirName,
1694 ArrayRef<OMPClause *> Clauses,
1695 Stmt *AStmt,
1696 SourceLocation StartLoc,
1697 SourceLocation EndLoc) {
1698
1699 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1700 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1701 }
1702
1703 /// Build a new OpenMP 'if' clause.
1704 ///
1705 /// By default, performs semantic analysis to build the new OpenMP clause.
1706 /// Subclasses may override this routine to provide different behavior.
1707 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1708 Expr *Condition, SourceLocation StartLoc,
1709 SourceLocation LParenLoc,
1710 SourceLocation NameModifierLoc,
1711 SourceLocation ColonLoc,
1712 SourceLocation EndLoc) {
1713 return getSema().OpenMP().ActOnOpenMPIfClause(
1714 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1715 EndLoc);
1716 }
1717
1718 /// Build a new OpenMP 'final' clause.
1719 ///
1720 /// By default, performs semantic analysis to build the new OpenMP clause.
1721 /// Subclasses may override this routine to provide different behavior.
1722 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1723 SourceLocation LParenLoc,
1724 SourceLocation EndLoc) {
1725 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1726 LParenLoc, EndLoc);
1727 }
1728
1729 /// Build a new OpenMP 'num_threads' clause.
1730 ///
1731 /// By default, performs semantic analysis to build the new OpenMP clause.
1732 /// Subclasses may override this routine to provide different behavior.
1733 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1734 Expr *NumThreads,
1735 SourceLocation StartLoc,
1736 SourceLocation LParenLoc,
1737 SourceLocation ModifierLoc,
1738 SourceLocation EndLoc) {
1739 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1740 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1741 }
1742
1743 /// Build a new OpenMP 'safelen' clause.
1744 ///
1745 /// By default, performs semantic analysis to build the new OpenMP clause.
1746 /// Subclasses may override this routine to provide different behavior.
1747 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1748 SourceLocation LParenLoc,
1749 SourceLocation EndLoc) {
1750 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1751 EndLoc);
1752 }
1753
1754 /// Build a new OpenMP 'simdlen' clause.
1755 ///
1756 /// By default, performs semantic analysis to build the new OpenMP clause.
1757 /// Subclasses may override this routine to provide different behavior.
1758 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1759 SourceLocation LParenLoc,
1760 SourceLocation EndLoc) {
1761 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1762 EndLoc);
1763 }
1764
1765 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1766 SourceLocation StartLoc,
1767 SourceLocation LParenLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1770 EndLoc);
1771 }
1772
1773 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1774 SourceLocation StartLoc,
1775 SourceLocation LParenLoc,
1776 SourceLocation EndLoc,
1777 std::optional<unsigned> FillIdx,
1778 SourceLocation FillLoc) {
1779 unsigned FillCount = FillIdx ? 1 : 0;
1780 return getSema().OpenMP().ActOnOpenMPCountsClause(
1781 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1782 }
1783
1784 /// Build a new OpenMP 'permutation' clause.
1785 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1786 SourceLocation StartLoc,
1787 SourceLocation LParenLoc,
1788 SourceLocation EndLoc) {
1789 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1790 LParenLoc, EndLoc);
1791 }
1792
1793 /// Build a new OpenMP 'full' clause.
1794 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1795 SourceLocation EndLoc) {
1796 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1797 }
1798
1799 /// Build a new OpenMP 'partial' clause.
1800 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1801 SourceLocation LParenLoc,
1802 SourceLocation EndLoc) {
1803 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1804 LParenLoc, EndLoc);
1805 }
1806
1807 OMPClause *
1808 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1809 SourceLocation LParenLoc, SourceLocation FirstLoc,
1810 SourceLocation CountLoc, SourceLocation EndLoc) {
1811 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1812 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1813 }
1814
1815 /// Build a new OpenMP 'allocator' clause.
1816 ///
1817 /// By default, performs semantic analysis to build the new OpenMP clause.
1818 /// Subclasses may override this routine to provide different behavior.
1819 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1820 SourceLocation LParenLoc,
1821 SourceLocation EndLoc) {
1822 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1823 EndLoc);
1824 }
1825
1826 /// Build a new OpenMP 'collapse' clause.
1827 ///
1828 /// By default, performs semantic analysis to build the new OpenMP clause.
1829 /// Subclasses may override this routine to provide different behavior.
1830 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1831 SourceLocation LParenLoc,
1832 SourceLocation EndLoc) {
1833 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1834 LParenLoc, EndLoc);
1835 }
1836
1837 /// Build a new OpenMP 'default' clause.
1838 ///
1839 /// By default, performs semantic analysis to build the new OpenMP clause.
1840 /// Subclasses may override this routine to provide different behavior.
1841 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1842 OpenMPDefaultClauseVariableCategory VCKind,
1843 SourceLocation VCLoc,
1844 SourceLocation StartLoc,
1845 SourceLocation LParenLoc,
1846 SourceLocation EndLoc) {
1847 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1848 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1849 }
1850
1851 /// Build a new OpenMP 'proc_bind' clause.
1852 ///
1853 /// By default, performs semantic analysis to build the new OpenMP clause.
1854 /// Subclasses may override this routine to provide different behavior.
1855 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1856 SourceLocation KindKwLoc,
1857 SourceLocation StartLoc,
1858 SourceLocation LParenLoc,
1859 SourceLocation EndLoc) {
1860 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1861 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1862 }
1863 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1864 SourceLocation StartLoc,
1865 SourceLocation LParenLoc,
1866 SourceLocation EndLoc) {
1867 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1868 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1869 }
1870
1871 /// Build a new OpenMP 'schedule' clause.
1872 ///
1873 /// By default, performs semantic analysis to build the new OpenMP clause.
1874 /// Subclasses may override this routine to provide different behavior.
1875 OMPClause *RebuildOMPScheduleClause(
1876 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1877 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1878 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1879 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1880 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1881 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1882 CommaLoc, EndLoc);
1883 }
1884
1885 /// Build a new OpenMP 'ordered' clause.
1886 ///
1887 /// By default, performs semantic analysis to build the new OpenMP clause.
1888 /// Subclasses may override this routine to provide different behavior.
1889 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1890 SourceLocation EndLoc,
1891 SourceLocation LParenLoc, Expr *Num) {
1892 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1893 LParenLoc, Num);
1894 }
1895
1896 /// Build a new OpenMP 'nowait' clause.
1897 ///
1898 /// By default, performs semantic analysis to build the new OpenMP clause.
1899 /// Subclasses may override this routine to provide different behavior.
1900 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1901 SourceLocation LParenLoc,
1902 SourceLocation EndLoc) {
1903 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1904 LParenLoc, Condition);
1905 }
1906
1907 /// Build a new OpenMP 'private' 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 *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1912 SourceLocation StartLoc,
1913 SourceLocation LParenLoc,
1914 SourceLocation EndLoc) {
1915 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1916 LParenLoc, EndLoc);
1917 }
1918
1919 /// Build a new OpenMP 'firstprivate' 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 *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1924 SourceLocation StartLoc,
1925 SourceLocation LParenLoc,
1926 SourceLocation EndLoc) {
1927 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1928 LParenLoc, EndLoc);
1929 }
1930
1931 /// Build a new OpenMP 'lastprivate' clause.
1932 ///
1933 /// By default, performs semantic analysis to build the new OpenMP clause.
1934 /// Subclasses may override this routine to provide different behavior.
1935 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1936 OpenMPLastprivateModifier LPKind,
1937 SourceLocation LPKindLoc,
1938 SourceLocation ColonLoc,
1939 SourceLocation StartLoc,
1940 SourceLocation LParenLoc,
1941 SourceLocation EndLoc) {
1942 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1943 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1944 }
1945
1946 /// Build a new OpenMP 'shared' clause.
1947 ///
1948 /// By default, performs semantic analysis to build the new OpenMP clause.
1949 /// Subclasses may override this routine to provide different behavior.
1950 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1951 SourceLocation StartLoc,
1952 SourceLocation LParenLoc,
1953 SourceLocation EndLoc) {
1954 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1955 LParenLoc, EndLoc);
1956 }
1957
1958 /// Build a new OpenMP 'reduction' clause.
1959 ///
1960 /// By default, performs semantic analysis to build the new statement.
1961 /// Subclasses may override this routine to provide different behavior.
1962 OMPClause *RebuildOMPReductionClause(
1963 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1964 OpenMPOriginalSharingModifier OriginalSharingModifier,
1965 SourceLocation StartLoc, SourceLocation LParenLoc,
1966 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1967 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1968 const DeclarationNameInfo &ReductionId,
1969 ArrayRef<Expr *> UnresolvedReductions) {
1970 return getSema().OpenMP().ActOnOpenMPReductionClause(
1971 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1972 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1973 UnresolvedReductions);
1974 }
1975
1976 /// Build a new OpenMP 'task_reduction' clause.
1977 ///
1978 /// By default, performs semantic analysis to build the new statement.
1979 /// Subclasses may override this routine to provide different behavior.
1980 OMPClause *RebuildOMPTaskReductionClause(
1981 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1982 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1983 CXXScopeSpec &ReductionIdScopeSpec,
1984 const DeclarationNameInfo &ReductionId,
1985 ArrayRef<Expr *> UnresolvedReductions) {
1986 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1987 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1988 ReductionId, UnresolvedReductions);
1989 }
1990
1991 /// Build a new OpenMP 'in_reduction' clause.
1992 ///
1993 /// By default, performs semantic analysis to build the new statement.
1994 /// Subclasses may override this routine to provide different behavior.
1995 OMPClause *
1996 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1997 SourceLocation LParenLoc, SourceLocation ColonLoc,
1998 SourceLocation EndLoc,
1999 CXXScopeSpec &ReductionIdScopeSpec,
2000 const DeclarationNameInfo &ReductionId,
2001 ArrayRef<Expr *> UnresolvedReductions) {
2002 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2003 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2004 ReductionId, UnresolvedReductions);
2005 }
2006
2007 /// Build a new OpenMP 'linear' clause.
2008 ///
2009 /// By default, performs semantic analysis to build the new OpenMP clause.
2010 /// Subclasses may override this routine to provide different behavior.
2011 OMPClause *RebuildOMPLinearClause(
2012 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2013 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2014 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2015 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2016 return getSema().OpenMP().ActOnOpenMPLinearClause(
2017 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2018 StepModifierLoc, EndLoc);
2019 }
2020
2021 /// Build a new OpenMP 'aligned' clause.
2022 ///
2023 /// By default, performs semantic analysis to build the new OpenMP clause.
2024 /// Subclasses may override this routine to provide different behavior.
2025 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2026 SourceLocation StartLoc,
2027 SourceLocation LParenLoc,
2028 SourceLocation ColonLoc,
2029 SourceLocation EndLoc) {
2030 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2031 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2032 }
2033
2034 /// Build a new OpenMP 'copyin' 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 *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2039 SourceLocation StartLoc,
2040 SourceLocation LParenLoc,
2041 SourceLocation EndLoc) {
2042 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2043 LParenLoc, EndLoc);
2044 }
2045
2046 /// Build a new OpenMP 'copyprivate' 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 *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2051 SourceLocation StartLoc,
2052 SourceLocation LParenLoc,
2053 SourceLocation EndLoc) {
2054 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2055 LParenLoc, EndLoc);
2056 }
2057
2058 /// Build a new OpenMP 'flush' 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 *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2063 SourceLocation StartLoc,
2064 SourceLocation LParenLoc,
2065 SourceLocation EndLoc) {
2066 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2067 LParenLoc, EndLoc);
2068 }
2069
2070 /// Build a new OpenMP 'depobj' pseudo clause.
2071 ///
2072 /// By default, performs semantic analysis to build the new OpenMP clause.
2073 /// Subclasses may override this routine to provide different behavior.
2074 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2075 SourceLocation LParenLoc,
2076 SourceLocation EndLoc) {
2077 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2078 LParenLoc, EndLoc);
2079 }
2080
2081 /// Build a new OpenMP 'depend' pseudo clause.
2082 ///
2083 /// By default, performs semantic analysis to build the new OpenMP clause.
2084 /// Subclasses may override this routine to provide different behavior.
2085 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2086 Expr *DepModifier, ArrayRef<Expr *> VarList,
2087 SourceLocation StartLoc,
2088 SourceLocation LParenLoc,
2089 SourceLocation EndLoc) {
2090 return getSema().OpenMP().ActOnOpenMPDependClause(
2091 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2092 }
2093
2094 /// Build a new OpenMP 'device' clause.
2095 ///
2096 /// By default, performs semantic analysis to build the new statement.
2097 /// Subclasses may override this routine to provide different behavior.
2098 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2099 Expr *Device, SourceLocation StartLoc,
2100 SourceLocation LParenLoc,
2101 SourceLocation ModifierLoc,
2102 SourceLocation EndLoc) {
2103 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2104 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2105 }
2106
2107 /// Build a new OpenMP 'map' clause.
2108 ///
2109 /// By default, performs semantic analysis to build the new OpenMP clause.
2110 /// Subclasses may override this routine to provide different behavior.
2111 OMPClause *RebuildOMPMapClause(
2112 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2113 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2114 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2115 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2116 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2117 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2118 return getSema().OpenMP().ActOnOpenMPMapClause(
2119 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2120 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2121 ColonLoc, VarList, Locs,
2122 /*NoDiagnose=*/false, UnresolvedMappers);
2123 }
2124
2125 /// Build a new OpenMP 'allocate' clause.
2126 ///
2127 /// By default, performs semantic analysis to build the new OpenMP clause.
2128 /// Subclasses may override this routine to provide different behavior.
2129 OMPClause *
2130 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2131 OpenMPAllocateClauseModifier FirstModifier,
2132 SourceLocation FirstModifierLoc,
2133 OpenMPAllocateClauseModifier SecondModifier,
2134 SourceLocation SecondModifierLoc,
2135 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2136 SourceLocation LParenLoc, SourceLocation ColonLoc,
2137 SourceLocation EndLoc) {
2138 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2139 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2140 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2141 }
2142
2143 /// Build a new OpenMP 'num_teams' 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 *RebuildOMPNumTeamsClause(
2148 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2149 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2150 SourceLocation LParenLoc, SourceLocation EndLoc) {
2151 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2152 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2153 EndLoc);
2154 }
2155
2156 /// Build a new OpenMP 'thread_limit' clause.
2157 ///
2158 /// By default, performs semantic analysis to build the new statement.
2159 /// Subclasses may override this routine to provide different behavior.
2160 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2161 SourceLocation StartLoc,
2162 SourceLocation LParenLoc,
2163 SourceLocation EndLoc) {
2164 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2165 LParenLoc, EndLoc);
2166 }
2167
2168 /// Build a new OpenMP 'priority' clause.
2169 ///
2170 /// By default, performs semantic analysis to build the new statement.
2171 /// Subclasses may override this routine to provide different behavior.
2172 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2173 SourceLocation LParenLoc,
2174 SourceLocation EndLoc) {
2175 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2176 LParenLoc, EndLoc);
2177 }
2178
2179 /// Build a new OpenMP 'grainsize' 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 *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2184 Expr *Device, SourceLocation StartLoc,
2185 SourceLocation LParenLoc,
2186 SourceLocation ModifierLoc,
2187 SourceLocation EndLoc) {
2188 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2189 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2190 }
2191
2192 /// Build a new OpenMP 'num_tasks' 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 *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2197 Expr *NumTasks, SourceLocation StartLoc,
2198 SourceLocation LParenLoc,
2199 SourceLocation ModifierLoc,
2200 SourceLocation EndLoc) {
2201 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2202 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2203 }
2204
2205 /// Build a new OpenMP 'hint' clause.
2206 ///
2207 /// By default, performs semantic analysis to build the new statement.
2208 /// Subclasses may override this routine to provide different behavior.
2209 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2210 SourceLocation LParenLoc,
2211 SourceLocation EndLoc) {
2212 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2213 EndLoc);
2214 }
2215
2216 /// Build a new OpenMP 'detach' clause.
2217 ///
2218 /// By default, performs semantic analysis to build the new statement.
2219 /// Subclasses may override this routine to provide different behavior.
2220 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2221 SourceLocation LParenLoc,
2222 SourceLocation EndLoc) {
2223 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2224 EndLoc);
2225 }
2226
2227 /// Build a new OpenMP 'dist_schedule' clause.
2228 ///
2229 /// By default, performs semantic analysis to build the new OpenMP clause.
2230 /// Subclasses may override this routine to provide different behavior.
2231 OMPClause *
2232 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2233 Expr *ChunkSize, SourceLocation StartLoc,
2234 SourceLocation LParenLoc, SourceLocation KindLoc,
2235 SourceLocation CommaLoc, SourceLocation EndLoc) {
2236 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2237 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2238 }
2239
2240 /// Build a new OpenMP 'to' clause.
2241 ///
2242 /// By default, performs semantic analysis to build the new statement.
2243 /// Subclasses may override this routine to provide different behavior.
2244 OMPClause *
2245 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2246 ArrayRef<SourceLocation> MotionModifiersLoc,
2247 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2248 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2249 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2250 ArrayRef<Expr *> UnresolvedMappers) {
2251 return getSema().OpenMP().ActOnOpenMPToClause(
2252 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2253 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2254 UnresolvedMappers);
2255 }
2256
2257 /// Build a new OpenMP 'from' clause.
2258 ///
2259 /// By default, performs semantic analysis to build the new statement.
2260 /// Subclasses may override this routine to provide different behavior.
2261 OMPClause *
2262 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2263 ArrayRef<SourceLocation> MotionModifiersLoc,
2264 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2265 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2266 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2267 ArrayRef<Expr *> UnresolvedMappers) {
2268 return getSema().OpenMP().ActOnOpenMPFromClause(
2269 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2270 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2271 UnresolvedMappers);
2272 }
2273
2274 /// Build a new OpenMP 'use_device_ptr' clause.
2275 ///
2276 /// By default, performs semantic analysis to build the new OpenMP clause.
2277 /// Subclasses may override this routine to provide different behavior.
2278 OMPClause *RebuildOMPUseDevicePtrClause(
2279 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2280 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2281 SourceLocation FallbackModifierLoc) {
2282 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2283 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2284 }
2285
2286 /// Build a new OpenMP 'use_device_addr' clause.
2287 ///
2288 /// By default, performs semantic analysis to build the new OpenMP clause.
2289 /// Subclasses may override this routine to provide different behavior.
2290 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2291 const OMPVarListLocTy &Locs) {
2292 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2293 }
2294
2295 /// Build a new OpenMP 'is_device_ptr' clause.
2296 ///
2297 /// By default, performs semantic analysis to build the new OpenMP clause.
2298 /// Subclasses may override this routine to provide different behavior.
2299 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2300 const OMPVarListLocTy &Locs) {
2301 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2302 }
2303
2304 /// Build a new OpenMP 'has_device_addr' clause.
2305 ///
2306 /// By default, performs semantic analysis to build the new OpenMP clause.
2307 /// Subclasses may override this routine to provide different behavior.
2308 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2309 const OMPVarListLocTy &Locs) {
2310 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2311 }
2312
2313 /// Build a new OpenMP 'defaultmap' clause.
2314 ///
2315 /// By default, performs semantic analysis to build the new OpenMP clause.
2316 /// Subclasses may override this routine to provide different behavior.
2317 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2318 OpenMPDefaultmapClauseKind Kind,
2319 SourceLocation StartLoc,
2320 SourceLocation LParenLoc,
2321 SourceLocation MLoc,
2322 SourceLocation KindLoc,
2323 SourceLocation EndLoc) {
2324 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2325 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2326 }
2327
2328 /// Build a new OpenMP 'nontemporal' clause.
2329 ///
2330 /// By default, performs semantic analysis to build the new OpenMP clause.
2331 /// Subclasses may override this routine to provide different behavior.
2332 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2333 SourceLocation StartLoc,
2334 SourceLocation LParenLoc,
2335 SourceLocation EndLoc) {
2336 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2337 LParenLoc, EndLoc);
2338 }
2339
2340 /// Build a new OpenMP 'inclusive' clause.
2341 ///
2342 /// By default, performs semantic analysis to build the new OpenMP clause.
2343 /// Subclasses may override this routine to provide different behavior.
2344 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2345 SourceLocation StartLoc,
2346 SourceLocation LParenLoc,
2347 SourceLocation EndLoc) {
2348 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2349 LParenLoc, EndLoc);
2350 }
2351
2352 /// Build a new OpenMP 'exclusive' clause.
2353 ///
2354 /// By default, performs semantic analysis to build the new OpenMP clause.
2355 /// Subclasses may override this routine to provide different behavior.
2356 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2357 SourceLocation StartLoc,
2358 SourceLocation LParenLoc,
2359 SourceLocation EndLoc) {
2360 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2361 LParenLoc, EndLoc);
2362 }
2363
2364 /// Build a new OpenMP 'uses_allocators' clause.
2365 ///
2366 /// By default, performs semantic analysis to build the new OpenMP clause.
2367 /// Subclasses may override this routine to provide different behavior.
2368 OMPClause *RebuildOMPUsesAllocatorsClause(
2369 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2370 SourceLocation LParenLoc, SourceLocation EndLoc) {
2371 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2372 StartLoc, LParenLoc, EndLoc, Data);
2373 }
2374
2375 /// Build a new OpenMP 'affinity' 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 *RebuildOMPAffinityClause(SourceLocation StartLoc,
2380 SourceLocation LParenLoc,
2381 SourceLocation ColonLoc,
2382 SourceLocation EndLoc, Expr *Modifier,
2383 ArrayRef<Expr *> Locators) {
2384 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2385 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2386 }
2387
2388 /// Build a new OpenMP 'order' clause.
2389 ///
2390 /// By default, performs semantic analysis to build the new OpenMP clause.
2391 /// Subclasses may override this routine to provide different behavior.
2392 OMPClause *RebuildOMPOrderClause(
2393 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2394 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2395 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2396 return getSema().OpenMP().ActOnOpenMPOrderClause(
2397 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2398 }
2399
2400 /// Build a new OpenMP 'init' 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 *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2405 SourceLocation StartLoc,
2406 SourceLocation LParenLoc,
2407 SourceLocation VarLoc,
2408 SourceLocation EndLoc) {
2409 return getSema().OpenMP().ActOnOpenMPInitClause(
2410 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2411 }
2412
2413 /// Build a new OpenMP 'use' clause.
2414 ///
2415 /// By default, performs semantic analysis to build the new OpenMP clause.
2416 /// Subclasses may override this routine to provide different behavior.
2417 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2418 SourceLocation LParenLoc,
2419 SourceLocation VarLoc, SourceLocation EndLoc) {
2420 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2421 LParenLoc, VarLoc, EndLoc);
2422 }
2423
2424 /// Build a new OpenMP 'destroy' clause.
2425 ///
2426 /// By default, performs semantic analysis to build the new OpenMP clause.
2427 /// Subclasses may override this routine to provide different behavior.
2428 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2429 SourceLocation LParenLoc,
2430 SourceLocation VarLoc,
2431 SourceLocation EndLoc) {
2432 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2433 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2434 }
2435
2436 /// Build a new OpenMP 'novariants' clause.
2437 ///
2438 /// By default, performs semantic analysis to build the new OpenMP clause.
2439 /// Subclasses may override this routine to provide different behavior.
2440 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2441 SourceLocation StartLoc,
2442 SourceLocation LParenLoc,
2443 SourceLocation EndLoc) {
2444 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2445 LParenLoc, EndLoc);
2446 }
2447
2448 /// Build a new OpenMP 'nocontext' clause.
2449 ///
2450 /// By default, performs semantic analysis to build the new OpenMP clause.
2451 /// Subclasses may override this routine to provide different behavior.
2452 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2453 SourceLocation LParenLoc,
2454 SourceLocation EndLoc) {
2455 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2456 LParenLoc, EndLoc);
2457 }
2458
2459 /// Build a new OpenMP 'filter' clause.
2460 ///
2461 /// By default, performs semantic analysis to build the new OpenMP clause.
2462 /// Subclasses may override this routine to provide different behavior.
2463 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2464 SourceLocation LParenLoc,
2465 SourceLocation EndLoc) {
2466 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2467 LParenLoc, EndLoc);
2468 }
2469
2470 /// Build a new OpenMP 'bind' 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 *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2475 SourceLocation KindLoc,
2476 SourceLocation StartLoc,
2477 SourceLocation LParenLoc,
2478 SourceLocation EndLoc) {
2479 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2480 LParenLoc, EndLoc);
2481 }
2482
2483 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2484 ///
2485 /// By default, performs semantic analysis to build the new OpenMP clause.
2486 /// Subclasses may override this routine to provide different behavior.
2487 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2488 SourceLocation LParenLoc,
2489 SourceLocation EndLoc) {
2490 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2491 LParenLoc, EndLoc);
2492 }
2493
2494 /// Build a new OpenMP 'dyn_groupprivate' 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 *RebuildOMPDynGroupprivateClause(
2499 OpenMPDynGroupprivateClauseModifier M1,
2500 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2501 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2502 SourceLocation M2Loc, SourceLocation EndLoc) {
2503 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2504 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2505 }
2506
2507 /// Build a new OpenMP 'ompx_attribute' clause.
2508 ///
2509 /// By default, performs semantic analysis to build the new OpenMP clause.
2510 /// Subclasses may override this routine to provide different behavior.
2511 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2512 SourceLocation StartLoc,
2513 SourceLocation LParenLoc,
2514 SourceLocation EndLoc) {
2515 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2516 LParenLoc, EndLoc);
2517 }
2518
2519 /// Build a new OpenMP 'ompx_bare' clause.
2520 ///
2521 /// By default, performs semantic analysis to build the new OpenMP clause.
2522 /// Subclasses may override this routine to provide different behavior.
2523 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2524 SourceLocation EndLoc) {
2525 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2526 }
2527
2528 /// Build a new OpenMP 'align' clause.
2529 ///
2530 /// By default, performs semantic analysis to build the new OpenMP clause.
2531 /// Subclasses may override this routine to provide different behavior.
2532 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2533 SourceLocation LParenLoc,
2534 SourceLocation EndLoc) {
2535 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2536 EndLoc);
2537 }
2538
2539 /// Build a new OpenMP 'at' clause.
2540 ///
2541 /// By default, performs semantic analysis to build the new OpenMP clause.
2542 /// Subclasses may override this routine to provide different behavior.
2543 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2544 SourceLocation StartLoc,
2545 SourceLocation LParenLoc,
2546 SourceLocation EndLoc) {
2547 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2548 LParenLoc, EndLoc);
2549 }
2550
2551 /// Build a new OpenMP 'severity' 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 *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2556 SourceLocation KwLoc,
2557 SourceLocation StartLoc,
2558 SourceLocation LParenLoc,
2559 SourceLocation EndLoc) {
2560 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2561 LParenLoc, EndLoc);
2562 }
2563
2564 /// Build a new OpenMP 'message' clause.
2565 ///
2566 /// By default, performs semantic analysis to build the new OpenMP clause.
2567 /// Subclasses may override this routine to provide different behavior.
2568 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2569 SourceLocation LParenLoc,
2570 SourceLocation EndLoc) {
2571 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2572 EndLoc);
2573 }
2574
2575 /// Build a new OpenMP 'doacross' clause.
2576 ///
2577 /// By default, performs semantic analysis to build the new OpenMP clause.
2578 /// Subclasses may override this routine to provide different behavior.
2579 OMPClause *
2580 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2581 SourceLocation DepLoc, SourceLocation ColonLoc,
2582 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2583 SourceLocation LParenLoc, SourceLocation EndLoc) {
2584 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2585 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2586 }
2587
2588 /// Build a new OpenMP 'holds' clause.
2589 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2590 SourceLocation LParenLoc,
2591 SourceLocation EndLoc) {
2592 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2593 EndLoc);
2594 }
2595
2596 /// Rebuild the operand to an Objective-C \@synchronized statement.
2597 ///
2598 /// By default, performs semantic analysis to build the new statement.
2599 /// Subclasses may override this routine to provide different behavior.
2600 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2601 Expr *object) {
2602 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2603 }
2604
2605 /// Build a new Objective-C \@synchronized statement.
2606 ///
2607 /// By default, performs semantic analysis to build the new statement.
2608 /// Subclasses may override this routine to provide different behavior.
2609 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2610 Expr *Object, Stmt *Body) {
2611 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2612 }
2613
2614 /// Build a new Objective-C \@autoreleasepool statement.
2615 ///
2616 /// By default, performs semantic analysis to build the new statement.
2617 /// Subclasses may override this routine to provide different behavior.
2618 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2619 Stmt *Body) {
2620 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2621 }
2622
2623 /// Build a new Objective-C fast enumeration statement.
2624 ///
2625 /// By default, performs semantic analysis to build the new statement.
2626 /// Subclasses may override this routine to provide different behavior.
2627 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2628 Stmt *Element,
2629 Expr *Collection,
2630 SourceLocation RParenLoc,
2631 Stmt *Body) {
2632 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2633 ForLoc, Element, Collection, RParenLoc);
2634 if (ForEachStmt.isInvalid())
2635 return StmtError();
2636
2637 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2638 Body);
2639 }
2640
2641 /// Build a new C++ exception declaration.
2642 ///
2643 /// By default, performs semantic analysis to build the new decaration.
2644 /// Subclasses may override this routine to provide different behavior.
2645 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2646 TypeSourceInfo *Declarator,
2647 SourceLocation StartLoc,
2648 SourceLocation IdLoc,
2649 IdentifierInfo *Id) {
2650 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2651 StartLoc, IdLoc, Id);
2652 if (Var)
2653 getSema().CurContext->addDecl(Var);
2654 return Var;
2655 }
2656
2657 /// Build a new C++ catch statement.
2658 ///
2659 /// By default, performs semantic analysis to build the new statement.
2660 /// Subclasses may override this routine to provide different behavior.
2661 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2662 VarDecl *ExceptionDecl,
2663 Stmt *Handler) {
2664 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2665 Handler));
2666 }
2667
2668 /// Build a new C++ try statement.
2669 ///
2670 /// By default, performs semantic analysis to build the new statement.
2671 /// Subclasses may override this routine to provide different behavior.
2672 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2673 ArrayRef<Stmt *> Handlers) {
2674 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2675 }
2676
2677 /// Build a new C++0x range-based for statement.
2678 ///
2679 /// By default, performs semantic analysis to build the new statement.
2680 /// Subclasses may override this routine to provide different behavior.
2681 StmtResult RebuildCXXForRangeStmt(
2682 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2683 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2684 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2685 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2686 // If we've just learned that the range is actually an Objective-C
2687 // collection, treat this as an Objective-C fast enumeration loop.
2688 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2689 if (RangeStmt->isSingleDecl()) {
2690 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2691 if (RangeVar->isInvalidDecl())
2692 return StmtError();
2693
2694 Expr *RangeExpr = RangeVar->getInit();
2695 if (!RangeExpr->isTypeDependent() &&
2696 RangeExpr->getType()->isObjCObjectPointerType()) {
2697 // FIXME: Support init-statements in Objective-C++20 ranged for
2698 // statement.
2699 if (Init) {
2700 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2701 DiagID: diag::err_objc_for_range_init_stmt)
2702 << Init->getSourceRange();
2703 }
2704 return getSema().ObjC().ActOnObjCForCollectionStmt(
2705 ForLoc, LoopVar, RangeExpr, RParenLoc);
2706 }
2707 }
2708 }
2709 }
2710
2711 return getSema().BuildCXXForRangeStmt(
2712 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2713 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2714 }
2715
2716 /// Build a new C++0x range-based for statement.
2717 ///
2718 /// By default, performs semantic analysis to build the new statement.
2719 /// Subclasses may override this routine to provide different behavior.
2720 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2721 bool IsIfExists,
2722 NestedNameSpecifierLoc QualifierLoc,
2723 DeclarationNameInfo NameInfo,
2724 Stmt *Nested) {
2725 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2726 QualifierLoc, NameInfo, Nested);
2727 }
2728
2729 /// Attach body to a C++0x range-based for statement.
2730 ///
2731 /// By default, performs semantic analysis to finish the new statement.
2732 /// Subclasses may override this routine to provide different behavior.
2733 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2734 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2735 }
2736
2737 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2738 Stmt *TryBlock, Stmt *Handler) {
2739 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2740 }
2741
2742 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2743 Stmt *Block) {
2744 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2745 }
2746
2747 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2748 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2749 }
2750
2751 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2752 SourceLocation LParen,
2753 SourceLocation RParen,
2754 TypeSourceInfo *TSI) {
2755 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2756 TSI);
2757 }
2758
2759 /// Build a new predefined expression.
2760 ///
2761 /// By default, performs semantic analysis to build the new expression.
2762 /// Subclasses may override this routine to provide different behavior.
2763 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2764 return getSema().BuildPredefinedExpr(Loc, IK);
2765 }
2766
2767 /// Build a new expression that references a declaration.
2768 ///
2769 /// By default, performs semantic analysis to build the new expression.
2770 /// Subclasses may override this routine to provide different behavior.
2771 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2772 LookupResult &R,
2773 bool RequiresADL) {
2774 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2775 }
2776
2777
2778 /// Build a new expression that references a declaration.
2779 ///
2780 /// By default, performs semantic analysis to build the new expression.
2781 /// Subclasses may override this routine to provide different behavior.
2782 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2783 ValueDecl *VD,
2784 const DeclarationNameInfo &NameInfo,
2785 NamedDecl *Found,
2786 TemplateArgumentListInfo *TemplateArgs) {
2787 CXXScopeSpec SS;
2788 SS.Adopt(Other: QualifierLoc);
2789 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2790 TemplateArgs);
2791 }
2792
2793 /// Build a new expression in parentheses.
2794 ///
2795 /// By default, performs semantic analysis to build the new expression.
2796 /// Subclasses may override this routine to provide different behavior.
2797 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2798 SourceLocation RParen) {
2799 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2800 }
2801
2802 /// Build a new pseudo-destructor 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 RebuildCXXPseudoDestructorExpr(Expr *Base,
2807 SourceLocation OperatorLoc,
2808 bool isArrow,
2809 CXXScopeSpec &SS,
2810 TypeSourceInfo *ScopeType,
2811 SourceLocation CCLoc,
2812 SourceLocation TildeLoc,
2813 PseudoDestructorTypeStorage Destroyed);
2814
2815 /// Build a new unary operator expression.
2816 ///
2817 /// By default, performs semantic analysis to build the new expression.
2818 /// Subclasses may override this routine to provide different behavior.
2819 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2820 UnaryOperatorKind Opc,
2821 Expr *SubExpr) {
2822 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2823 }
2824
2825 /// Build a new builtin offsetof expression.
2826 ///
2827 /// By default, performs semantic analysis to build the new expression.
2828 /// Subclasses may override this routine to provide different behavior.
2829 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2830 TypeSourceInfo *Type, const Designation &Desig,
2831 SourceLocation RParenLoc) {
2832 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2833 }
2834
2835 /// Build a new sizeof, alignof or vec_step expression with a
2836 /// type argument.
2837 ///
2838 /// By default, performs semantic analysis to build the new expression.
2839 /// Subclasses may override this routine to provide different behavior.
2840 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2841 SourceLocation OpLoc,
2842 UnaryExprOrTypeTrait ExprKind,
2843 SourceRange R) {
2844 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2845 }
2846
2847 /// Build a new sizeof, alignof or vec step expression with an
2848 /// expression argument.
2849 ///
2850 /// By default, performs semantic analysis to build the new expression.
2851 /// Subclasses may override this routine to provide different behavior.
2852 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2853 UnaryExprOrTypeTrait ExprKind,
2854 SourceRange R) {
2855 ExprResult Result
2856 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2857 if (Result.isInvalid())
2858 return ExprError();
2859
2860 return Result;
2861 }
2862
2863 /// Build a new array subscript expression.
2864 ///
2865 /// By default, performs semantic analysis to build the new expression.
2866 /// Subclasses may override this routine to provide different behavior.
2867 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2868 SourceLocation LBracketLoc,
2869 Expr *RHS,
2870 SourceLocation RBracketLoc) {
2871 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2872 LBracketLoc, RHS,
2873 RBracketLoc);
2874 }
2875
2876 /// Build a new matrix single subscript expression.
2877 ///
2878 /// By default, performs semantic analysis to build the new expression.
2879 /// Subclasses may override this routine to provide different behavior.
2880 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2881 SourceLocation RBracketLoc) {
2882 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2883 RBracketLoc);
2884 }
2885
2886 /// Build a new matrix subscript expression.
2887 ///
2888 /// By default, performs semantic analysis to build the new expression.
2889 /// Subclasses may override this routine to provide different behavior.
2890 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2891 Expr *ColumnIdx,
2892 SourceLocation RBracketLoc) {
2893 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2894 RBracketLoc);
2895 }
2896
2897 /// Build a new array section expression.
2898 ///
2899 /// By default, performs semantic analysis to build the new expression.
2900 /// Subclasses may override this routine to provide different behavior.
2901 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2902 SourceLocation LBracketLoc,
2903 Expr *LowerBound,
2904 SourceLocation ColonLocFirst,
2905 SourceLocation ColonLocSecond,
2906 Expr *Length, Expr *Stride,
2907 SourceLocation RBracketLoc) {
2908 if (IsOMPArraySection)
2909 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2910 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2911 Stride, RBracketLoc);
2912
2913 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2914 "Stride/second colon not allowed for OpenACC");
2915
2916 return getSema().OpenACC().ActOnArraySectionExpr(
2917 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2918 }
2919
2920 /// Build a new array shaping expression.
2921 ///
2922 /// By default, performs semantic analysis to build the new expression.
2923 /// Subclasses may override this routine to provide different behavior.
2924 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2925 SourceLocation RParenLoc,
2926 ArrayRef<Expr *> Dims,
2927 ArrayRef<SourceRange> BracketsRanges) {
2928 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2929 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2930 }
2931
2932 /// Build a new iterator expression.
2933 ///
2934 /// By default, performs semantic analysis to build the new expression.
2935 /// Subclasses may override this routine to provide different behavior.
2936 ExprResult
2937 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2938 SourceLocation RLoc,
2939 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2940 return getSema().OpenMP().ActOnOMPIteratorExpr(
2941 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2942 }
2943
2944 /// Build a new call expression.
2945 ///
2946 /// By default, performs semantic analysis to build the new expression.
2947 /// Subclasses may override this routine to provide different behavior.
2948 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2949 MultiExprArg Args,
2950 SourceLocation RParenLoc,
2951 Expr *ExecConfig = nullptr) {
2952 return getSema().ActOnCallExpr(
2953 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2954 }
2955
2956 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2957 MultiExprArg Args,
2958 SourceLocation RParenLoc) {
2959 return getSema().ActOnArraySubscriptExpr(
2960 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2961 }
2962
2963 /// Build a new member access expression.
2964 ///
2965 /// By default, performs semantic analysis to build the new expression.
2966 /// Subclasses may override this routine to provide different behavior.
2967 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2968 bool isArrow,
2969 NestedNameSpecifierLoc QualifierLoc,
2970 SourceLocation TemplateKWLoc,
2971 const DeclarationNameInfo &MemberNameInfo,
2972 ValueDecl *Member,
2973 NamedDecl *FoundDecl,
2974 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2975 NamedDecl *FirstQualifierInScope) {
2976 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2977 isArrow);
2978 if (!Member->getDeclName()) {
2979 // We have a reference to an unnamed field. This is always the
2980 // base of an anonymous struct/union member access, i.e. the
2981 // field is always of record type.
2982 assert(Member->getType()->isRecordType() &&
2983 "unnamed member not of record type?");
2984
2985 BaseResult =
2986 getSema().PerformObjectMemberConversion(BaseResult.get(),
2987 QualifierLoc.getNestedNameSpecifier(),
2988 FoundDecl, Member);
2989 if (BaseResult.isInvalid())
2990 return ExprError();
2991 Base = BaseResult.get();
2992
2993 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2994 // from the AST, so we need to re-insert them if needed (since
2995 // `BuildFieldRefereneExpr()` doesn't do this).
2996 if (!isArrow && Base->isPRValue()) {
2997 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2998 if (BaseResult.isInvalid())
2999 return ExprError();
3000 Base = BaseResult.get();
3001 }
3002
3003 CXXScopeSpec EmptySS;
3004 return getSema().BuildFieldReferenceExpr(
3005 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3006 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3007 MemberNameInfo);
3008 }
3009
3010 CXXScopeSpec SS;
3011 SS.Adopt(Other: QualifierLoc);
3012
3013 Base = BaseResult.get();
3014 if (Base->containsErrors())
3015 return ExprError();
3016
3017 QualType BaseType = Base->getType();
3018
3019 if (isArrow && !BaseType->isPointerType())
3020 return ExprError();
3021
3022 // FIXME: this involves duplicating earlier analysis in a lot of
3023 // cases; we should avoid this when possible.
3024 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3025 R.addDecl(D: FoundDecl);
3026 R.resolveKind();
3027
3028 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3029 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3030 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3031 ->getType()
3032 ->getPointeeType()
3033 ->getAsCXXRecordDecl()) {
3034 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3035 // In unevaluated contexts, an expression supposed to be a member access
3036 // might reference a member in an unrelated class.
3037 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3038 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3039 VK_LValue, Member->getLocation());
3040 }
3041 }
3042
3043 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3044 SS, TemplateKWLoc,
3045 FirstQualifierInScope,
3046 R, ExplicitTemplateArgs,
3047 /*S*/nullptr);
3048 }
3049
3050 /// Build a new binary 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 RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3055 Expr *LHS, Expr *RHS,
3056 bool ForFoldExpression = false) {
3057 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3058 ForFoldExpression);
3059 }
3060
3061 /// Build a new rewritten 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 RebuildCXXRewrittenBinaryOperator(
3066 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3067 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3068 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3069 RHS, /*RequiresADL*/false);
3070 }
3071
3072 /// Build a new conditional operator expression.
3073 ///
3074 /// By default, performs semantic analysis to build the new expression.
3075 /// Subclasses may override this routine to provide different behavior.
3076 ExprResult RebuildConditionalOperator(Expr *Cond,
3077 SourceLocation QuestionLoc,
3078 Expr *LHS,
3079 SourceLocation ColonLoc,
3080 Expr *RHS) {
3081 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3082 LHS, RHS);
3083 }
3084
3085 /// Build a new C-style cast expression.
3086 ///
3087 /// By default, performs semantic analysis to build the new expression.
3088 /// Subclasses may override this routine to provide different behavior.
3089 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3090 TypeSourceInfo *TInfo,
3091 SourceLocation RParenLoc,
3092 Expr *SubExpr) {
3093 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3094 SubExpr);
3095 }
3096
3097 /// Build a new compound literal expression.
3098 ///
3099 /// By default, performs semantic analysis to build the new expression.
3100 /// Subclasses may override this routine to provide different behavior.
3101 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3102 TypeSourceInfo *TInfo,
3103 SourceLocation RParenLoc,
3104 Expr *Init) {
3105 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3106 Init);
3107 }
3108
3109 /// Build a new extended vector or matrix element access expression.
3110 ///
3111 /// By default, performs semantic analysis to build the new expression.
3112 /// Subclasses may override this routine to provide different behavior.
3113 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3114 SourceLocation OpLoc,
3115 bool IsArrow,
3116 SourceLocation AccessorLoc,
3117 IdentifierInfo &Accessor) {
3118
3119 CXXScopeSpec SS;
3120 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3121 return getSema().BuildMemberReferenceExpr(
3122 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3123 /*FirstQualifierInScope*/ nullptr, NameInfo,
3124 /* TemplateArgs */ nullptr,
3125 /*S*/ nullptr);
3126 }
3127
3128 /// Build a new initializer list expression.
3129 ///
3130 /// By default, performs semantic analysis to build the new expression.
3131 /// Subclasses may override this routine to provide different behavior.
3132 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3133 SourceLocation RBraceLoc, bool IsExplicit) {
3134 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3135 }
3136
3137 /// Build a new designated initializer expression.
3138 ///
3139 /// By default, performs semantic analysis to build the new expression.
3140 /// Subclasses may override this routine to provide different behavior.
3141 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3142 MultiExprArg ArrayExprs,
3143 SourceLocation EqualOrColonLoc,
3144 bool GNUSyntax,
3145 Expr *Init) {
3146 ExprResult Result
3147 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3148 Init);
3149 if (Result.isInvalid())
3150 return ExprError();
3151
3152 return Result;
3153 }
3154
3155 /// Build a new value-initialized expression.
3156 ///
3157 /// By default, builds the implicit value initialization without performing
3158 /// any semantic analysis. Subclasses may override this routine to provide
3159 /// different behavior.
3160 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3161 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3162 }
3163
3164 /// Build a new \c va_arg expression.
3165 ///
3166 /// By default, performs semantic analysis to build the new expression.
3167 /// Subclasses may override this routine to provide different behavior.
3168 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3169 Expr *SubExpr, TypeSourceInfo *TInfo,
3170 SourceLocation RParenLoc) {
3171 return getSema().BuildVAArgExpr(BuiltinLoc,
3172 SubExpr, TInfo,
3173 RParenLoc);
3174 }
3175
3176 /// Build a new expression list in parentheses.
3177 ///
3178 /// By default, performs semantic analysis to build the new expression.
3179 /// Subclasses may override this routine to provide different behavior.
3180 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3181 MultiExprArg SubExprs,
3182 SourceLocation RParenLoc) {
3183 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3184 }
3185
3186 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3187 unsigned NumUserSpecifiedExprs,
3188 SourceLocation InitLoc,
3189 SourceLocation LParenLoc,
3190 SourceLocation RParenLoc) {
3191 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3192 InitLoc, LParenLoc, RParenLoc);
3193 }
3194
3195 /// Build a new address-of-label expression.
3196 ///
3197 /// By default, performs semantic analysis, using the name of the label
3198 /// rather than attempting to map the label statement itself.
3199 /// Subclasses may override this routine to provide different behavior.
3200 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3201 SourceLocation LabelLoc, LabelDecl *Label) {
3202 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3203 }
3204
3205 /// Build a new GNU statement 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 RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3210 SourceLocation RParenLoc, unsigned TemplateDepth) {
3211 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3212 TemplateDepth);
3213 }
3214
3215 /// Build a new __builtin_choose_expr expression.
3216 ///
3217 /// By default, performs semantic analysis to build the new expression.
3218 /// Subclasses may override this routine to provide different behavior.
3219 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3220 Expr *Cond, Expr *LHS, Expr *RHS,
3221 SourceLocation RParenLoc) {
3222 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3223 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3224 RPLoc: RParenLoc);
3225 }
3226
3227 /// Build a new generic selection expression with an expression predicate.
3228 ///
3229 /// By default, performs semantic analysis to build the new expression.
3230 /// Subclasses may override this routine to provide different behavior.
3231 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3232 SourceLocation DefaultLoc,
3233 SourceLocation RParenLoc,
3234 Expr *ControllingExpr,
3235 ArrayRef<TypeSourceInfo *> Types,
3236 ArrayRef<Expr *> Exprs) {
3237 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3238 /*PredicateIsExpr=*/true,
3239 ControllingExpr, Types, Exprs);
3240 }
3241
3242 /// Build a new generic selection expression with a type predicate.
3243 ///
3244 /// By default, performs semantic analysis to build the new expression.
3245 /// Subclasses may override this routine to provide different behavior.
3246 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3247 SourceLocation DefaultLoc,
3248 SourceLocation RParenLoc,
3249 TypeSourceInfo *ControllingType,
3250 ArrayRef<TypeSourceInfo *> Types,
3251 ArrayRef<Expr *> Exprs) {
3252 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3253 /*PredicateIsExpr=*/false,
3254 ControllingType, Types, Exprs);
3255 }
3256
3257 /// Build a new overloaded operator call expression.
3258 ///
3259 /// By default, performs semantic analysis to build the new expression.
3260 /// The semantic analysis provides the behavior of template instantiation,
3261 /// copying with transformations that turn what looks like an overloaded
3262 /// operator call into a use of a builtin operator, performing
3263 /// argument-dependent lookup, etc. Subclasses may override this routine to
3264 /// provide different behavior.
3265 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3266 SourceLocation OpLoc,
3267 SourceLocation CalleeLoc,
3268 bool RequiresADL,
3269 const UnresolvedSetImpl &Functions,
3270 Expr *First, Expr *Second);
3271
3272 /// Build a new C++ "named" cast expression, such as static_cast or
3273 /// reinterpret_cast.
3274 ///
3275 /// By default, this routine dispatches to one of the more-specific routines
3276 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3277 /// Subclasses may override this routine to provide different behavior.
3278 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3279 Stmt::StmtClass Class,
3280 SourceLocation LAngleLoc,
3281 TypeSourceInfo *TInfo,
3282 SourceLocation RAngleLoc,
3283 SourceLocation LParenLoc,
3284 Expr *SubExpr,
3285 SourceLocation RParenLoc) {
3286 switch (Class) {
3287 case Stmt::CXXStaticCastExprClass:
3288 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3289 RAngleLoc, LParenLoc,
3290 SubExpr, RParenLoc);
3291
3292 case Stmt::CXXDynamicCastExprClass:
3293 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3294 RAngleLoc, LParenLoc,
3295 SubExpr, RParenLoc);
3296
3297 case Stmt::CXXReinterpretCastExprClass:
3298 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3299 RAngleLoc, LParenLoc,
3300 SubExpr,
3301 RParenLoc);
3302
3303 case Stmt::CXXConstCastExprClass:
3304 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3305 RAngleLoc, LParenLoc,
3306 SubExpr, RParenLoc);
3307
3308 case Stmt::CXXAddrspaceCastExprClass:
3309 return getDerived().RebuildCXXAddrspaceCastExpr(
3310 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3311
3312 default:
3313 llvm_unreachable("Invalid C++ named cast");
3314 }
3315 }
3316
3317 /// Build a new C++ static_cast expression.
3318 ///
3319 /// By default, performs semantic analysis to build the new expression.
3320 /// Subclasses may override this routine to provide different behavior.
3321 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3322 SourceLocation LAngleLoc,
3323 TypeSourceInfo *TInfo,
3324 SourceLocation RAngleLoc,
3325 SourceLocation LParenLoc,
3326 Expr *SubExpr,
3327 SourceLocation RParenLoc) {
3328 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3329 TInfo, SubExpr,
3330 SourceRange(LAngleLoc, RAngleLoc),
3331 SourceRange(LParenLoc, RParenLoc));
3332 }
3333
3334 /// Build a new C++ dynamic_cast expression.
3335 ///
3336 /// By default, performs semantic analysis to build the new expression.
3337 /// Subclasses may override this routine to provide different behavior.
3338 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3339 SourceLocation LAngleLoc,
3340 TypeSourceInfo *TInfo,
3341 SourceLocation RAngleLoc,
3342 SourceLocation LParenLoc,
3343 Expr *SubExpr,
3344 SourceLocation RParenLoc) {
3345 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3346 TInfo, SubExpr,
3347 SourceRange(LAngleLoc, RAngleLoc),
3348 SourceRange(LParenLoc, RParenLoc));
3349 }
3350
3351 /// Build a new C++ reinterpret_cast expression.
3352 ///
3353 /// By default, performs semantic analysis to build the new expression.
3354 /// Subclasses may override this routine to provide different behavior.
3355 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3356 SourceLocation LAngleLoc,
3357 TypeSourceInfo *TInfo,
3358 SourceLocation RAngleLoc,
3359 SourceLocation LParenLoc,
3360 Expr *SubExpr,
3361 SourceLocation RParenLoc) {
3362 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3363 TInfo, SubExpr,
3364 SourceRange(LAngleLoc, RAngleLoc),
3365 SourceRange(LParenLoc, RParenLoc));
3366 }
3367
3368 /// Build a new C++ const_cast expression.
3369 ///
3370 /// By default, performs semantic analysis to build the new expression.
3371 /// Subclasses may override this routine to provide different behavior.
3372 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3373 SourceLocation LAngleLoc,
3374 TypeSourceInfo *TInfo,
3375 SourceLocation RAngleLoc,
3376 SourceLocation LParenLoc,
3377 Expr *SubExpr,
3378 SourceLocation RParenLoc) {
3379 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3380 TInfo, SubExpr,
3381 SourceRange(LAngleLoc, RAngleLoc),
3382 SourceRange(LParenLoc, RParenLoc));
3383 }
3384
3385 ExprResult
3386 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3387 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3388 SourceLocation LParenLoc, Expr *SubExpr,
3389 SourceLocation RParenLoc) {
3390 return getSema().BuildCXXNamedCast(
3391 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3392 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3393 }
3394
3395 /// Build a new C++ functional-style cast expression.
3396 ///
3397 /// By default, performs semantic analysis to build the new expression.
3398 /// Subclasses may override this routine to provide different behavior.
3399 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3400 SourceLocation LParenLoc,
3401 Expr *Sub,
3402 SourceLocation RParenLoc,
3403 bool ListInitialization) {
3404 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3405 // CXXParenListInitExpr. Pass its expanded arguments so that the
3406 // CXXParenListInitExpr can be rebuilt.
3407 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3408 return getSema().BuildCXXTypeConstructExpr(
3409 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3410 RParenLoc, ListInitialization);
3411
3412 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3413 return getSema().BuildCXXTypeConstructExpr(
3414 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3415
3416 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3417 MultiExprArg(&Sub, 1), RParenLoc,
3418 ListInitialization);
3419 }
3420
3421 /// Build a new C++ __builtin_bit_cast 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 RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3426 TypeSourceInfo *TSI, Expr *Sub,
3427 SourceLocation RParenLoc) {
3428 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3429 }
3430
3431 /// Build a new C++ typeid(type) expression.
3432 ///
3433 /// By default, performs semantic analysis to build the new expression.
3434 /// Subclasses may override this routine to provide different behavior.
3435 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3436 SourceLocation TypeidLoc,
3437 TypeSourceInfo *Operand,
3438 SourceLocation RParenLoc) {
3439 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3440 RParenLoc);
3441 }
3442
3443
3444 /// Build a new C++ typeid(expr) expression.
3445 ///
3446 /// By default, performs semantic analysis to build the new expression.
3447 /// Subclasses may override this routine to provide different behavior.
3448 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3449 SourceLocation TypeidLoc,
3450 Expr *Operand,
3451 SourceLocation RParenLoc) {
3452 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3453 RParenLoc);
3454 }
3455
3456 /// Build a new C++ __uuidof(type) 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 TypeSourceInfo *Operand,
3462 SourceLocation RParenLoc) {
3463 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3464 }
3465
3466 /// Build a new C++ __uuidof(expr) expression.
3467 ///
3468 /// By default, performs semantic analysis to build the new expression.
3469 /// Subclasses may override this routine to provide different behavior.
3470 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3471 Expr *Operand, SourceLocation RParenLoc) {
3472 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3473 }
3474
3475 /// Build a new C++ "this" expression.
3476 ///
3477 /// By default, performs semantic analysis to build a new "this" expression.
3478 /// Subclasses may override this routine to provide different behavior.
3479 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3480 QualType ThisType,
3481 bool isImplicit) {
3482 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3483 return ExprError();
3484 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3485 }
3486
3487 /// Build a new C++ throw expression.
3488 ///
3489 /// By default, performs semantic analysis to build the new expression.
3490 /// Subclasses may override this routine to provide different behavior.
3491 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3492 bool IsThrownVariableInScope) {
3493 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3494 }
3495
3496 /// Build a new C++ default-argument expression.
3497 ///
3498 /// By default, builds a new default-argument expression, which does not
3499 /// require any semantic analysis. Subclasses may override this routine to
3500 /// provide different behavior.
3501 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3502 Expr *RewrittenExpr) {
3503 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3504 RewrittenExpr, UsedContext: getSema().CurContext);
3505 }
3506
3507 /// Build a new C++11 default-initialization expression.
3508 ///
3509 /// By default, builds a new default field initialization expression, which
3510 /// does not require any semantic analysis. Subclasses may override this
3511 /// routine to provide different behavior.
3512 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3513 FieldDecl *Field) {
3514 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3515 }
3516
3517 /// Build a new C++ zero-initialization expression.
3518 ///
3519 /// By default, performs semantic analysis to build the new expression.
3520 /// Subclasses may override this routine to provide different behavior.
3521 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3522 SourceLocation LParenLoc,
3523 SourceLocation RParenLoc) {
3524 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3525 /*ListInitialization=*/false);
3526 }
3527
3528 /// Build a new C++ "new" expression.
3529 ///
3530 /// By default, performs semantic analysis to build the new expression.
3531 /// Subclasses may override this routine to provide different behavior.
3532 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3533 SourceLocation PlacementLParen,
3534 MultiExprArg PlacementArgs,
3535 SourceLocation PlacementRParen,
3536 SourceRange TypeIdParens, QualType AllocatedType,
3537 TypeSourceInfo *AllocatedTypeInfo,
3538 std::optional<Expr *> ArraySize,
3539 SourceRange DirectInitRange, Expr *Initializer) {
3540 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3541 PlacementLParen,
3542 PlacementArgs,
3543 PlacementRParen,
3544 TypeIdParens,
3545 AllocatedType,
3546 AllocatedTypeInfo,
3547 ArraySize,
3548 DirectInitRange,
3549 Initializer);
3550 }
3551
3552 /// Build a new C++ "delete" expression.
3553 ///
3554 /// By default, performs semantic analysis to build the new expression.
3555 /// Subclasses may override this routine to provide different behavior.
3556 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3557 bool IsGlobalDelete,
3558 bool IsArrayForm,
3559 Expr *Operand) {
3560 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3561 Operand);
3562 }
3563
3564 /// Build a new type trait expression.
3565 ///
3566 /// By default, performs semantic analysis to build the new expression.
3567 /// Subclasses may override this routine to provide different behavior.
3568 ExprResult RebuildTypeTrait(TypeTrait Trait,
3569 SourceLocation StartLoc,
3570 ArrayRef<TypeSourceInfo *> Args,
3571 SourceLocation RParenLoc) {
3572 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3573 }
3574
3575 /// Build a new array type trait expression.
3576 ///
3577 /// By default, performs semantic analysis to build the new expression.
3578 /// Subclasses may override this routine to provide different behavior.
3579 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3580 SourceLocation StartLoc,
3581 TypeSourceInfo *TSInfo,
3582 Expr *DimExpr,
3583 SourceLocation RParenLoc) {
3584 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3585 }
3586
3587 /// Build a new expression trait expression.
3588 ///
3589 /// By default, performs semantic analysis to build the new expression.
3590 /// Subclasses may override this routine to provide different behavior.
3591 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3592 SourceLocation StartLoc,
3593 Expr *Queried,
3594 SourceLocation RParenLoc) {
3595 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3596 }
3597
3598 /// Build a new (previously unresolved) declaration reference
3599 /// expression.
3600 ///
3601 /// By default, performs semantic analysis to build the new expression.
3602 /// Subclasses may override this routine to provide different behavior.
3603 ExprResult RebuildDependentScopeDeclRefExpr(
3604 NestedNameSpecifierLoc QualifierLoc,
3605 SourceLocation TemplateKWLoc,
3606 const DeclarationNameInfo &NameInfo,
3607 const TemplateArgumentListInfo *TemplateArgs,
3608 bool IsAddressOfOperand,
3609 TypeSourceInfo **RecoveryTSI) {
3610 CXXScopeSpec SS;
3611 SS.Adopt(Other: QualifierLoc);
3612
3613 if (TemplateArgs || TemplateKWLoc.isValid())
3614 return getSema().BuildQualifiedTemplateIdExpr(
3615 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3616
3617 return getSema().BuildQualifiedDeclarationNameExpr(
3618 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3619 }
3620
3621 /// Build a new template-id expression.
3622 ///
3623 /// By default, performs semantic analysis to build the new expression.
3624 /// Subclasses may override this routine to provide different behavior.
3625 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3626 SourceLocation TemplateKWLoc,
3627 LookupResult &R,
3628 bool RequiresADL,
3629 const TemplateArgumentListInfo *TemplateArgs) {
3630 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3631 TemplateArgs);
3632 }
3633
3634 /// Build a new object-construction expression.
3635 ///
3636 /// By default, performs semantic analysis to build the new expression.
3637 /// Subclasses may override this routine to provide different behavior.
3638 ExprResult RebuildCXXConstructExpr(
3639 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3640 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3641 bool ListInitialization, bool StdInitListInitialization,
3642 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3643 SourceRange ParenRange) {
3644 // Reconstruct the constructor we originally found, which might be
3645 // different if this is a call to an inherited constructor.
3646 CXXConstructorDecl *FoundCtor = Constructor;
3647 if (Constructor->isInheritingConstructor())
3648 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3649
3650 SmallVector<Expr *, 8> ConvertedArgs;
3651 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3652 ConvertedArgs))
3653 return ExprError();
3654
3655 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3656 IsElidable,
3657 ConvertedArgs,
3658 HadMultipleCandidates,
3659 ListInitialization,
3660 StdInitListInitialization,
3661 RequiresZeroInit, ConstructKind,
3662 ParenRange);
3663 }
3664
3665 /// Build a new implicit construction via inherited constructor
3666 /// expression.
3667 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3668 CXXConstructorDecl *Constructor,
3669 bool ConstructsVBase,
3670 bool InheritedFromVBase) {
3671 return new (getSema().Context) CXXInheritedCtorInitExpr(
3672 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3673 }
3674
3675 /// Build a new object-construction expression.
3676 ///
3677 /// By default, performs semantic analysis to build the new expression.
3678 /// Subclasses may override this routine to provide different behavior.
3679 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3680 SourceLocation LParenOrBraceLoc,
3681 MultiExprArg Args,
3682 SourceLocation RParenOrBraceLoc,
3683 bool ListInitialization) {
3684 return getSema().BuildCXXTypeConstructExpr(
3685 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3686 }
3687
3688 /// Build a new object-construction expression.
3689 ///
3690 /// By default, performs semantic analysis to build the new expression.
3691 /// Subclasses may override this routine to provide different behavior.
3692 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3693 SourceLocation LParenLoc,
3694 MultiExprArg Args,
3695 SourceLocation RParenLoc,
3696 bool ListInitialization) {
3697 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3698 RParenLoc, ListInitialization);
3699 }
3700
3701 /// Build a new member reference expression.
3702 ///
3703 /// By default, performs semantic analysis to build the new expression.
3704 /// Subclasses may override this routine to provide different behavior.
3705 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3706 QualType BaseType,
3707 bool IsArrow,
3708 SourceLocation OperatorLoc,
3709 NestedNameSpecifierLoc QualifierLoc,
3710 SourceLocation TemplateKWLoc,
3711 NamedDecl *FirstQualifierInScope,
3712 const DeclarationNameInfo &MemberNameInfo,
3713 const TemplateArgumentListInfo *TemplateArgs) {
3714 CXXScopeSpec SS;
3715 SS.Adopt(Other: QualifierLoc);
3716
3717 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3718 OpLoc: OperatorLoc, IsArrow,
3719 SS, TemplateKWLoc,
3720 FirstQualifierInScope,
3721 NameInfo: MemberNameInfo,
3722 TemplateArgs, /*S*/S: nullptr);
3723 }
3724
3725 /// Build a new member reference expression.
3726 ///
3727 /// By default, performs semantic analysis to build the new expression.
3728 /// Subclasses may override this routine to provide different behavior.
3729 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3730 SourceLocation OperatorLoc,
3731 bool IsArrow,
3732 NestedNameSpecifierLoc QualifierLoc,
3733 SourceLocation TemplateKWLoc,
3734 NamedDecl *FirstQualifierInScope,
3735 LookupResult &R,
3736 const TemplateArgumentListInfo *TemplateArgs) {
3737 CXXScopeSpec SS;
3738 SS.Adopt(Other: QualifierLoc);
3739
3740 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3741 OpLoc: OperatorLoc, IsArrow,
3742 SS, TemplateKWLoc,
3743 FirstQualifierInScope,
3744 R, TemplateArgs, /*S*/S: nullptr);
3745 }
3746
3747 /// Build a new noexcept expression.
3748 ///
3749 /// By default, performs semantic analysis to build the new expression.
3750 /// Subclasses may override this routine to provide different behavior.
3751 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3752 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3753 }
3754
3755 UnsignedOrNone
3756 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3757
3758 /// Build a new expression to compute the length of a parameter pack.
3759 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3760 SourceLocation PackLoc,
3761 SourceLocation RParenLoc,
3762 UnsignedOrNone Length,
3763 ArrayRef<TemplateArgument> PartialArgs) {
3764 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3765 RParenLoc, Length, PartialArgs);
3766 }
3767
3768 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3769 SourceLocation RSquareLoc,
3770 Expr *PackIdExpression, Expr *IndexExpr,
3771 ArrayRef<Expr *> ExpandedExprs,
3772 bool FullySubstituted = false) {
3773 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3774 IndexExpr, RSquareLoc, ExpandedExprs,
3775 FullySubstituted);
3776 }
3777
3778 /// Build a new expression representing a call to a source location
3779 /// builtin.
3780 ///
3781 /// By default, performs semantic analysis to build the new expression.
3782 /// Subclasses may override this routine to provide different behavior.
3783 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3784 SourceLocation BuiltinLoc,
3785 SourceLocation RPLoc,
3786 DeclContext *ParentContext) {
3787 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3788 ParentContext);
3789 }
3790
3791 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3792 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3793 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3794 TemplateArgumentListInfo *TALI) {
3795 CXXScopeSpec SS;
3796 SS.Adopt(Other: NNS);
3797 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3798 ConceptNameInfo,
3799 FoundDecl,
3800 NamedConcept, TALI);
3801 if (Result.isInvalid())
3802 return ExprError();
3803 return Result;
3804 }
3805
3806 /// \brief Build a new requires expression.
3807 ///
3808 /// By default, performs semantic analysis to build the new expression.
3809 /// Subclasses may override this routine to provide different behavior.
3810 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3811 RequiresExprBodyDecl *Body,
3812 SourceLocation LParenLoc,
3813 ArrayRef<ParmVarDecl *> LocalParameters,
3814 SourceLocation RParenLoc,
3815 ArrayRef<concepts::Requirement *> Requirements,
3816 SourceLocation ClosingBraceLoc) {
3817 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3818 LocalParameters, RParenLoc, Requirements,
3819 RBraceLoc: ClosingBraceLoc);
3820 }
3821
3822 concepts::TypeRequirement *
3823 RebuildTypeRequirement(
3824 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3825 return SemaRef.BuildTypeRequirement(SubstDiag);
3826 }
3827
3828 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3829 return SemaRef.BuildTypeRequirement(Type: T);
3830 }
3831
3832 concepts::ExprRequirement *
3833 RebuildExprRequirement(
3834 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3835 SourceLocation NoexceptLoc,
3836 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3837 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3838 ReturnTypeRequirement: std::move(Ret));
3839 }
3840
3841 concepts::ExprRequirement *
3842 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3843 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3844 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3845 ReturnTypeRequirement: std::move(Ret));
3846 }
3847
3848 concepts::NestedRequirement *
3849 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3850 const ASTConstraintSatisfaction &Satisfaction) {
3851 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3852 Satisfaction);
3853 }
3854
3855 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3856 return SemaRef.BuildNestedRequirement(E: Constraint);
3857 }
3858
3859 /// \brief Build a new Objective-C boxed expression.
3860 ///
3861 /// By default, performs semantic analysis to build the new expression.
3862 /// Subclasses may override this routine to provide different behavior.
3863 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3864 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3865 }
3866
3867 /// Build a new Objective-C array literal.
3868 ///
3869 /// By default, performs semantic analysis to build the new expression.
3870 /// Subclasses may override this routine to provide different behavior.
3871 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3872 Expr **Elements, unsigned NumElements) {
3873 return getSema().ObjC().BuildObjCArrayLiteral(
3874 Range, MultiExprArg(Elements, NumElements));
3875 }
3876
3877 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3878 Expr *Base, Expr *Key,
3879 ObjCMethodDecl *getterMethod,
3880 ObjCMethodDecl *setterMethod) {
3881 return getSema().ObjC().BuildObjCSubscriptExpression(
3882 RB, Base, Key, getterMethod, setterMethod);
3883 }
3884
3885 /// Build a new Objective-C dictionary literal.
3886 ///
3887 /// By default, performs semantic analysis to build the new expression.
3888 /// Subclasses may override this routine to provide different behavior.
3889 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3890 MutableArrayRef<ObjCDictionaryElement> Elements) {
3891 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3892 }
3893
3894 /// Build a new Objective-C \@encode expression.
3895 ///
3896 /// By default, performs semantic analysis to build the new expression.
3897 /// Subclasses may override this routine to provide different behavior.
3898 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3899 TypeSourceInfo *EncodeTypeInfo,
3900 SourceLocation RParenLoc) {
3901 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3902 RParenLoc);
3903 }
3904
3905 /// Build a new Objective-C class message.
3906 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3907 Selector Sel,
3908 ArrayRef<SourceLocation> SelectorLocs,
3909 ObjCMethodDecl *Method,
3910 SourceLocation LBracLoc,
3911 MultiExprArg Args,
3912 SourceLocation RBracLoc) {
3913 return SemaRef.ObjC().BuildClassMessage(
3914 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3915 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3916 RBracLoc, Args);
3917 }
3918
3919 /// Build a new Objective-C instance message.
3920 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3921 Selector Sel,
3922 ArrayRef<SourceLocation> SelectorLocs,
3923 ObjCMethodDecl *Method,
3924 SourceLocation LBracLoc,
3925 MultiExprArg Args,
3926 SourceLocation RBracLoc) {
3927 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3928 /*SuperLoc=*/SuperLoc: SourceLocation(),
3929 Sel, Method, LBracLoc,
3930 SelectorLocs, RBracLoc, Args);
3931 }
3932
3933 /// Build a new Objective-C instance/class message to 'super'.
3934 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3935 Selector Sel,
3936 ArrayRef<SourceLocation> SelectorLocs,
3937 QualType SuperType,
3938 ObjCMethodDecl *Method,
3939 SourceLocation LBracLoc,
3940 MultiExprArg Args,
3941 SourceLocation RBracLoc) {
3942 return Method->isInstanceMethod()
3943 ? SemaRef.ObjC().BuildInstanceMessage(
3944 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3945 SelectorLocs, RBracLoc, Args)
3946 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3947 Sel, Method, LBracLoc,
3948 SelectorLocs, RBracLoc, Args);
3949 }
3950
3951 /// Build a new Objective-C ivar reference expression.
3952 ///
3953 /// By default, performs semantic analysis to build the new expression.
3954 /// Subclasses may override this routine to provide different behavior.
3955 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3956 SourceLocation IvarLoc,
3957 bool IsArrow, bool IsFreeIvar) {
3958 CXXScopeSpec SS;
3959 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3960 ExprResult Result = getSema().BuildMemberReferenceExpr(
3961 BaseArg, BaseArg->getType(),
3962 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3963 /*FirstQualifierInScope=*/nullptr, NameInfo,
3964 /*TemplateArgs=*/nullptr,
3965 /*S=*/nullptr);
3966 if (IsFreeIvar && Result.isUsable())
3967 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3968 return Result;
3969 }
3970
3971 /// Build a new Objective-C property reference expression.
3972 ///
3973 /// By default, performs semantic analysis to build the new expression.
3974 /// Subclasses may override this routine to provide different behavior.
3975 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3976 ObjCPropertyDecl *Property,
3977 SourceLocation PropertyLoc) {
3978 CXXScopeSpec SS;
3979 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3980 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3981 /*FIXME:*/PropertyLoc,
3982 /*IsArrow=*/false,
3983 SS, SourceLocation(),
3984 /*FirstQualifierInScope=*/nullptr,
3985 NameInfo,
3986 /*TemplateArgs=*/nullptr,
3987 /*S=*/nullptr);
3988 }
3989
3990 /// Build a new Objective-C property reference expression.
3991 ///
3992 /// By default, performs semantic analysis to build the new expression.
3993 /// Subclasses may override this routine to provide different behavior.
3994 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3995 ObjCMethodDecl *Getter,
3996 ObjCMethodDecl *Setter,
3997 SourceLocation PropertyLoc) {
3998 // Since these expressions can only be value-dependent, we do not
3999 // need to perform semantic analysis again.
4000 return Owned(
4001 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4002 VK_LValue, OK_ObjCProperty,
4003 PropertyLoc, Base));
4004 }
4005
4006 /// Build a new Objective-C "isa" expression.
4007 ///
4008 /// By default, performs semantic analysis to build the new expression.
4009 /// Subclasses may override this routine to provide different behavior.
4010 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4011 SourceLocation OpLoc, bool IsArrow) {
4012 CXXScopeSpec SS;
4013 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4014 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4015 OpLoc, IsArrow,
4016 SS, SourceLocation(),
4017 /*FirstQualifierInScope=*/nullptr,
4018 NameInfo,
4019 /*TemplateArgs=*/nullptr,
4020 /*S=*/nullptr);
4021 }
4022
4023 /// Build a new shuffle vector expression.
4024 ///
4025 /// By default, performs semantic analysis to build the new expression.
4026 /// Subclasses may override this routine to provide different behavior.
4027 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4028 MultiExprArg SubExprs,
4029 SourceLocation RParenLoc) {
4030 // Find the declaration for __builtin_shufflevector
4031 const IdentifierInfo &Name
4032 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4033 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4034 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4035 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4036
4037 // Build a reference to the __builtin_shufflevector builtin
4038 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4039 Expr *Callee = new (SemaRef.Context)
4040 DeclRefExpr(SemaRef.Context, Builtin, false,
4041 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4042 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4043 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4044 CK: CK_BuiltinFnToFnPtr).get();
4045
4046 // Build the CallExpr
4047 ExprResult TheCall = CallExpr::Create(
4048 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4049 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4050 FPFeatures: FPOptionsOverride());
4051
4052 // Type-check the __builtin_shufflevector expression.
4053 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4054 }
4055
4056 /// Build a new convert vector expression.
4057 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4058 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4059 SourceLocation RParenLoc) {
4060 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4061 }
4062
4063 /// Build a new template argument pack expansion.
4064 ///
4065 /// By default, performs semantic analysis to build a new pack expansion
4066 /// for a template argument. Subclasses may override this routine to provide
4067 /// different behavior.
4068 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4069 SourceLocation EllipsisLoc,
4070 UnsignedOrNone NumExpansions) {
4071 switch (Pattern.getArgument().getKind()) {
4072 case TemplateArgument::Expression: {
4073 ExprResult Result
4074 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4075 EllipsisLoc, NumExpansions);
4076 if (Result.isInvalid())
4077 return TemplateArgumentLoc();
4078
4079 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4080 /*IsCanonical=*/false),
4081 Result.get());
4082 }
4083
4084 case TemplateArgument::Template:
4085 return TemplateArgumentLoc(
4086 SemaRef.Context,
4087 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4088 NumExpansions),
4089 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4090 Pattern.getTemplateNameLoc(), EllipsisLoc);
4091
4092 case TemplateArgument::Null:
4093 case TemplateArgument::Integral:
4094 case TemplateArgument::Declaration:
4095 case TemplateArgument::StructuralValue:
4096 case TemplateArgument::Pack:
4097 case TemplateArgument::TemplateExpansion:
4098 case TemplateArgument::NullPtr:
4099 llvm_unreachable("Pack expansion pattern has no parameter packs");
4100
4101 case TemplateArgument::Type:
4102 if (TypeSourceInfo *Expansion
4103 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4104 EllipsisLoc,
4105 NumExpansions))
4106 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4107 Expansion);
4108 break;
4109 }
4110
4111 return TemplateArgumentLoc();
4112 }
4113
4114 /// Build a new expression pack expansion.
4115 ///
4116 /// By default, performs semantic analysis to build a new pack expansion
4117 /// for an expression. Subclasses may override this routine to provide
4118 /// different behavior.
4119 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4120 UnsignedOrNone NumExpansions) {
4121 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4122 }
4123
4124 /// Build a new C++1z fold-expression.
4125 ///
4126 /// By default, performs semantic analysis in order to build a new fold
4127 /// expression.
4128 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4129 SourceLocation LParenLoc, Expr *LHS,
4130 BinaryOperatorKind Operator,
4131 SourceLocation EllipsisLoc, Expr *RHS,
4132 SourceLocation RParenLoc,
4133 UnsignedOrNone NumExpansions) {
4134 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4135 EllipsisLoc, RHS, RParenLoc,
4136 NumExpansions);
4137 }
4138
4139 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4140 LambdaScopeInfo *LSI) {
4141 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4142 if (Expr *Init = PVD->getInit())
4143 LSI->ContainsUnexpandedParameterPack |=
4144 Init->containsUnexpandedParameterPack();
4145 else if (PVD->hasUninstantiatedDefaultArg())
4146 LSI->ContainsUnexpandedParameterPack |=
4147 PVD->getUninstantiatedDefaultArg()
4148 ->containsUnexpandedParameterPack();
4149 }
4150 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4151 }
4152
4153 /// Build an empty C++1z fold-expression with the given operator.
4154 ///
4155 /// By default, produces the fallback value for the fold-expression, or
4156 /// produce an error if there is no fallback value.
4157 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4158 BinaryOperatorKind Operator) {
4159 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4160 }
4161
4162 /// Build a new atomic operation expression.
4163 ///
4164 /// By default, performs semantic analysis to build the new expression.
4165 /// Subclasses may override this routine to provide different behavior.
4166 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4167 AtomicExpr::AtomicOp Op,
4168 SourceLocation RParenLoc) {
4169 // Use this for all of the locations, since we don't know the difference
4170 // between the call and the expr at this point.
4171 SourceRange Range{BuiltinLoc, RParenLoc};
4172 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4173 Sema::AtomicArgumentOrder::AST);
4174 }
4175
4176 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4177 ArrayRef<Expr *> SubExprs, QualType Type) {
4178 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4179 }
4180
4181 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4182 SourceLocation BeginLoc,
4183 SourceLocation DirLoc,
4184 SourceLocation EndLoc,
4185 ArrayRef<OpenACCClause *> Clauses,
4186 StmtResult StrBlock) {
4187 return getSema().OpenACC().ActOnEndStmtDirective(
4188 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4189 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4190 }
4191
4192 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4193 SourceLocation DirLoc,
4194 SourceLocation EndLoc,
4195 ArrayRef<OpenACCClause *> Clauses,
4196 StmtResult Loop) {
4197 return getSema().OpenACC().ActOnEndStmtDirective(
4198 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4199 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4200 Clauses, Loop);
4201 }
4202
4203 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4204 SourceLocation BeginLoc,
4205 SourceLocation DirLoc,
4206 SourceLocation EndLoc,
4207 ArrayRef<OpenACCClause *> Clauses,
4208 StmtResult Loop) {
4209 return getSema().OpenACC().ActOnEndStmtDirective(
4210 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4211 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4212 }
4213
4214 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4215 SourceLocation DirLoc,
4216 SourceLocation EndLoc,
4217 ArrayRef<OpenACCClause *> Clauses,
4218 StmtResult StrBlock) {
4219 return getSema().OpenACC().ActOnEndStmtDirective(
4220 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4221 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4222 Clauses, StrBlock);
4223 }
4224
4225 StmtResult
4226 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4227 SourceLocation DirLoc, SourceLocation EndLoc,
4228 ArrayRef<OpenACCClause *> Clauses) {
4229 return getSema().OpenACC().ActOnEndStmtDirective(
4230 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4231 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4232 Clauses, {});
4233 }
4234
4235 StmtResult
4236 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4237 SourceLocation DirLoc, SourceLocation EndLoc,
4238 ArrayRef<OpenACCClause *> Clauses) {
4239 return getSema().OpenACC().ActOnEndStmtDirective(
4240 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4241 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4242 Clauses, {});
4243 }
4244
4245 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4246 SourceLocation DirLoc,
4247 SourceLocation EndLoc,
4248 ArrayRef<OpenACCClause *> Clauses,
4249 StmtResult StrBlock) {
4250 return getSema().OpenACC().ActOnEndStmtDirective(
4251 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4252 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4253 Clauses, StrBlock);
4254 }
4255
4256 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4257 SourceLocation DirLoc,
4258 SourceLocation EndLoc,
4259 ArrayRef<OpenACCClause *> Clauses) {
4260 return getSema().OpenACC().ActOnEndStmtDirective(
4261 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4262 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4263 Clauses, {});
4264 }
4265
4266 StmtResult
4267 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4268 SourceLocation DirLoc, SourceLocation EndLoc,
4269 ArrayRef<OpenACCClause *> Clauses) {
4270 return getSema().OpenACC().ActOnEndStmtDirective(
4271 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4272 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4273 Clauses, {});
4274 }
4275
4276 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4277 SourceLocation DirLoc,
4278 SourceLocation EndLoc,
4279 ArrayRef<OpenACCClause *> Clauses) {
4280 return getSema().OpenACC().ActOnEndStmtDirective(
4281 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4282 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4283 Clauses, {});
4284 }
4285
4286 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4287 SourceLocation DirLoc,
4288 SourceLocation EndLoc,
4289 ArrayRef<OpenACCClause *> Clauses) {
4290 return getSema().OpenACC().ActOnEndStmtDirective(
4291 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4292 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4293 Clauses, {});
4294 }
4295
4296 StmtResult RebuildOpenACCWaitConstruct(
4297 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4298 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4299 SourceLocation RParenLoc, SourceLocation EndLoc,
4300 ArrayRef<OpenACCClause *> Clauses) {
4301 llvm::SmallVector<Expr *> Exprs;
4302 Exprs.push_back(Elt: DevNumExpr);
4303 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4304 return getSema().OpenACC().ActOnEndStmtDirective(
4305 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4306 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4307 }
4308
4309 StmtResult RebuildOpenACCCacheConstruct(
4310 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4311 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4312 SourceLocation RParenLoc, SourceLocation EndLoc) {
4313 return getSema().OpenACC().ActOnEndStmtDirective(
4314 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4315 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4316 }
4317
4318 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4319 SourceLocation DirLoc,
4320 OpenACCAtomicKind AtKind,
4321 SourceLocation EndLoc,
4322 ArrayRef<OpenACCClause *> Clauses,
4323 StmtResult AssociatedStmt) {
4324 return getSema().OpenACC().ActOnEndStmtDirective(
4325 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4326 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4327 AssociatedStmt);
4328 }
4329
4330 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4331 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4332 }
4333
4334 ExprResult
4335 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4336 QualType ParamType, SourceLocation Loc,
4337 TemplateArgument Arg,
4338 UnsignedOrNone PackIndex, bool Final) {
4339 return getSema().BuildSubstNonTypeTemplateParmExpr(
4340 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4341 }
4342
4343 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4344 SourceLocation StartLoc,
4345 SourceLocation LParenLoc,
4346 SourceLocation EndLoc) {
4347 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4348 LParenLoc, EndLoc);
4349 }
4350
4351private:
4352 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4353 QualType ObjectType,
4354 NamedDecl *FirstQualifierInScope);
4355
4356 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4357 QualType ObjectType,
4358 NamedDecl *FirstQualifierInScope) {
4359 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4360 return TSInfo;
4361
4362 TypeLocBuilder TLB;
4363 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4364 ObjectType, FirstQualifierInScope);
4365 if (T.isNull())
4366 return nullptr;
4367 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4368 }
4369
4370 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4371 DependentNameTypeLoc TL,
4372 bool DeducibleTSTContext,
4373 QualType ObjectType = QualType(),
4374 NamedDecl *UnqualLookup = nullptr);
4375
4376 llvm::SmallVector<OpenACCClause *>
4377 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4378 ArrayRef<const OpenACCClause *> OldClauses);
4379
4380 OpenACCClause *
4381 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4382 OpenACCDirectiveKind DirKind,
4383 const OpenACCClause *OldClause);
4384};
4385
4386template <typename Derived>
4387StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4388 if (!S)
4389 return S;
4390
4391 switch (S->getStmtClass()) {
4392 case Stmt::NoStmtClass: break;
4393
4394 // Transform individual statement nodes
4395 // Pass SDK into statements that can produce a value
4396#define STMT(Node, Parent) \
4397 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4398#define VALUESTMT(Node, Parent) \
4399 case Stmt::Node##Class: \
4400 return getDerived().Transform##Node(cast<Node>(S), SDK);
4401#define ABSTRACT_STMT(Node)
4402#define EXPR(Node, Parent)
4403#include "clang/AST/StmtNodes.inc"
4404
4405 // Transform expressions by calling TransformExpr.
4406#define STMT(Node, Parent)
4407#define ABSTRACT_STMT(Stmt)
4408#define EXPR(Node, Parent) case Stmt::Node##Class:
4409#include "clang/AST/StmtNodes.inc"
4410 {
4411 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4412
4413 if (SDK == StmtDiscardKind::StmtExprResult)
4414 E = getSema().ActOnStmtExprResult(E);
4415 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4416 }
4417 }
4418
4419 return S;
4420}
4421
4422template<typename Derived>
4423OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4424 if (!S)
4425 return S;
4426
4427 switch (S->getClauseKind()) {
4428 default: break;
4429 // Transform individual clause nodes
4430#define GEN_CLANG_CLAUSE_CLASS
4431#define CLAUSE_CLASS(Enum, Str, Class) \
4432 case Enum: \
4433 return getDerived().Transform##Class(cast<Class>(S));
4434#include "llvm/Frontend/OpenMP/OMP.inc"
4435 }
4436
4437 return S;
4438}
4439
4440
4441template<typename Derived>
4442ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4443 if (!E)
4444 return E;
4445
4446 switch (E->getStmtClass()) {
4447 case Stmt::NoStmtClass: break;
4448#define STMT(Node, Parent) case Stmt::Node##Class: break;
4449#define ABSTRACT_STMT(Stmt)
4450#define EXPR(Node, Parent) \
4451 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4452#include "clang/AST/StmtNodes.inc"
4453 }
4454
4455 return E;
4456}
4457
4458template<typename Derived>
4459ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4460 bool NotCopyInit) {
4461 // Initializers are instantiated like expressions, except that various outer
4462 // layers are stripped.
4463 if (!Init)
4464 return Init;
4465
4466 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4467 Init = FE->getSubExpr();
4468
4469 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4470 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4471 Init = OVE->getSourceExpr();
4472 }
4473
4474 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4475 Init = MTE->getSubExpr();
4476
4477 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4478 Init = Binder->getSubExpr();
4479
4480 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4481 Init = ICE->getSubExprAsWritten();
4482
4483 if (CXXStdInitializerListExpr *ILE =
4484 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4485 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4486
4487 // If this is copy-initialization, we only need to reconstruct
4488 // InitListExprs. Other forms of copy-initialization will be a no-op if
4489 // the initializer is already the right type.
4490 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4491 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4492 return getDerived().TransformExpr(Init);
4493
4494 // Revert value-initialization back to empty parens.
4495 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4496 SourceRange Parens = VIE->getSourceRange();
4497 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4498 Parens.getEnd());
4499 }
4500
4501 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4502 if (isa<ImplicitValueInitExpr>(Val: Init))
4503 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4504 SourceLocation());
4505
4506 // Revert initialization by constructor back to a parenthesized or braced list
4507 // of expressions. Any other form of initializer can just be reused directly.
4508 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4509 return getDerived().TransformExpr(Init);
4510
4511 // If the initialization implicitly converted an initializer list to a
4512 // std::initializer_list object, unwrap the std::initializer_list too.
4513 if (Construct && Construct->isStdInitListInitialization())
4514 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4515
4516 // Enter a list-init context if this was list initialization.
4517 EnterExpressionEvaluationContext Context(
4518 getSema(), EnterExpressionEvaluationContext::InitList,
4519 Construct->isListInitialization());
4520
4521 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4522 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4523 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4524 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4525 SmallVector<Expr*, 8> NewArgs;
4526 bool ArgChanged = false;
4527 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4528 /*IsCall*/true, NewArgs, &ArgChanged))
4529 return ExprError();
4530
4531 // If this was list initialization, revert to syntactic list form.
4532 if (Construct->isListInitialization())
4533 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4534 Construct->getEndLoc(),
4535 /*IsExplicit=*/true);
4536
4537 // Build a ParenListExpr to represent anything else.
4538 SourceRange Parens = Construct->getParenOrBraceRange();
4539 if (Parens.isInvalid()) {
4540 // This was a variable declaration's initialization for which no initializer
4541 // was specified.
4542 assert(NewArgs.empty() &&
4543 "no parens or braces but have direct init with arguments?");
4544 return ExprEmpty();
4545 }
4546 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4547 Parens.getEnd());
4548}
4549
4550template<typename Derived>
4551bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4552 unsigned NumInputs,
4553 bool IsCall,
4554 SmallVectorImpl<Expr *> &Outputs,
4555 bool *ArgChanged) {
4556 for (unsigned I = 0; I != NumInputs; ++I) {
4557 // If requested, drop call arguments that need to be dropped.
4558 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4559 if (ArgChanged)
4560 *ArgChanged = true;
4561
4562 break;
4563 }
4564
4565 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4566 Expr *Pattern = Expansion->getPattern();
4567
4568 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4569 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4570 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4571
4572 // Determine whether the set of unexpanded parameter packs can and should
4573 // be expanded.
4574 bool Expand = true;
4575 bool RetainExpansion = false;
4576 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4577 UnsignedOrNone NumExpansions = OrigNumExpansions;
4578 if (getDerived().TryExpandParameterPacks(
4579 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4580 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4581 RetainExpansion, NumExpansions))
4582 return true;
4583
4584 if (!Expand) {
4585 // The transform has determined that we should perform a simple
4586 // transformation on the pack expansion, producing another pack
4587 // expansion.
4588 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4589 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4590 if (OutPattern.isInvalid())
4591 return true;
4592
4593 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4594 Expansion->getEllipsisLoc(),
4595 NumExpansions);
4596 if (Out.isInvalid())
4597 return true;
4598
4599 if (ArgChanged)
4600 *ArgChanged = true;
4601 Outputs.push_back(Elt: Out.get());
4602 continue;
4603 }
4604
4605 // Record right away that the argument was changed. This needs
4606 // to happen even if the array expands to nothing.
4607 if (ArgChanged) *ArgChanged = true;
4608
4609 // The transform has determined that we should perform an elementwise
4610 // expansion of the pattern. Do so.
4611 for (unsigned I = 0; I != *NumExpansions; ++I) {
4612 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4613 ExprResult Out = getDerived().TransformExpr(Pattern);
4614 if (Out.isInvalid())
4615 return true;
4616
4617 if (Out.get()->containsUnexpandedParameterPack()) {
4618 Out = getDerived().RebuildPackExpansion(
4619 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4620 if (Out.isInvalid())
4621 return true;
4622 }
4623
4624 Outputs.push_back(Elt: Out.get());
4625 }
4626
4627 // If we're supposed to retain a pack expansion, do so by temporarily
4628 // forgetting the partially-substituted parameter pack.
4629 if (RetainExpansion) {
4630 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4631
4632 ExprResult Out = getDerived().TransformExpr(Pattern);
4633 if (Out.isInvalid())
4634 return true;
4635
4636 Out = getDerived().RebuildPackExpansion(
4637 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4638 if (Out.isInvalid())
4639 return true;
4640
4641 Outputs.push_back(Elt: Out.get());
4642 }
4643
4644 continue;
4645 }
4646
4647 ExprResult Result =
4648 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4649 : getDerived().TransformExpr(Inputs[I]);
4650 if (Result.isInvalid())
4651 return true;
4652
4653 if (Result.get() != Inputs[I] && ArgChanged)
4654 *ArgChanged = true;
4655
4656 Outputs.push_back(Elt: Result.get());
4657 }
4658
4659 return false;
4660}
4661
4662template <typename Derived>
4663Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4664 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4665
4666 EnterExpressionEvaluationContext Eval(
4667 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4668 /*LambdaContextDecl=*/nullptr,
4669 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4670 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4671
4672 if (Var) {
4673 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4674 getDerived().TransformDefinition(Var->getLocation(), Var));
4675
4676 if (!ConditionVar)
4677 return Sema::ConditionError();
4678
4679 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4680 }
4681
4682 if (Expr) {
4683 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4684
4685 if (CondExpr.isInvalid())
4686 return Sema::ConditionError();
4687
4688 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4689 /*MissingOK=*/true);
4690 }
4691
4692 return Sema::ConditionResult();
4693}
4694
4695template <typename Derived>
4696NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4697 NestedNameSpecifierLoc NNS, QualType ObjectType,
4698 NamedDecl *FirstQualifierInScope) {
4699 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4700
4701 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4702 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4703 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4704 Qualifiers.push_back(Elt: Qualifier);
4705 };
4706 insertNNS(NNS);
4707
4708 CXXScopeSpec SS;
4709 while (!Qualifiers.empty()) {
4710 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4711 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4712
4713 switch (QNNS.getKind()) {
4714 case NestedNameSpecifier::Kind::Null:
4715 llvm_unreachable("unexpected null nested name specifier");
4716
4717 case NestedNameSpecifier::Kind::Namespace: {
4718 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4719 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4720 QNNS.getAsNamespaceAndPrefix().Namespace)));
4721 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4722 break;
4723 }
4724
4725 case NestedNameSpecifier::Kind::Global:
4726 // There is no meaningful transformation that one could perform on the
4727 // global scope.
4728 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4729 break;
4730
4731 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4732 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4733 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4734 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4735 ColonColonLoc: Q.getEndLoc());
4736 break;
4737 }
4738
4739 case NestedNameSpecifier::Kind::Type: {
4740 assert(SS.isEmpty());
4741 TypeLoc TL = Q.castAsTypeLoc();
4742
4743 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4744 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4745 if (QualifierLoc) {
4746 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4747 QualifierLoc, ObjectType, FirstQualifierInScope);
4748 if (!QualifierLoc)
4749 return NestedNameSpecifierLoc();
4750 ObjectType = QualType();
4751 FirstQualifierInScope = nullptr;
4752 }
4753 SS.Adopt(Other: QualifierLoc);
4754 Sema::NestedNameSpecInfo IdInfo(
4755 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4756 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4757 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4758 EnteringContext: false, SS,
4759 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4760 return NestedNameSpecifierLoc();
4761 return SS.getWithLocInContext(Context&: SemaRef.Context);
4762 }
4763
4764 QualType T = TL.getType();
4765 TypeLocBuilder TLB;
4766 if (!getDerived().AlreadyTransformed(T)) {
4767 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4768 FirstQualifierInScope);
4769 if (T.isNull())
4770 return NestedNameSpecifierLoc();
4771 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4772 }
4773
4774 if (T->isDependentType() || T->isRecordType() ||
4775 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4776 if (T->isEnumeralType())
4777 SemaRef.Diag(Loc: TL.getBeginLoc(),
4778 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4779 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4780 break;
4781 }
4782 // If the nested-name-specifier is an invalid type def, don't emit an
4783 // error because a previous error should have already been emitted.
4784 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4785 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4786 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4787 << T << SS.getRange();
4788 }
4789 return NestedNameSpecifierLoc();
4790 }
4791 }
4792 }
4793
4794 // Don't rebuild the nested-name-specifier if we don't have to.
4795 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4796 !getDerived().AlwaysRebuild())
4797 return NNS;
4798
4799 // If we can re-use the source-location data from the original
4800 // nested-name-specifier, do so.
4801 if (SS.location_size() == NNS.getDataLength() &&
4802 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4803 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4804
4805 // Allocate new nested-name-specifier location information.
4806 return SS.getWithLocInContext(Context&: SemaRef.Context);
4807}
4808
4809template<typename Derived>
4810DeclarationNameInfo
4811TreeTransform<Derived>
4812::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4813 DeclarationName Name = NameInfo.getName();
4814 if (!Name)
4815 return DeclarationNameInfo();
4816
4817 switch (Name.getNameKind()) {
4818 case DeclarationName::Identifier:
4819 case DeclarationName::ObjCZeroArgSelector:
4820 case DeclarationName::ObjCOneArgSelector:
4821 case DeclarationName::ObjCMultiArgSelector:
4822 case DeclarationName::CXXOperatorName:
4823 case DeclarationName::CXXLiteralOperatorName:
4824 case DeclarationName::CXXUsingDirective:
4825 return NameInfo;
4826
4827 case DeclarationName::CXXDeductionGuideName: {
4828 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4829 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4830 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4831 if (!NewTemplate)
4832 return DeclarationNameInfo();
4833
4834 DeclarationNameInfo NewNameInfo(NameInfo);
4835 NewNameInfo.setName(
4836 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4837 return NewNameInfo;
4838 }
4839
4840 case DeclarationName::CXXConstructorName:
4841 case DeclarationName::CXXDestructorName:
4842 case DeclarationName::CXXConversionFunctionName: {
4843 TypeSourceInfo *NewTInfo;
4844 CanQualType NewCanTy;
4845 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4846 NewTInfo = getDerived().TransformType(OldTInfo);
4847 if (!NewTInfo)
4848 return DeclarationNameInfo();
4849 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4850 }
4851 else {
4852 NewTInfo = nullptr;
4853 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4854 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4855 if (NewT.isNull())
4856 return DeclarationNameInfo();
4857 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4858 }
4859
4860 DeclarationName NewName
4861 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4862 Ty: NewCanTy);
4863 DeclarationNameInfo NewNameInfo(NameInfo);
4864 NewNameInfo.setName(NewName);
4865 NewNameInfo.setNamedTypeInfo(NewTInfo);
4866 return NewNameInfo;
4867 }
4868 }
4869
4870 llvm_unreachable("Unknown name kind.");
4871}
4872
4873template <typename Derived>
4874TemplateName TreeTransform<Derived>::RebuildTemplateName(
4875 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4876 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4877 QualType ObjectType, bool AllowInjectedClassName) {
4878 if (const IdentifierInfo *II = IO.getIdentifier())
4879 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4880 ObjectType, AllowInjectedClassName);
4881 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4882 NameLoc, ObjectType,
4883 AllowInjectedClassName);
4884}
4885
4886template <typename Derived>
4887TemplateName TreeTransform<Derived>::TransformTemplateName(
4888 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4889 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4890 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4891 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4892 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4893
4894 if (QualifierLoc) {
4895 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4896 QualifierLoc, ObjectType, FirstQualifierInScope);
4897 if (!QualifierLoc)
4898 return TemplateName();
4899 }
4900
4901 NestedNameSpecifierLoc UnderlyingQualifier;
4902 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4903 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4904 FirstQualifierInScope, AllowInjectedClassName);
4905 if (NewUnderlyingName.isNull())
4906 return TemplateName();
4907 assert(!UnderlyingQualifier && "unexpected qualifier");
4908
4909 if (!getDerived().AlwaysRebuild() &&
4910 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4911 NewUnderlyingName == UnderlyingName)
4912 return Name;
4913 CXXScopeSpec SS;
4914 SS.Adopt(Other: QualifierLoc);
4915 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4916 NewUnderlyingName);
4917 }
4918
4919 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4920 if (QualifierLoc) {
4921 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4922 QualifierLoc, ObjectType, FirstQualifierInScope);
4923 if (!QualifierLoc)
4924 return TemplateName();
4925 // The qualifier-in-scope and object type only apply to the leftmost
4926 // entity.
4927 ObjectType = QualType();
4928 }
4929
4930 if (!getDerived().AlwaysRebuild() &&
4931 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4932 ObjectType.isNull())
4933 return Name;
4934
4935 CXXScopeSpec SS;
4936 SS.Adopt(Other: QualifierLoc);
4937 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4938 NameLoc, ObjectType,
4939 AllowInjectedClassName);
4940 }
4941
4942 if (SubstTemplateTemplateParmStorage *S =
4943 Name.getAsSubstTemplateTemplateParm()) {
4944 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4945
4946 NestedNameSpecifierLoc ReplacementQualifierLoc;
4947 TemplateName ReplacementName = S->getReplacement();
4948 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4949 NestedNameSpecifierLocBuilder Builder;
4950 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4951 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4952 }
4953
4954 TemplateName NewName = getDerived().TransformTemplateName(
4955 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4956 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4957 if (NewName.isNull())
4958 return TemplateName();
4959 Decl *AssociatedDecl =
4960 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4961 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4962 AssociatedDecl == S->getAssociatedDecl())
4963 return Name;
4964 return SemaRef.Context.getSubstTemplateTemplateParm(
4965 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4966 Final: S->getFinal());
4967 }
4968
4969 assert(!Name.getAsDeducedTemplateName() &&
4970 "DeducedTemplateName should not escape partial ordering");
4971
4972 // FIXME: Preserve UsingTemplateName.
4973 if (auto *Template = Name.getAsTemplateDecl()) {
4974 assert(!QualifierLoc && "Unexpected qualifier");
4975 return TemplateName(cast_or_null<TemplateDecl>(
4976 getDerived().TransformDecl(NameLoc, Template)));
4977 }
4978
4979 if (SubstTemplateTemplateParmPackStorage *SubstPack
4980 = Name.getAsSubstTemplateTemplateParmPack()) {
4981 assert(!QualifierLoc &&
4982 "Unexpected qualified SubstTemplateTemplateParmPack");
4983 return getDerived().RebuildTemplateName(
4984 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4985 SubstPack->getIndex(), SubstPack->getFinal());
4986 }
4987
4988 // These should be getting filtered out before they reach the AST.
4989 llvm_unreachable("overloaded function decl survived to here");
4990}
4991
4992template <typename Derived>
4993TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
4994 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
4995 TemplateName Name, SourceLocation NameLoc) {
4996 TemplateName TN = getDerived().TransformTemplateName(
4997 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
4998 if (TN.isNull())
4999 return TemplateArgument();
5000 return TemplateArgument(TN);
5001}
5002
5003template<typename Derived>
5004void TreeTransform<Derived>::InventTemplateArgumentLoc(
5005 const TemplateArgument &Arg,
5006 TemplateArgumentLoc &Output) {
5007 Output = getSema().getTrivialTemplateArgumentLoc(
5008 Arg, QualType(), getDerived().getBaseLocation());
5009}
5010
5011template <typename Derived>
5012bool TreeTransform<Derived>::TransformTemplateArgument(
5013 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5014 bool Uneval) {
5015 const TemplateArgument &Arg = Input.getArgument();
5016 switch (Arg.getKind()) {
5017 case TemplateArgument::Null:
5018 case TemplateArgument::Pack:
5019 llvm_unreachable("Unexpected TemplateArgument");
5020
5021 case TemplateArgument::Integral:
5022 case TemplateArgument::NullPtr:
5023 case TemplateArgument::Declaration:
5024 case TemplateArgument::StructuralValue: {
5025 // Transform a resolved template argument straight to a resolved template
5026 // argument. We get here when substituting into an already-substituted
5027 // template type argument during concept satisfaction checking.
5028 QualType T = Arg.getNonTypeTemplateArgumentType();
5029 QualType NewT = getDerived().TransformType(T);
5030 if (NewT.isNull())
5031 return true;
5032
5033 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5034 ? Arg.getAsDecl()
5035 : nullptr;
5036 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5037 getDerived().getBaseLocation(), D))
5038 : nullptr;
5039 if (D && !NewD)
5040 return true;
5041
5042 if (NewT == T && D == NewD)
5043 Output = Input;
5044 else if (Arg.getKind() == TemplateArgument::Integral)
5045 Output = TemplateArgumentLoc(
5046 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5047 TemplateArgumentLocInfo());
5048 else if (Arg.getKind() == TemplateArgument::NullPtr)
5049 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5050 TemplateArgumentLocInfo());
5051 else if (Arg.getKind() == TemplateArgument::Declaration)
5052 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5053 TemplateArgumentLocInfo());
5054 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5055 Output = TemplateArgumentLoc(
5056 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5057 TemplateArgumentLocInfo());
5058 else
5059 llvm_unreachable("unexpected template argument kind");
5060
5061 return false;
5062 }
5063
5064 case TemplateArgument::Type: {
5065 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5066 if (!TSI)
5067 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5068
5069 TSI = getDerived().TransformType(TSI);
5070 if (!TSI)
5071 return true;
5072
5073 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5074 return false;
5075 }
5076
5077 case TemplateArgument::Template: {
5078 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5079
5080 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5081 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5082 Input.getTemplateNameLoc());
5083 if (Out.isNull())
5084 return true;
5085 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5086 QualifierLoc, Input.getTemplateNameLoc());
5087 return false;
5088 }
5089
5090 case TemplateArgument::TemplateExpansion:
5091 llvm_unreachable("Caller should expand pack expansions");
5092
5093 case TemplateArgument::Expression: {
5094 // Template argument expressions are constant expressions.
5095 EnterExpressionEvaluationContext Unevaluated(
5096 getSema(),
5097 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5098 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5099 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5100 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5101
5102 Expr *InputExpr = Input.getSourceExpression();
5103 if (!InputExpr)
5104 InputExpr = Input.getArgument().getAsExpr();
5105
5106 ExprResult E = getDerived().TransformExpr(InputExpr);
5107 E = SemaRef.ActOnConstantExpression(Res: E);
5108 if (E.isInvalid())
5109 return true;
5110 Output = TemplateArgumentLoc(
5111 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5112 return false;
5113 }
5114 }
5115
5116 // Work around bogus GCC warning
5117 return true;
5118}
5119
5120/// Iterator adaptor that invents template argument location information
5121/// for each of the template arguments in its underlying iterator.
5122template<typename Derived, typename InputIterator>
5123class TemplateArgumentLocInventIterator {
5124 TreeTransform<Derived> &Self;
5125 InputIterator Iter;
5126
5127public:
5128 typedef TemplateArgumentLoc value_type;
5129 typedef TemplateArgumentLoc reference;
5130 typedef typename std::iterator_traits<InputIterator>::difference_type
5131 difference_type;
5132 typedef std::input_iterator_tag iterator_category;
5133
5134 class pointer {
5135 TemplateArgumentLoc Arg;
5136
5137 public:
5138 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5139
5140 const TemplateArgumentLoc *operator->() const { return &Arg; }
5141 };
5142
5143 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5144 InputIterator Iter)
5145 : Self(Self), Iter(Iter) { }
5146
5147 TemplateArgumentLocInventIterator &operator++() {
5148 ++Iter;
5149 return *this;
5150 }
5151
5152 TemplateArgumentLocInventIterator operator++(int) {
5153 TemplateArgumentLocInventIterator Old(*this);
5154 ++(*this);
5155 return Old;
5156 }
5157
5158 reference operator*() const {
5159 TemplateArgumentLoc Result;
5160 Self.InventTemplateArgumentLoc(*Iter, Result);
5161 return Result;
5162 }
5163
5164 pointer operator->() const { return pointer(**this); }
5165
5166 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5167 const TemplateArgumentLocInventIterator &Y) {
5168 return X.Iter == Y.Iter;
5169 }
5170
5171 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5172 const TemplateArgumentLocInventIterator &Y) {
5173 return X.Iter != Y.Iter;
5174 }
5175};
5176
5177template<typename Derived>
5178template<typename InputIterator>
5179bool TreeTransform<Derived>::TransformTemplateArguments(
5180 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5181 bool Uneval) {
5182 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5183 TemplateArgumentLoc Out;
5184 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5185 // Unpack argument packs, which we translate them into separate
5186 // arguments.
5187 // FIXME: We could do much better if we could guarantee that the
5188 // TemplateArgumentLocInfo for the pack expansion would be usable for
5189 // all of the template arguments in the argument pack.
5190 typedef TemplateArgumentLocInventIterator<Derived,
5191 TemplateArgument::pack_iterator>
5192 PackLocIterator;
5193
5194 TemplateArgumentListInfo *PackOutput = &Outputs;
5195 TemplateArgumentListInfo New;
5196
5197 if (TransformTemplateArguments(
5198 PackLocIterator(*this, In.getArgument().pack_begin()),
5199 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5200 Uneval))
5201 return true;
5202
5203 continue;
5204 }
5205
5206 if (In.getArgument().isPackExpansion()) {
5207 UnexpandedInfo Info;
5208 TemplateArgumentLoc Prepared;
5209 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5210 return true;
5211 if (!Info.Expand) {
5212 Outputs.addArgument(Loc: Prepared);
5213 continue;
5214 }
5215
5216 // The transform has determined that we should perform an elementwise
5217 // expansion of the pattern. Do so.
5218 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5219 if (Info.ExpandUnderForgetSubstitions)
5220 ForgetSubst.emplace(getDerived());
5221 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5222 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5223
5224 TemplateArgumentLoc Out;
5225 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5226 return true;
5227
5228 if (Out.getArgument().containsUnexpandedParameterPack()) {
5229 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5230 Info.OrigNumExpansions);
5231 if (Out.getArgument().isNull())
5232 return true;
5233 }
5234
5235 Outputs.addArgument(Loc: Out);
5236 }
5237
5238 // If we're supposed to retain a pack expansion, do so by temporarily
5239 // forgetting the partially-substituted parameter pack.
5240 if (Info.RetainExpansion) {
5241 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5242
5243 TemplateArgumentLoc Out;
5244 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5245 return true;
5246
5247 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5248 Info.OrigNumExpansions);
5249 if (Out.getArgument().isNull())
5250 return true;
5251
5252 Outputs.addArgument(Loc: Out);
5253 }
5254
5255 continue;
5256 }
5257
5258 // The simple case:
5259 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5260 return true;
5261
5262 Outputs.addArgument(Loc: Out);
5263 }
5264
5265 return false;
5266}
5267
5268template <typename Derived>
5269template <typename InputIterator>
5270bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5271 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5272 bool Uneval) {
5273
5274 // [C++26][temp.constr.normal]
5275 // any non-dependent concept template argument
5276 // is substituted into the constraint-expression of C.
5277 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5278 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5279 };
5280
5281 for (; First != Last; ++First) {
5282 TemplateArgumentLoc Out;
5283 TemplateArgumentLoc In = *First;
5284
5285 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5286 typedef TemplateArgumentLocInventIterator<Derived,
5287 TemplateArgument::pack_iterator>
5288 PackLocIterator;
5289 if (TransformConceptTemplateArguments(
5290 PackLocIterator(*this, In.getArgument().pack_begin()),
5291 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5292 Uneval))
5293 return true;
5294 continue;
5295 }
5296
5297 if (!isNonDependentConceptArgument(In.getArgument())) {
5298 Outputs.addArgument(Loc: In);
5299 continue;
5300 }
5301
5302 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5303 return true;
5304
5305 Outputs.addArgument(Loc: Out);
5306 }
5307
5308 return false;
5309}
5310
5311// FIXME: Find ways to reduce code duplication for pack expansions.
5312template <typename Derived>
5313bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5314 bool Uneval,
5315 TemplateArgumentLoc &Out,
5316 UnexpandedInfo &Info) {
5317 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5318 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5319 TemplateArgumentLoc &Pattern) {
5320 assert(Arg.getArgument().isPackExpansion());
5321 // We have a pack expansion, for which we will be substituting into the
5322 // pattern.
5323 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5324 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5325 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5326 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5327 if (IsLateExpansionAttempt) {
5328 // Request expansion only when there is an opportunity to expand a pack
5329 // that required a substituion first.
5330 bool SawPackTypes =
5331 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5332 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5333 });
5334 if (!SawPackTypes) {
5335 Info.Expand = false;
5336 return false;
5337 }
5338 }
5339 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5340
5341 // Determine whether the set of unexpanded parameter packs can and
5342 // should be expanded.
5343 Info.Expand = true;
5344 Info.RetainExpansion = false;
5345 Info.NumExpansions = Info.OrigNumExpansions;
5346 return getDerived().TryExpandParameterPacks(
5347 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5348 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5349 Info.RetainExpansion, Info.NumExpansions);
5350 };
5351
5352 TemplateArgumentLoc Pattern;
5353 if (ComputeInfo(In, false, Info, Pattern))
5354 return true;
5355
5356 if (Info.Expand) {
5357 Out = Pattern;
5358 return false;
5359 }
5360
5361 // The transform has determined that we should perform a simple
5362 // transformation on the pack expansion, producing another pack
5363 // expansion.
5364 TemplateArgumentLoc OutPattern;
5365 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5366 std::in_place, getSema(), std::nullopt);
5367 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5368 return true;
5369
5370 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5371 Info.NumExpansions);
5372 if (Out.getArgument().isNull())
5373 return true;
5374 SubstIndex.reset();
5375
5376 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5377 return false;
5378
5379 // Some packs will learn their length after substitution, e.g.
5380 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5381 // value of `T`.
5382 //
5383 // We only expand after we know sizes of all packs, check if this is the case
5384 // or not. However, we avoid a full template substitution and only do
5385 // expanstions after this point.
5386
5387 // E.g. when substituting template arguments of tuple with {T -> int} in the
5388 // following example:
5389 // template <class T>
5390 // struct TupleWithInt {
5391 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5392 // };
5393 // TupleWithInt<int>::type y;
5394 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5395 // length and run `ComputeInfo()` to provide the necessary information to our
5396 // caller.
5397 //
5398 // Note that we may still have situations where builtin is not going to be
5399 // expanded. For example:
5400 // template <class T>
5401 // struct Foo {
5402 // template <class U> using tuple_with_t =
5403 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5404 // tuple_with_t<short>;
5405 // }
5406 // Because the substitution into `type` happens in dependent context, `type`
5407 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5408 // and the caller will not be able to expand it.
5409 ForgetSubstitutionRAII ForgetSubst(getDerived());
5410 if (ComputeInfo(Out, true, Info, OutPattern))
5411 return true;
5412 if (!Info.Expand)
5413 return false;
5414 Out = OutPattern;
5415 Info.ExpandUnderForgetSubstitions = true;
5416 return false;
5417}
5418
5419//===----------------------------------------------------------------------===//
5420// Type transformation
5421//===----------------------------------------------------------------------===//
5422
5423template<typename Derived>
5424QualType TreeTransform<Derived>::TransformType(QualType T) {
5425 if (getDerived().AlreadyTransformed(T))
5426 return T;
5427
5428 // Temporary workaround. All of these transformations should
5429 // eventually turn into transformations on TypeLocs.
5430 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5431 T, getDerived().getBaseLocation());
5432
5433 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5434
5435 if (!NewTSI)
5436 return QualType();
5437
5438 return NewTSI->getType();
5439}
5440
5441template <typename Derived>
5442TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5443 // Refine the base location to the type's location.
5444 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5445 getDerived().getBaseEntity());
5446 if (getDerived().AlreadyTransformed(TSI->getType()))
5447 return TSI;
5448
5449 TypeLocBuilder TLB;
5450
5451 TypeLoc TL = TSI->getTypeLoc();
5452 TLB.reserve(Requested: TL.getFullDataSize());
5453
5454 QualType Result = getDerived().TransformType(TLB, TL);
5455 if (Result.isNull())
5456 return nullptr;
5457
5458 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5459}
5460
5461template<typename Derived>
5462QualType
5463TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5464 switch (T.getTypeLocClass()) {
5465#define ABSTRACT_TYPELOC(CLASS, PARENT)
5466#define TYPELOC(CLASS, PARENT) \
5467 case TypeLoc::CLASS: \
5468 return getDerived().Transform##CLASS##Type(TLB, \
5469 T.castAs<CLASS##TypeLoc>());
5470#include "clang/AST/TypeLocNodes.def"
5471 }
5472
5473 llvm_unreachable("unhandled type loc!");
5474}
5475
5476template<typename Derived>
5477QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5478 if (!isa<DependentNameType>(Val: T))
5479 return TransformType(T);
5480
5481 if (getDerived().AlreadyTransformed(T))
5482 return T;
5483 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5484 T, getDerived().getBaseLocation());
5485 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5486 return NewTSI ? NewTSI->getType() : QualType();
5487}
5488
5489template <typename Derived>
5490TypeSourceInfo *
5491TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5492 if (!isa<DependentNameType>(Val: TSI->getType()))
5493 return TransformType(TSI);
5494
5495 // Refine the base location to the type's location.
5496 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5497 getDerived().getBaseEntity());
5498 if (getDerived().AlreadyTransformed(TSI->getType()))
5499 return TSI;
5500
5501 TypeLocBuilder TLB;
5502
5503 TypeLoc TL = TSI->getTypeLoc();
5504 TLB.reserve(Requested: TL.getFullDataSize());
5505
5506 auto QTL = TL.getAs<QualifiedTypeLoc>();
5507 if (QTL)
5508 TL = QTL.getUnqualifiedLoc();
5509
5510 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5511
5512 QualType Result = getDerived().TransformDependentNameType(
5513 TLB, DNTL, /*DeducedTSTContext*/true);
5514 if (Result.isNull())
5515 return nullptr;
5516
5517 if (QTL) {
5518 Result = getDerived().RebuildQualifiedType(Result, QTL);
5519 if (Result.isNull())
5520 return nullptr;
5521 TLB.TypeWasModifiedSafely(T: Result);
5522 }
5523
5524 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5525}
5526
5527template<typename Derived>
5528QualType
5529TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5530 QualifiedTypeLoc T) {
5531 QualType Result;
5532 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5533 auto SuppressObjCLifetime =
5534 T.getType().getLocalQualifiers().hasObjCLifetime();
5535 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5536 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5537 SuppressObjCLifetime);
5538 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5539 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5540 TLB, STTP, SuppressObjCLifetime);
5541 } else {
5542 Result = getDerived().TransformType(TLB, UnqualTL);
5543 }
5544
5545 if (Result.isNull())
5546 return QualType();
5547
5548 Result = getDerived().RebuildQualifiedType(Result, T);
5549
5550 if (Result.isNull())
5551 return QualType();
5552
5553 // RebuildQualifiedType might have updated the type, but not in a way
5554 // that invalidates the TypeLoc. (There's no location information for
5555 // qualifiers.)
5556 TLB.TypeWasModifiedSafely(T: Result);
5557
5558 return Result;
5559}
5560
5561template <typename Derived>
5562QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5563 QualifiedTypeLoc TL) {
5564
5565 SourceLocation Loc = TL.getBeginLoc();
5566 Qualifiers Quals = TL.getType().getLocalQualifiers();
5567
5568 if ((T.getAddressSpace() != LangAS::Default &&
5569 Quals.getAddressSpace() != LangAS::Default) &&
5570 T.getAddressSpace() != Quals.getAddressSpace()) {
5571 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5572 << TL.getType() << T;
5573 return QualType();
5574 }
5575
5576 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5577 if (LocalPointerAuth.isPresent()) {
5578 if (T.getPointerAuth().isPresent()) {
5579 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5580 return QualType();
5581 }
5582 if (!T->isDependentType()) {
5583 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5584 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5585 return QualType();
5586 }
5587 }
5588 }
5589 // C++ [dcl.fct]p7:
5590 // [When] adding cv-qualifications on top of the function type [...] the
5591 // cv-qualifiers are ignored.
5592 if (T->isFunctionType()) {
5593 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5594 AddressSpace: Quals.getAddressSpace());
5595 return T;
5596 }
5597
5598 // C++ [dcl.ref]p1:
5599 // when the cv-qualifiers are introduced through the use of a typedef-name
5600 // or decltype-specifier [...] the cv-qualifiers are ignored.
5601 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5602 // applied to a reference type.
5603 if (T->isReferenceType()) {
5604 // The only qualifier that applies to a reference type is restrict.
5605 if (!Quals.hasRestrict())
5606 return T;
5607 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5608 }
5609
5610 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5611 // resulting type.
5612 if (Quals.hasObjCLifetime()) {
5613 if (!T->isObjCLifetimeType() && !T->isDependentType())
5614 Quals.removeObjCLifetime();
5615 else if (T.getObjCLifetime()) {
5616 // Objective-C ARC:
5617 // A lifetime qualifier applied to a substituted template parameter
5618 // overrides the lifetime qualifier from the template argument.
5619 const AutoType *AutoTy;
5620 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5621 // 'auto' types behave the same way as template parameters.
5622 QualType Deduced = AutoTy->getDeducedType();
5623 Qualifiers Qs = Deduced.getQualifiers();
5624 Qs.removeObjCLifetime();
5625 Deduced =
5626 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5627 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5628 Keyword: AutoTy->getKeyword(),
5629 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5630 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5631 } else {
5632 // Otherwise, complain about the addition of a qualifier to an
5633 // already-qualified type.
5634 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5635 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5636 Quals.removeObjCLifetime();
5637 }
5638 }
5639 }
5640
5641 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5642}
5643
5644template <typename Derived>
5645QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5646 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5647 NamedDecl *FirstQualifierInScope) {
5648 assert(!getDerived().AlreadyTransformed(TL.getType()));
5649
5650 switch (TL.getTypeLocClass()) {
5651 case TypeLoc::TemplateSpecialization:
5652 return getDerived().TransformTemplateSpecializationType(
5653 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5654 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5655 case TypeLoc::DependentName:
5656 return getDerived().TransformDependentNameType(
5657 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5658 ObjectType, FirstQualifierInScope);
5659 default:
5660 // Any dependent canonical type can appear here, through type alias
5661 // templates.
5662 return getDerived().TransformType(TLB, TL);
5663 }
5664}
5665
5666template <class TyLoc> static inline
5667QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5668 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5669 NewT.setNameLoc(T.getNameLoc());
5670 return T.getType();
5671}
5672
5673template<typename Derived>
5674QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5675 BuiltinTypeLoc T) {
5676 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5677 NewT.setBuiltinLoc(T.getBuiltinLoc());
5678 if (T.needsExtraLocalData())
5679 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5680 return T.getType();
5681}
5682
5683template<typename Derived>
5684QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5685 ComplexTypeLoc T) {
5686 // FIXME: recurse?
5687 return TransformTypeSpecType(TLB, T);
5688}
5689
5690template <typename Derived>
5691QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5692 AdjustedTypeLoc TL) {
5693 // Adjustments applied during transformation are handled elsewhere.
5694 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5695}
5696
5697template<typename Derived>
5698QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5699 DecayedTypeLoc TL) {
5700 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5701 if (OriginalType.isNull())
5702 return QualType();
5703
5704 QualType Result = TL.getType();
5705 if (getDerived().AlwaysRebuild() ||
5706 OriginalType != TL.getOriginalLoc().getType())
5707 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5708 TLB.push<DecayedTypeLoc>(T: Result);
5709 // Nothing to set for DecayedTypeLoc.
5710 return Result;
5711}
5712
5713template <typename Derived>
5714QualType
5715TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5716 ArrayParameterTypeLoc TL) {
5717 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5718 if (OriginalType.isNull())
5719 return QualType();
5720
5721 QualType Result = TL.getType();
5722 if (getDerived().AlwaysRebuild() ||
5723 OriginalType != TL.getElementLoc().getType())
5724 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5725 TLB.push<ArrayParameterTypeLoc>(T: Result);
5726 // Nothing to set for ArrayParameterTypeLoc.
5727 return Result;
5728}
5729
5730template<typename Derived>
5731QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5732 PointerTypeLoc TL) {
5733 QualType PointeeType
5734 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5735 if (PointeeType.isNull())
5736 return QualType();
5737
5738 QualType Result = TL.getType();
5739 if (PointeeType->getAs<ObjCObjectType>()) {
5740 // A dependent pointer type 'T *' has is being transformed such
5741 // that an Objective-C class type is being replaced for 'T'. The
5742 // resulting pointer type is an ObjCObjectPointerType, not a
5743 // PointerType.
5744 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5745
5746 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5747 NewT.setStarLoc(TL.getStarLoc());
5748 return Result;
5749 }
5750
5751 if (getDerived().AlwaysRebuild() ||
5752 PointeeType != TL.getPointeeLoc().getType()) {
5753 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5754 if (Result.isNull())
5755 return QualType();
5756 }
5757
5758 // Objective-C ARC can add lifetime qualifiers to the type that we're
5759 // pointing to.
5760 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5761
5762 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5763 NewT.setSigilLoc(TL.getSigilLoc());
5764 return Result;
5765}
5766
5767template<typename Derived>
5768QualType
5769TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5770 BlockPointerTypeLoc TL) {
5771 QualType PointeeType
5772 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5773 if (PointeeType.isNull())
5774 return QualType();
5775
5776 QualType Result = TL.getType();
5777 if (getDerived().AlwaysRebuild() ||
5778 PointeeType != TL.getPointeeLoc().getType()) {
5779 Result = getDerived().RebuildBlockPointerType(PointeeType,
5780 TL.getSigilLoc());
5781 if (Result.isNull())
5782 return QualType();
5783 }
5784
5785 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5786 NewT.setSigilLoc(TL.getSigilLoc());
5787 return Result;
5788}
5789
5790/// Transforms a reference type. Note that somewhat paradoxically we
5791/// don't care whether the type itself is an l-value type or an r-value
5792/// type; we only care if the type was *written* as an l-value type
5793/// or an r-value type.
5794template<typename Derived>
5795QualType
5796TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5797 ReferenceTypeLoc TL) {
5798 const ReferenceType *T = TL.getTypePtr();
5799
5800 // Note that this works with the pointee-as-written.
5801 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5802 if (PointeeType.isNull())
5803 return QualType();
5804
5805 QualType Result = TL.getType();
5806 if (getDerived().AlwaysRebuild() ||
5807 PointeeType != T->getPointeeTypeAsWritten()) {
5808 Result = getDerived().RebuildReferenceType(PointeeType,
5809 T->isSpelledAsLValue(),
5810 TL.getSigilLoc());
5811 if (Result.isNull())
5812 return QualType();
5813 }
5814
5815 // Objective-C ARC can add lifetime qualifiers to the type that we're
5816 // referring to.
5817 TLB.TypeWasModifiedSafely(
5818 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5819
5820 // r-value references can be rebuilt as l-value references.
5821 ReferenceTypeLoc NewTL;
5822 if (isa<LValueReferenceType>(Val: Result))
5823 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5824 else
5825 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5826 NewTL.setSigilLoc(TL.getSigilLoc());
5827
5828 return Result;
5829}
5830
5831template<typename Derived>
5832QualType
5833TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5834 LValueReferenceTypeLoc TL) {
5835 return TransformReferenceType(TLB, TL);
5836}
5837
5838template<typename Derived>
5839QualType
5840TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5841 RValueReferenceTypeLoc TL) {
5842 return TransformReferenceType(TLB, TL);
5843}
5844
5845template<typename Derived>
5846QualType
5847TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5848 MemberPointerTypeLoc TL) {
5849 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5850 if (PointeeType.isNull())
5851 return QualType();
5852
5853 const MemberPointerType *T = TL.getTypePtr();
5854
5855 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5856 NestedNameSpecifierLoc NewQualifierLoc =
5857 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5858 if (!NewQualifierLoc)
5859 return QualType();
5860
5861 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5862 if (OldCls) {
5863 NewCls = cast_or_null<CXXRecordDecl>(
5864 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5865 if (!NewCls)
5866 return QualType();
5867 }
5868
5869 QualType Result = TL.getType();
5870 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5871 NewQualifierLoc.getNestedNameSpecifier() !=
5872 OldQualifierLoc.getNestedNameSpecifier() ||
5873 NewCls != OldCls) {
5874 CXXScopeSpec SS;
5875 SS.Adopt(Other: NewQualifierLoc);
5876 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5877 TL.getStarLoc());
5878 if (Result.isNull())
5879 return QualType();
5880 }
5881
5882 // If we had to adjust the pointee type when building a member pointer, make
5883 // sure to push TypeLoc info for it.
5884 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5885 if (MPT && PointeeType != MPT->getPointeeType()) {
5886 assert(isa<AdjustedType>(MPT->getPointeeType()));
5887 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5888 }
5889
5890 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5891 NewTL.setSigilLoc(TL.getSigilLoc());
5892 NewTL.setQualifierLoc(NewQualifierLoc);
5893
5894 return Result;
5895}
5896
5897template<typename Derived>
5898QualType
5899TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5900 ConstantArrayTypeLoc TL) {
5901 const ConstantArrayType *T = TL.getTypePtr();
5902 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5903 if (ElementType.isNull())
5904 return QualType();
5905
5906 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5907 Expr *OldSize = TL.getSizeExpr();
5908 if (!OldSize)
5909 OldSize = const_cast<Expr*>(T->getSizeExpr());
5910 Expr *NewSize = nullptr;
5911 if (OldSize) {
5912 EnterExpressionEvaluationContext Unevaluated(
5913 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5914 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5915 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5916 }
5917
5918 QualType Result = TL.getType();
5919 if (getDerived().AlwaysRebuild() ||
5920 ElementType != T->getElementType() ||
5921 (T->getSizeExpr() && NewSize != OldSize)) {
5922 Result = getDerived().RebuildConstantArrayType(ElementType,
5923 T->getSizeModifier(),
5924 T->getSize(), NewSize,
5925 T->getIndexTypeCVRQualifiers(),
5926 TL.getBracketsRange());
5927 if (Result.isNull())
5928 return QualType();
5929 }
5930
5931 // We might have either a ConstantArrayType or a VariableArrayType now:
5932 // a ConstantArrayType is allowed to have an element type which is a
5933 // VariableArrayType if the type is dependent. Fortunately, all array
5934 // types have the same location layout.
5935 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5936 NewTL.setLBracketLoc(TL.getLBracketLoc());
5937 NewTL.setRBracketLoc(TL.getRBracketLoc());
5938 NewTL.setSizeExpr(NewSize);
5939
5940 return Result;
5941}
5942
5943template<typename Derived>
5944QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5945 TypeLocBuilder &TLB,
5946 IncompleteArrayTypeLoc TL) {
5947 const IncompleteArrayType *T = TL.getTypePtr();
5948 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5949 if (ElementType.isNull())
5950 return QualType();
5951
5952 QualType Result = TL.getType();
5953 if (getDerived().AlwaysRebuild() ||
5954 ElementType != T->getElementType()) {
5955 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5956 T->getSizeModifier(),
5957 T->getIndexTypeCVRQualifiers(),
5958 TL.getBracketsRange());
5959 if (Result.isNull())
5960 return QualType();
5961 }
5962
5963 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5964 NewTL.setLBracketLoc(TL.getLBracketLoc());
5965 NewTL.setRBracketLoc(TL.getRBracketLoc());
5966 NewTL.setSizeExpr(nullptr);
5967
5968 return Result;
5969}
5970
5971template<typename Derived>
5972QualType
5973TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5974 VariableArrayTypeLoc TL) {
5975 const VariableArrayType *T = TL.getTypePtr();
5976 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5977 if (ElementType.isNull())
5978 return QualType();
5979
5980 ExprResult SizeResult;
5981 {
5982 EnterExpressionEvaluationContext Context(
5983 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5984 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5985 }
5986 if (SizeResult.isInvalid())
5987 return QualType();
5988 SizeResult =
5989 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5990 if (SizeResult.isInvalid())
5991 return QualType();
5992
5993 Expr *Size = SizeResult.get();
5994
5995 QualType Result = TL.getType();
5996 if (getDerived().AlwaysRebuild() ||
5997 ElementType != T->getElementType() ||
5998 Size != T->getSizeExpr()) {
5999 Result = getDerived().RebuildVariableArrayType(ElementType,
6000 T->getSizeModifier(),
6001 Size,
6002 T->getIndexTypeCVRQualifiers(),
6003 TL.getBracketsRange());
6004 if (Result.isNull())
6005 return QualType();
6006 }
6007
6008 // We might have constant size array now, but fortunately it has the same
6009 // location layout.
6010 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6011 NewTL.setLBracketLoc(TL.getLBracketLoc());
6012 NewTL.setRBracketLoc(TL.getRBracketLoc());
6013 NewTL.setSizeExpr(Size);
6014
6015 return Result;
6016}
6017
6018template<typename Derived>
6019QualType
6020TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6021 DependentSizedArrayTypeLoc TL) {
6022 const DependentSizedArrayType *T = TL.getTypePtr();
6023 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6024 if (ElementType.isNull())
6025 return QualType();
6026
6027 // Array bounds are constant expressions.
6028 EnterExpressionEvaluationContext Unevaluated(
6029 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6030
6031 // If we have a VLA then it won't be a constant.
6032 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6033
6034 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6035 Expr *origSize = TL.getSizeExpr();
6036 if (!origSize) origSize = T->getSizeExpr();
6037
6038 ExprResult sizeResult
6039 = getDerived().TransformExpr(origSize);
6040 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6041 if (sizeResult.isInvalid())
6042 return QualType();
6043
6044 Expr *size = sizeResult.get();
6045
6046 QualType Result = TL.getType();
6047 if (getDerived().AlwaysRebuild() ||
6048 ElementType != T->getElementType() ||
6049 size != origSize) {
6050 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6051 T->getSizeModifier(),
6052 size,
6053 T->getIndexTypeCVRQualifiers(),
6054 TL.getBracketsRange());
6055 if (Result.isNull())
6056 return QualType();
6057 }
6058
6059 // We might have any sort of array type now, but fortunately they
6060 // all have the same location layout.
6061 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6062 NewTL.setLBracketLoc(TL.getLBracketLoc());
6063 NewTL.setRBracketLoc(TL.getRBracketLoc());
6064 NewTL.setSizeExpr(size);
6065
6066 return Result;
6067}
6068
6069template <typename Derived>
6070QualType TreeTransform<Derived>::TransformDependentVectorType(
6071 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6072 const DependentVectorType *T = TL.getTypePtr();
6073 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6074 if (ElementType.isNull())
6075 return QualType();
6076
6077 EnterExpressionEvaluationContext Unevaluated(
6078 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6079
6080 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6081 Size = SemaRef.ActOnConstantExpression(Res: Size);
6082 if (Size.isInvalid())
6083 return QualType();
6084
6085 QualType Result = TL.getType();
6086 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6087 Size.get() != T->getSizeExpr()) {
6088 Result = getDerived().RebuildDependentVectorType(
6089 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6090 if (Result.isNull())
6091 return QualType();
6092 }
6093
6094 // Result might be dependent or not.
6095 if (isa<DependentVectorType>(Val: Result)) {
6096 DependentVectorTypeLoc NewTL =
6097 TLB.push<DependentVectorTypeLoc>(T: Result);
6098 NewTL.setNameLoc(TL.getNameLoc());
6099 } else {
6100 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6101 NewTL.setNameLoc(TL.getNameLoc());
6102 }
6103
6104 return Result;
6105}
6106
6107template<typename Derived>
6108QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6109 TypeLocBuilder &TLB,
6110 DependentSizedExtVectorTypeLoc TL) {
6111 const DependentSizedExtVectorType *T = TL.getTypePtr();
6112
6113 // FIXME: ext vector locs should be nested
6114 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6115 if (ElementType.isNull())
6116 return QualType();
6117
6118 // Vector sizes are constant expressions.
6119 EnterExpressionEvaluationContext Unevaluated(
6120 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6121
6122 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6123 Size = SemaRef.ActOnConstantExpression(Res: Size);
6124 if (Size.isInvalid())
6125 return QualType();
6126
6127 QualType Result = TL.getType();
6128 if (getDerived().AlwaysRebuild() ||
6129 ElementType != T->getElementType() ||
6130 Size.get() != T->getSizeExpr()) {
6131 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6132 Size.get(),
6133 T->getAttributeLoc());
6134 if (Result.isNull())
6135 return QualType();
6136 }
6137
6138 // Result might be dependent or not.
6139 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6140 DependentSizedExtVectorTypeLoc NewTL
6141 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6142 NewTL.setNameLoc(TL.getNameLoc());
6143 } else {
6144 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6145 NewTL.setNameLoc(TL.getNameLoc());
6146 }
6147
6148 return Result;
6149}
6150
6151template <typename Derived>
6152QualType
6153TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6154 ConstantMatrixTypeLoc TL) {
6155 const ConstantMatrixType *T = TL.getTypePtr();
6156 QualType ElementType = getDerived().TransformType(T->getElementType());
6157 if (ElementType.isNull())
6158 return QualType();
6159
6160 QualType Result = TL.getType();
6161 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6162 Result = getDerived().RebuildConstantMatrixType(
6163 ElementType, T->getNumRows(), T->getNumColumns());
6164 if (Result.isNull())
6165 return QualType();
6166 }
6167
6168 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6169 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6170 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6171 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6172 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6173
6174 return Result;
6175}
6176
6177template <typename Derived>
6178QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6179 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6180 const DependentSizedMatrixType *T = TL.getTypePtr();
6181
6182 QualType ElementType = getDerived().TransformType(T->getElementType());
6183 if (ElementType.isNull()) {
6184 return QualType();
6185 }
6186
6187 // Matrix dimensions are constant expressions.
6188 EnterExpressionEvaluationContext Unevaluated(
6189 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6190
6191 Expr *origRows = TL.getAttrRowOperand();
6192 if (!origRows)
6193 origRows = T->getRowExpr();
6194 Expr *origColumns = TL.getAttrColumnOperand();
6195 if (!origColumns)
6196 origColumns = T->getColumnExpr();
6197
6198 ExprResult rowResult = getDerived().TransformExpr(origRows);
6199 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6200 if (rowResult.isInvalid())
6201 return QualType();
6202
6203 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6204 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6205 if (columnResult.isInvalid())
6206 return QualType();
6207
6208 Expr *rows = rowResult.get();
6209 Expr *columns = columnResult.get();
6210
6211 QualType Result = TL.getType();
6212 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6213 rows != origRows || columns != origColumns) {
6214 Result = getDerived().RebuildDependentSizedMatrixType(
6215 ElementType, rows, columns, T->getAttributeLoc());
6216
6217 if (Result.isNull())
6218 return QualType();
6219 }
6220
6221 // We might have any sort of matrix type now, but fortunately they
6222 // all have the same location layout.
6223 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6224 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6225 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6226 NewTL.setAttrRowOperand(rows);
6227 NewTL.setAttrColumnOperand(columns);
6228 return Result;
6229}
6230
6231template <typename Derived>
6232QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6233 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6234 const DependentAddressSpaceType *T = TL.getTypePtr();
6235
6236 QualType pointeeType =
6237 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6238
6239 if (pointeeType.isNull())
6240 return QualType();
6241
6242 // Address spaces are constant expressions.
6243 EnterExpressionEvaluationContext Unevaluated(
6244 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6245
6246 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6247 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6248 if (AddrSpace.isInvalid())
6249 return QualType();
6250
6251 QualType Result = TL.getType();
6252 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6253 AddrSpace.get() != T->getAddrSpaceExpr()) {
6254 Result = getDerived().RebuildDependentAddressSpaceType(
6255 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6256 if (Result.isNull())
6257 return QualType();
6258 }
6259
6260 // Result might be dependent or not.
6261 if (isa<DependentAddressSpaceType>(Val: Result)) {
6262 DependentAddressSpaceTypeLoc NewTL =
6263 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6264
6265 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6266 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6267 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6268
6269 } else {
6270 TLB.TypeWasModifiedSafely(T: Result);
6271 }
6272
6273 return Result;
6274}
6275
6276template <typename Derived>
6277QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6278 VectorTypeLoc TL) {
6279 const VectorType *T = TL.getTypePtr();
6280 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6281 if (ElementType.isNull())
6282 return QualType();
6283
6284 QualType Result = TL.getType();
6285 if (getDerived().AlwaysRebuild() ||
6286 ElementType != T->getElementType()) {
6287 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6288 T->getVectorKind());
6289 if (Result.isNull())
6290 return QualType();
6291 }
6292
6293 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6294 NewTL.setNameLoc(TL.getNameLoc());
6295
6296 return Result;
6297}
6298
6299template<typename Derived>
6300QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6301 ExtVectorTypeLoc TL) {
6302 const VectorType *T = TL.getTypePtr();
6303 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6304 if (ElementType.isNull())
6305 return QualType();
6306
6307 QualType Result = TL.getType();
6308 if (getDerived().AlwaysRebuild() ||
6309 ElementType != T->getElementType()) {
6310 Result = getDerived().RebuildExtVectorType(ElementType,
6311 T->getNumElements(),
6312 /*FIXME*/ SourceLocation());
6313 if (Result.isNull())
6314 return QualType();
6315 }
6316
6317 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6318 NewTL.setNameLoc(TL.getNameLoc());
6319
6320 return Result;
6321}
6322
6323template <typename Derived>
6324ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6325 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6326 bool ExpectParameterPack) {
6327 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6328 TypeSourceInfo *NewTSI = nullptr;
6329
6330 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6331 // If we're substituting into a pack expansion type and we know the
6332 // length we want to expand to, just substitute for the pattern.
6333 TypeLoc OldTL = OldTSI->getTypeLoc();
6334 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6335
6336 TypeLocBuilder TLB;
6337 TypeLoc NewTL = OldTSI->getTypeLoc();
6338 TLB.reserve(Requested: NewTL.getFullDataSize());
6339
6340 QualType Result = getDerived().TransformType(TLB,
6341 OldExpansionTL.getPatternLoc());
6342 if (Result.isNull())
6343 return nullptr;
6344
6345 Result = RebuildPackExpansionType(Pattern: Result,
6346 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6347 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6348 NumExpansions);
6349 if (Result.isNull())
6350 return nullptr;
6351
6352 PackExpansionTypeLoc NewExpansionTL
6353 = TLB.push<PackExpansionTypeLoc>(T: Result);
6354 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6355 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6356 } else
6357 NewTSI = getDerived().TransformType(OldTSI);
6358 if (!NewTSI)
6359 return nullptr;
6360
6361 if (NewTSI == OldTSI && indexAdjustment == 0)
6362 return OldParm;
6363
6364 ParmVarDecl *newParm = ParmVarDecl::Create(
6365 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6366 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6367 TInfo: NewTSI, S: OldParm->getStorageClass(),
6368 /* DefArg */ DefArg: nullptr);
6369 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6370 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6371 getDerived().transformedLocalDecl(OldParm, {newParm});
6372 return newParm;
6373}
6374
6375template <typename Derived>
6376bool TreeTransform<Derived>::TransformFunctionTypeParams(
6377 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6378 const QualType *ParamTypes,
6379 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6380 SmallVectorImpl<QualType> &OutParamTypes,
6381 SmallVectorImpl<ParmVarDecl *> *PVars,
6382 Sema::ExtParameterInfoBuilder &PInfos,
6383 unsigned *LastParamTransformed) {
6384 int indexAdjustment = 0;
6385
6386 unsigned NumParams = Params.size();
6387 for (unsigned i = 0; i != NumParams; ++i) {
6388 if (LastParamTransformed)
6389 *LastParamTransformed = i;
6390 if (ParmVarDecl *OldParm = Params[i]) {
6391 assert(OldParm->getFunctionScopeIndex() == i);
6392
6393 UnsignedOrNone NumExpansions = std::nullopt;
6394 ParmVarDecl *NewParm = nullptr;
6395 if (OldParm->isParameterPack()) {
6396 // We have a function parameter pack that may need to be expanded.
6397 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6398
6399 // Find the parameter packs that could be expanded.
6400 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6401 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6402 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6403 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6404
6405 // Determine whether we should expand the parameter packs.
6406 bool ShouldExpand = false;
6407 bool RetainExpansion = false;
6408 UnsignedOrNone OrigNumExpansions = std::nullopt;
6409 if (Unexpanded.size() > 0) {
6410 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6411 NumExpansions = OrigNumExpansions;
6412 if (getDerived().TryExpandParameterPacks(
6413 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6414 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6415 ShouldExpand, RetainExpansion, NumExpansions)) {
6416 return true;
6417 }
6418 } else {
6419#ifndef NDEBUG
6420 const AutoType *AT =
6421 Pattern.getType().getTypePtr()->getContainedAutoType();
6422 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6423 "Could not find parameter packs or undeduced auto type!");
6424#endif
6425 }
6426
6427 if (ShouldExpand) {
6428 // Expand the function parameter pack into multiple, separate
6429 // parameters.
6430 getDerived().ExpandingFunctionParameterPack(OldParm);
6431 for (unsigned I = 0; I != *NumExpansions; ++I) {
6432 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6433 ParmVarDecl *NewParm
6434 = getDerived().TransformFunctionTypeParam(OldParm,
6435 indexAdjustment++,
6436 OrigNumExpansions,
6437 /*ExpectParameterPack=*/false);
6438 if (!NewParm)
6439 return true;
6440
6441 if (ParamInfos)
6442 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6443 OutParamTypes.push_back(Elt: NewParm->getType());
6444 if (PVars)
6445 PVars->push_back(Elt: NewParm);
6446 }
6447
6448 // If we're supposed to retain a pack expansion, do so by temporarily
6449 // forgetting the partially-substituted parameter pack.
6450 if (RetainExpansion) {
6451 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6452 ParmVarDecl *NewParm
6453 = getDerived().TransformFunctionTypeParam(OldParm,
6454 indexAdjustment++,
6455 OrigNumExpansions,
6456 /*ExpectParameterPack=*/false);
6457 if (!NewParm)
6458 return true;
6459
6460 if (ParamInfos)
6461 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6462 OutParamTypes.push_back(Elt: NewParm->getType());
6463 if (PVars)
6464 PVars->push_back(Elt: NewParm);
6465 }
6466
6467 // The next parameter should have the same adjustment as the
6468 // last thing we pushed, but we post-incremented indexAdjustment
6469 // on every push. Also, if we push nothing, the adjustment should
6470 // go down by one.
6471 indexAdjustment--;
6472
6473 // We're done with the pack expansion.
6474 continue;
6475 }
6476
6477 // We'll substitute the parameter now without expanding the pack
6478 // expansion.
6479 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6480 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6481 indexAdjustment,
6482 NumExpansions,
6483 /*ExpectParameterPack=*/true);
6484 assert(NewParm->isParameterPack() &&
6485 "Parameter pack no longer a parameter pack after "
6486 "transformation.");
6487 } else {
6488 NewParm = getDerived().TransformFunctionTypeParam(
6489 OldParm, indexAdjustment, std::nullopt,
6490 /*ExpectParameterPack=*/false);
6491 }
6492
6493 if (!NewParm)
6494 return true;
6495
6496 if (ParamInfos)
6497 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6498 OutParamTypes.push_back(Elt: NewParm->getType());
6499 if (PVars)
6500 PVars->push_back(Elt: NewParm);
6501 continue;
6502 }
6503
6504 // Deal with the possibility that we don't have a parameter
6505 // declaration for this parameter.
6506 assert(ParamTypes);
6507 QualType OldType = ParamTypes[i];
6508 bool IsPackExpansion = false;
6509 UnsignedOrNone NumExpansions = std::nullopt;
6510 QualType NewType;
6511 if (const PackExpansionType *Expansion
6512 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6513 // We have a function parameter pack that may need to be expanded.
6514 QualType Pattern = Expansion->getPattern();
6515 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6516 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6517
6518 // Determine whether we should expand the parameter packs.
6519 bool ShouldExpand = false;
6520 bool RetainExpansion = false;
6521 if (getDerived().TryExpandParameterPacks(
6522 Loc, SourceRange(), Unexpanded,
6523 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6524 RetainExpansion, NumExpansions)) {
6525 return true;
6526 }
6527
6528 if (ShouldExpand) {
6529 // Expand the function parameter pack into multiple, separate
6530 // parameters.
6531 for (unsigned I = 0; I != *NumExpansions; ++I) {
6532 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6533 QualType NewType = getDerived().TransformType(Pattern);
6534 if (NewType.isNull())
6535 return true;
6536
6537 if (NewType->containsUnexpandedParameterPack()) {
6538 NewType = getSema().getASTContext().getPackExpansionType(
6539 NewType, std::nullopt);
6540
6541 if (NewType.isNull())
6542 return true;
6543 }
6544
6545 if (ParamInfos)
6546 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6547 OutParamTypes.push_back(Elt: NewType);
6548 if (PVars)
6549 PVars->push_back(Elt: nullptr);
6550 }
6551
6552 // We're done with the pack expansion.
6553 continue;
6554 }
6555
6556 // If we're supposed to retain a pack expansion, do so by temporarily
6557 // forgetting the partially-substituted parameter pack.
6558 if (RetainExpansion) {
6559 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6560 QualType NewType = getDerived().TransformType(Pattern);
6561 if (NewType.isNull())
6562 return true;
6563
6564 if (ParamInfos)
6565 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6566 OutParamTypes.push_back(Elt: NewType);
6567 if (PVars)
6568 PVars->push_back(Elt: nullptr);
6569 }
6570
6571 // We'll substitute the parameter now without expanding the pack
6572 // expansion.
6573 OldType = Expansion->getPattern();
6574 IsPackExpansion = true;
6575 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6576 NewType = getDerived().TransformType(OldType);
6577 } else {
6578 NewType = getDerived().TransformType(OldType);
6579 }
6580
6581 if (NewType.isNull())
6582 return true;
6583
6584 if (IsPackExpansion)
6585 NewType = getSema().Context.getPackExpansionType(NewType,
6586 NumExpansions);
6587
6588 if (ParamInfos)
6589 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6590 OutParamTypes.push_back(Elt: NewType);
6591 if (PVars)
6592 PVars->push_back(Elt: nullptr);
6593 }
6594
6595#ifndef NDEBUG
6596 if (PVars) {
6597 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6598 if (ParmVarDecl *parm = (*PVars)[i])
6599 assert(parm->getFunctionScopeIndex() == i);
6600 }
6601#endif
6602
6603 return false;
6604}
6605
6606template<typename Derived>
6607QualType
6608TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6609 FunctionProtoTypeLoc TL) {
6610 SmallVector<QualType, 4> ExceptionStorage;
6611 return getDerived().TransformFunctionProtoType(
6612 TLB, TL, nullptr, Qualifiers(),
6613 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6614 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6615 ExceptionStorage, Changed);
6616 });
6617}
6618
6619template<typename Derived> template<typename Fn>
6620QualType TreeTransform<Derived>::TransformFunctionProtoType(
6621 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6622 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6623
6624 // Transform the parameters and return type.
6625 //
6626 // We are required to instantiate the params and return type in source order.
6627 // When the function has a trailing return type, we instantiate the
6628 // parameters before the return type, since the return type can then refer
6629 // to the parameters themselves (via decltype, sizeof, etc.).
6630 //
6631 SmallVector<QualType, 4> ParamTypes;
6632 SmallVector<ParmVarDecl*, 4> ParamDecls;
6633 Sema::ExtParameterInfoBuilder ExtParamInfos;
6634 const FunctionProtoType *T = TL.getTypePtr();
6635
6636 QualType ResultType;
6637
6638 if (T->hasTrailingReturn()) {
6639 if (getDerived().TransformFunctionTypeParams(
6640 TL.getBeginLoc(), TL.getParams(),
6641 TL.getTypePtr()->param_type_begin(),
6642 T->getExtParameterInfosOrNull(),
6643 ParamTypes, &ParamDecls, ExtParamInfos))
6644 return QualType();
6645
6646 {
6647 // C++11 [expr.prim.general]p3:
6648 // If a declaration declares a member function or member function
6649 // template of a class X, the expression this is a prvalue of type
6650 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6651 // and the end of the function-definition, member-declarator, or
6652 // declarator.
6653 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6654 Sema::CXXThisScopeRAII ThisScope(
6655 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6656
6657 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6658 if (ResultType.isNull())
6659 return QualType();
6660 }
6661 }
6662 else {
6663 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6664 if (ResultType.isNull())
6665 return QualType();
6666
6667 if (getDerived().TransformFunctionTypeParams(
6668 TL.getBeginLoc(), TL.getParams(),
6669 TL.getTypePtr()->param_type_begin(),
6670 T->getExtParameterInfosOrNull(),
6671 ParamTypes, &ParamDecls, ExtParamInfos))
6672 return QualType();
6673 }
6674
6675 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6676
6677 bool EPIChanged = false;
6678 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6679 return QualType();
6680
6681 // Handle extended parameter information.
6682 if (auto NewExtParamInfos =
6683 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6684 if (!EPI.ExtParameterInfos ||
6685 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6686 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6687 EPIChanged = true;
6688 }
6689 EPI.ExtParameterInfos = NewExtParamInfos;
6690 } else if (EPI.ExtParameterInfos) {
6691 EPIChanged = true;
6692 EPI.ExtParameterInfos = nullptr;
6693 }
6694
6695 // Transform any function effects with unevaluated conditions.
6696 // Hold this set in a local for the rest of this function, since EPI
6697 // may need to hold a FunctionEffectsRef pointing into it.
6698 std::optional<FunctionEffectSet> NewFX;
6699 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6700 NewFX.emplace();
6701 EnterExpressionEvaluationContext Unevaluated(
6702 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6703
6704 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6705 FunctionEffectWithCondition NewEC = PrevEC;
6706 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6707 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6708 if (NewExpr.isInvalid())
6709 return QualType();
6710 std::optional<FunctionEffectMode> Mode =
6711 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6712 if (!Mode)
6713 return QualType();
6714
6715 // The condition expression has been transformed, and re-evaluated.
6716 // It may or may not have become constant.
6717 switch (*Mode) {
6718 case FunctionEffectMode::True:
6719 NewEC.Cond = {};
6720 break;
6721 case FunctionEffectMode::False:
6722 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6723 NewEC.Cond = {};
6724 break;
6725 case FunctionEffectMode::Dependent:
6726 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6727 break;
6728 case FunctionEffectMode::None:
6729 llvm_unreachable(
6730 "FunctionEffectMode::None shouldn't be possible here");
6731 }
6732 }
6733 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6734 NewAttrLoc: TL.getBeginLoc())) {
6735 FunctionEffectSet::Conflicts Errs;
6736 NewFX->insert(NewEC, Errs);
6737 assert(Errs.empty());
6738 }
6739 }
6740 EPI.FunctionEffects = *NewFX;
6741 EPIChanged = true;
6742 }
6743
6744 QualType Result = TL.getType();
6745 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6746 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6747 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6748 if (Result.isNull())
6749 return QualType();
6750 }
6751
6752 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6753 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6754 NewTL.setLParenLoc(TL.getLParenLoc());
6755 NewTL.setRParenLoc(TL.getRParenLoc());
6756 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6757 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6758 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6759 NewTL.setParam(i, VD: ParamDecls[i]);
6760
6761 return Result;
6762}
6763
6764template<typename Derived>
6765bool TreeTransform<Derived>::TransformExceptionSpec(
6766 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6767 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6768 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6769
6770 // Instantiate a dynamic noexcept expression, if any.
6771 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6772 // Update this scrope because ContextDecl in Sema will be used in
6773 // TransformExpr.
6774 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6775 Sema::CXXThisScopeRAII ThisScope(
6776 SemaRef, Method ? Method->getParent() : nullptr,
6777 Method ? Method->getMethodQualifiers() : Qualifiers{},
6778 Method != nullptr);
6779 EnterExpressionEvaluationContext Unevaluated(
6780 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6781 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6782 if (NoexceptExpr.isInvalid())
6783 return true;
6784
6785 ExceptionSpecificationType EST = ESI.Type;
6786 NoexceptExpr =
6787 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6788 if (NoexceptExpr.isInvalid())
6789 return true;
6790
6791 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6792 Changed = true;
6793 ESI.NoexceptExpr = NoexceptExpr.get();
6794 ESI.Type = EST;
6795 }
6796
6797 if (ESI.Type != EST_Dynamic)
6798 return false;
6799
6800 // Instantiate a dynamic exception specification's type.
6801 for (QualType T : ESI.Exceptions) {
6802 if (const PackExpansionType *PackExpansion =
6803 T->getAs<PackExpansionType>()) {
6804 Changed = true;
6805
6806 // We have a pack expansion. Instantiate it.
6807 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6808 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6809 Unexpanded);
6810 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6811
6812 // Determine whether the set of unexpanded parameter packs can and
6813 // should
6814 // be expanded.
6815 bool Expand = false;
6816 bool RetainExpansion = false;
6817 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6818 // FIXME: Track the location of the ellipsis (and track source location
6819 // information for the types in the exception specification in general).
6820 if (getDerived().TryExpandParameterPacks(
6821 Loc, SourceRange(), Unexpanded,
6822 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6823 NumExpansions))
6824 return true;
6825
6826 if (!Expand) {
6827 // We can't expand this pack expansion into separate arguments yet;
6828 // just substitute into the pattern and create a new pack expansion
6829 // type.
6830 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6831 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6832 if (U.isNull())
6833 return true;
6834
6835 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6836 Exceptions.push_back(Elt: U);
6837 continue;
6838 }
6839
6840 // Substitute into the pack expansion pattern for each slice of the
6841 // pack.
6842 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6843 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6844
6845 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6846 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6847 return true;
6848
6849 Exceptions.push_back(Elt: U);
6850 }
6851 } else {
6852 QualType U = getDerived().TransformType(T);
6853 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6854 return true;
6855 if (T != U)
6856 Changed = true;
6857
6858 Exceptions.push_back(Elt: U);
6859 }
6860 }
6861
6862 ESI.Exceptions = Exceptions;
6863 if (ESI.Exceptions.empty())
6864 ESI.Type = EST_DynamicNone;
6865 return false;
6866}
6867
6868template<typename Derived>
6869QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6870 TypeLocBuilder &TLB,
6871 FunctionNoProtoTypeLoc TL) {
6872 const FunctionNoProtoType *T = TL.getTypePtr();
6873 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6874 if (ResultType.isNull())
6875 return QualType();
6876
6877 QualType Result = TL.getType();
6878 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6879 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6880
6881 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6882 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6883 NewTL.setLParenLoc(TL.getLParenLoc());
6884 NewTL.setRParenLoc(TL.getRParenLoc());
6885 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6886
6887 return Result;
6888}
6889
6890template <typename Derived>
6891QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6892 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6893
6894 const UnresolvedUsingType *T = TL.getTypePtr();
6895 bool Changed = false;
6896
6897 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6898 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6899 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6900 if (!QualifierLoc)
6901 return QualType();
6902 Changed |= QualifierLoc != OldQualifierLoc;
6903 }
6904
6905 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6906 if (!D)
6907 return QualType();
6908 Changed |= D != T->getDecl();
6909
6910 QualType Result = TL.getType();
6911 if (getDerived().AlwaysRebuild() || Changed) {
6912 Result = getDerived().RebuildUnresolvedUsingType(
6913 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
6914 D);
6915 if (Result.isNull())
6916 return QualType();
6917 }
6918
6919 if (isa<UsingType>(Val: Result))
6920 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6921 QualifierLoc, NameLoc: TL.getNameLoc());
6922 else
6923 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6924 QualifierLoc, NameLoc: TL.getNameLoc());
6925 return Result;
6926}
6927
6928template <typename Derived>
6929QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6930 UsingTypeLoc TL) {
6931 const UsingType *T = TL.getTypePtr();
6932 bool Changed = false;
6933
6934 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6935 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6936 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6937 if (!QualifierLoc)
6938 return QualType();
6939 Changed |= QualifierLoc != OldQualifierLoc;
6940 }
6941
6942 auto *D = cast_or_null<UsingShadowDecl>(
6943 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6944 if (!D)
6945 return QualType();
6946 Changed |= D != T->getDecl();
6947
6948 QualType UnderlyingType = getDerived().TransformType(T->desugar());
6949 if (UnderlyingType.isNull())
6950 return QualType();
6951 Changed |= UnderlyingType != T->desugar();
6952
6953 QualType Result = TL.getType();
6954 if (getDerived().AlwaysRebuild() || Changed) {
6955 Result = getDerived().RebuildUsingType(
6956 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
6957 UnderlyingType);
6958 if (Result.isNull())
6959 return QualType();
6960 }
6961 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
6962 NameLoc: TL.getNameLoc());
6963 return Result;
6964}
6965
6966template<typename Derived>
6967QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6968 TypedefTypeLoc TL) {
6969 const TypedefType *T = TL.getTypePtr();
6970 bool Changed = false;
6971
6972 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6973 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6974 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6975 if (!QualifierLoc)
6976 return QualType();
6977 Changed |= QualifierLoc != OldQualifierLoc;
6978 }
6979
6980 auto *Typedef = cast_or_null<TypedefNameDecl>(
6981 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6982 if (!Typedef)
6983 return QualType();
6984 Changed |= Typedef != T->getDecl();
6985
6986 // FIXME: Transform the UnderlyingType if different from decl.
6987
6988 QualType Result = TL.getType();
6989 if (getDerived().AlwaysRebuild() || Changed) {
6990 Result = getDerived().RebuildTypedefType(
6991 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
6992 if (Result.isNull())
6993 return QualType();
6994 }
6995
6996 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6997 QualifierLoc, NameLoc: TL.getNameLoc());
6998 return Result;
6999}
7000
7001template<typename Derived>
7002QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7003 TypeOfExprTypeLoc TL) {
7004 // typeof expressions are not potentially evaluated contexts
7005 EnterExpressionEvaluationContext Unevaluated(
7006 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7007 Sema::ReuseLambdaContextDecl);
7008
7009 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7010 if (E.isInvalid())
7011 return QualType();
7012
7013 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7014 if (E.isInvalid())
7015 return QualType();
7016
7017 QualType Result = TL.getType();
7018 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7019 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7020 Result =
7021 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7022 if (Result.isNull())
7023 return QualType();
7024 }
7025
7026 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7027 NewTL.setTypeofLoc(TL.getTypeofLoc());
7028 NewTL.setLParenLoc(TL.getLParenLoc());
7029 NewTL.setRParenLoc(TL.getRParenLoc());
7030
7031 return Result;
7032}
7033
7034template<typename Derived>
7035QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7036 TypeOfTypeLoc TL) {
7037 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7038 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7039 if (!New_Under_TI)
7040 return QualType();
7041
7042 QualType Result = TL.getType();
7043 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7044 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7045 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7046 if (Result.isNull())
7047 return QualType();
7048 }
7049
7050 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7051 NewTL.setTypeofLoc(TL.getTypeofLoc());
7052 NewTL.setLParenLoc(TL.getLParenLoc());
7053 NewTL.setRParenLoc(TL.getRParenLoc());
7054 NewTL.setUnmodifiedTInfo(New_Under_TI);
7055
7056 return Result;
7057}
7058
7059template<typename Derived>
7060QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7061 DecltypeTypeLoc TL) {
7062 const DecltypeType *T = TL.getTypePtr();
7063
7064 // decltype expressions are not potentially evaluated contexts
7065 EnterExpressionEvaluationContext Unevaluated(
7066 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7067 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7068
7069 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7070 if (E.isInvalid())
7071 return QualType();
7072
7073 E = getSema().ActOnDecltypeExpression(E.get());
7074 if (E.isInvalid())
7075 return QualType();
7076
7077 QualType Result = TL.getType();
7078 if (getDerived().AlwaysRebuild() ||
7079 E.get() != T->getUnderlyingExpr()) {
7080 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7081 if (Result.isNull())
7082 return QualType();
7083 }
7084 else E.get();
7085
7086 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7087 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7088 NewTL.setRParenLoc(TL.getRParenLoc());
7089 return Result;
7090}
7091
7092template <typename Derived>
7093QualType
7094TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7095 PackIndexingTypeLoc TL) {
7096 // Transform the index
7097 ExprResult IndexExpr;
7098 {
7099 EnterExpressionEvaluationContext ConstantContext(
7100 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7101
7102 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7103 if (IndexExpr.isInvalid())
7104 return QualType();
7105 }
7106 QualType Pattern = TL.getPattern();
7107
7108 const PackIndexingType *PIT = TL.getTypePtr();
7109 SmallVector<QualType, 5> SubtitutedTypes;
7110 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7111
7112 bool NotYetExpanded = Types.empty();
7113 bool FullySubstituted = true;
7114
7115 if (Types.empty() && !PIT->expandsToEmptyPack())
7116 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7117
7118 for (QualType T : Types) {
7119 if (!T->containsUnexpandedParameterPack()) {
7120 QualType Transformed = getDerived().TransformType(T);
7121 if (Transformed.isNull())
7122 return QualType();
7123 SubtitutedTypes.push_back(Elt: Transformed);
7124 continue;
7125 }
7126
7127 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7128 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7129 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7130 // Determine whether the set of unexpanded parameter packs can and should
7131 // be expanded.
7132 bool ShouldExpand = true;
7133 bool RetainExpansion = false;
7134 UnsignedOrNone NumExpansions = std::nullopt;
7135 if (getDerived().TryExpandParameterPacks(
7136 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7137 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7138 RetainExpansion, NumExpansions))
7139 return QualType();
7140 if (!ShouldExpand) {
7141 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7142 // FIXME: should we keep TypeLoc for individual expansions in
7143 // PackIndexingTypeLoc?
7144 TypeSourceInfo *TI =
7145 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7146 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7147 if (Pack.isNull())
7148 return QualType();
7149 if (NotYetExpanded) {
7150 FullySubstituted = false;
7151 QualType Out = getDerived().RebuildPackIndexingType(
7152 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7153 FullySubstituted);
7154 if (Out.isNull())
7155 return QualType();
7156
7157 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7158 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7159 return Out;
7160 }
7161 SubtitutedTypes.push_back(Elt: Pack);
7162 continue;
7163 }
7164 for (unsigned I = 0; I != *NumExpansions; ++I) {
7165 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7166 QualType Out = getDerived().TransformType(T);
7167 if (Out.isNull())
7168 return QualType();
7169 SubtitutedTypes.push_back(Elt: Out);
7170 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7171 }
7172 // If we're supposed to retain a pack expansion, do so by temporarily
7173 // forgetting the partially-substituted parameter pack.
7174 if (RetainExpansion) {
7175 FullySubstituted = false;
7176 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7177 QualType Out = getDerived().TransformType(T);
7178 if (Out.isNull())
7179 return QualType();
7180 SubtitutedTypes.push_back(Elt: Out);
7181 }
7182 }
7183
7184 // A pack indexing type can appear in a larger pack expansion,
7185 // e.g. `Pack...[pack_of_indexes]...`
7186 // so we need to temporarily disable substitution of pack elements
7187 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7188 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7189
7190 QualType Out = getDerived().RebuildPackIndexingType(
7191 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7192 FullySubstituted, SubtitutedTypes);
7193 if (Out.isNull())
7194 return Out;
7195
7196 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7197 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7198 return Out;
7199}
7200
7201template<typename Derived>
7202QualType TreeTransform<Derived>::TransformUnaryTransformType(
7203 TypeLocBuilder &TLB,
7204 UnaryTransformTypeLoc TL) {
7205 QualType Result = TL.getType();
7206 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7207 if (Result->isDependentType()) {
7208 const UnaryTransformType *T = TL.getTypePtr();
7209
7210 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7211 if (!NewBaseTSI)
7212 return QualType();
7213 QualType NewBase = NewBaseTSI->getType();
7214
7215 Result = getDerived().RebuildUnaryTransformType(NewBase,
7216 T->getUTTKind(),
7217 TL.getKWLoc());
7218 if (Result.isNull())
7219 return QualType();
7220 }
7221
7222 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7223 NewTL.setKWLoc(TL.getKWLoc());
7224 NewTL.setParensRange(TL.getParensRange());
7225 NewTL.setUnderlyingTInfo(NewBaseTSI);
7226 return Result;
7227}
7228
7229template<typename Derived>
7230QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7231 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7232 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7233
7234 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7235 TemplateName TemplateName = getDerived().TransformTemplateName(
7236 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7237 TL.getTemplateNameLoc());
7238 if (TemplateName.isNull())
7239 return QualType();
7240
7241 QualType OldDeduced = T->getDeducedType();
7242 QualType NewDeduced;
7243 if (!OldDeduced.isNull()) {
7244 NewDeduced = getDerived().TransformType(OldDeduced);
7245 if (NewDeduced.isNull())
7246 return QualType();
7247 }
7248
7249 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7250 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7251 NewDeduced, T->getKeyword(), TemplateName);
7252 if (Result.isNull())
7253 return QualType();
7254
7255 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7256 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7257 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7258 NewTL.setQualifierLoc(QualifierLoc);
7259 return Result;
7260}
7261
7262template <typename Derived>
7263QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7264 TagTypeLoc TL) {
7265 const TagType *T = TL.getTypePtr();
7266
7267 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7268 if (QualifierLoc) {
7269 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7270 if (!QualifierLoc)
7271 return QualType();
7272 }
7273
7274 auto *TD = cast_or_null<TagDecl>(
7275 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7276 if (!TD)
7277 return QualType();
7278
7279 QualType Result = TL.getType();
7280 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7281 TD != T->getDecl()) {
7282 if (T->isCanonicalUnqualified())
7283 Result = getDerived().RebuildCanonicalTagType(TD);
7284 else
7285 Result = getDerived().RebuildTagType(
7286 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7287 if (Result.isNull())
7288 return QualType();
7289 }
7290
7291 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7292 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7293 NewTL.setQualifierLoc(QualifierLoc);
7294 NewTL.setNameLoc(TL.getNameLoc());
7295
7296 return Result;
7297}
7298
7299template <typename Derived>
7300QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7301 EnumTypeLoc TL) {
7302 return getDerived().TransformTagType(TLB, TL);
7303}
7304
7305template <typename Derived>
7306QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7307 RecordTypeLoc TL) {
7308 return getDerived().TransformTagType(TLB, TL);
7309}
7310
7311template<typename Derived>
7312QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7313 TypeLocBuilder &TLB,
7314 InjectedClassNameTypeLoc TL) {
7315 return getDerived().TransformTagType(TLB, TL);
7316}
7317
7318template<typename Derived>
7319QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7320 TypeLocBuilder &TLB,
7321 TemplateTypeParmTypeLoc TL) {
7322 return getDerived().TransformTemplateTypeParmType(
7323 TLB, TL,
7324 /*SuppressObjCLifetime=*/false);
7325}
7326
7327template <typename Derived>
7328QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7329 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7330 return TransformTypeSpecType(TLB, T: TL);
7331}
7332
7333template<typename Derived>
7334QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7335 TypeLocBuilder &TLB,
7336 SubstTemplateTypeParmTypeLoc TL) {
7337 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7338
7339 Decl *NewReplaced =
7340 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7341
7342 // Substitute into the replacement type, which itself might involve something
7343 // that needs to be transformed. This only tends to occur with default
7344 // template arguments of template template parameters.
7345 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7346 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7347 if (Replacement.isNull())
7348 return QualType();
7349
7350 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7351 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7352 Final: T->getFinal());
7353
7354 // Propagate type-source information.
7355 SubstTemplateTypeParmTypeLoc NewTL
7356 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7357 NewTL.setNameLoc(TL.getNameLoc());
7358 return Result;
7359
7360}
7361template <typename Derived>
7362QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7363 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7364 return TransformTypeSpecType(TLB, T: TL);
7365}
7366
7367template<typename Derived>
7368QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7369 TypeLocBuilder &TLB,
7370 SubstTemplateTypeParmPackTypeLoc TL) {
7371 return getDerived().TransformSubstTemplateTypeParmPackType(
7372 TLB, TL, /*SuppressObjCLifetime=*/false);
7373}
7374
7375template <typename Derived>
7376QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7377 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7378 return TransformTypeSpecType(TLB, T: TL);
7379}
7380
7381template<typename Derived>
7382QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7383 AtomicTypeLoc TL) {
7384 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7385 if (ValueType.isNull())
7386 return QualType();
7387
7388 QualType Result = TL.getType();
7389 if (getDerived().AlwaysRebuild() ||
7390 ValueType != TL.getValueLoc().getType()) {
7391 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7392 if (Result.isNull())
7393 return QualType();
7394 }
7395
7396 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7397 NewTL.setKWLoc(TL.getKWLoc());
7398 NewTL.setLParenLoc(TL.getLParenLoc());
7399 NewTL.setRParenLoc(TL.getRParenLoc());
7400
7401 return Result;
7402}
7403
7404template <typename Derived>
7405QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7406 PipeTypeLoc TL) {
7407 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7408 if (ValueType.isNull())
7409 return QualType();
7410
7411 QualType Result = TL.getType();
7412 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7413 const PipeType *PT = Result->castAs<PipeType>();
7414 bool isReadPipe = PT->isReadOnly();
7415 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7416 if (Result.isNull())
7417 return QualType();
7418 }
7419
7420 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7421 NewTL.setKWLoc(TL.getKWLoc());
7422
7423 return Result;
7424}
7425
7426template <typename Derived>
7427QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7428 BitIntTypeLoc TL) {
7429 const BitIntType *EIT = TL.getTypePtr();
7430 QualType Result = TL.getType();
7431
7432 if (getDerived().AlwaysRebuild()) {
7433 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7434 EIT->getNumBits(), TL.getNameLoc());
7435 if (Result.isNull())
7436 return QualType();
7437 }
7438
7439 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7440 NewTL.setNameLoc(TL.getNameLoc());
7441 return Result;
7442}
7443
7444template <typename Derived>
7445QualType TreeTransform<Derived>::TransformDependentBitIntType(
7446 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7447 const DependentBitIntType *EIT = TL.getTypePtr();
7448
7449 EnterExpressionEvaluationContext Unevaluated(
7450 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7451 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7452 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7453
7454 if (BitsExpr.isInvalid())
7455 return QualType();
7456
7457 QualType Result = TL.getType();
7458
7459 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7460 Result = getDerived().RebuildDependentBitIntType(
7461 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7462
7463 if (Result.isNull())
7464 return QualType();
7465 }
7466
7467 if (isa<DependentBitIntType>(Val: Result)) {
7468 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7469 NewTL.setNameLoc(TL.getNameLoc());
7470 } else {
7471 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7472 NewTL.setNameLoc(TL.getNameLoc());
7473 }
7474 return Result;
7475}
7476
7477template <typename Derived>
7478QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7479 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7480 llvm_unreachable("This type does not need to be transformed.");
7481}
7482
7483 /// Simple iterator that traverses the template arguments in a
7484 /// container that provides a \c getArgLoc() member function.
7485 ///
7486 /// This iterator is intended to be used with the iterator form of
7487 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7488 template<typename ArgLocContainer>
7489 class TemplateArgumentLocContainerIterator {
7490 ArgLocContainer *Container;
7491 unsigned Index;
7492
7493 public:
7494 typedef TemplateArgumentLoc value_type;
7495 typedef TemplateArgumentLoc reference;
7496 typedef int difference_type;
7497 typedef std::input_iterator_tag iterator_category;
7498
7499 class pointer {
7500 TemplateArgumentLoc Arg;
7501
7502 public:
7503 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7504
7505 const TemplateArgumentLoc *operator->() const {
7506 return &Arg;
7507 }
7508 };
7509
7510
7511 TemplateArgumentLocContainerIterator() {}
7512
7513 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7514 unsigned Index)
7515 : Container(&Container), Index(Index) { }
7516
7517 TemplateArgumentLocContainerIterator &operator++() {
7518 ++Index;
7519 return *this;
7520 }
7521
7522 TemplateArgumentLocContainerIterator operator++(int) {
7523 TemplateArgumentLocContainerIterator Old(*this);
7524 ++(*this);
7525 return Old;
7526 }
7527
7528 TemplateArgumentLoc operator*() const {
7529 return Container->getArgLoc(Index);
7530 }
7531
7532 pointer operator->() const {
7533 return pointer(Container->getArgLoc(Index));
7534 }
7535
7536 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7537 const TemplateArgumentLocContainerIterator &Y) {
7538 return X.Container == Y.Container && X.Index == Y.Index;
7539 }
7540
7541 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7542 const TemplateArgumentLocContainerIterator &Y) {
7543 return !(X == Y);
7544 }
7545 };
7546
7547template<typename Derived>
7548QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7549 AutoTypeLoc TL) {
7550 const AutoType *T = TL.getTypePtr();
7551 QualType OldDeduced = T->getDeducedType();
7552 QualType NewDeduced;
7553 if (!OldDeduced.isNull()) {
7554 NewDeduced = getDerived().TransformType(OldDeduced);
7555 if (NewDeduced.isNull())
7556 return QualType();
7557 }
7558
7559 ConceptDecl *NewCD = nullptr;
7560 TemplateArgumentListInfo NewTemplateArgs;
7561 NestedNameSpecifierLoc NewNestedNameSpec;
7562 if (T->isConstrained()) {
7563 assert(TL.getConceptReference());
7564 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7565 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7566
7567 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7568 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7569 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7570 if (getDerived().TransformTemplateArguments(
7571 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7572 NewTemplateArgs))
7573 return QualType();
7574
7575 if (TL.getNestedNameSpecifierLoc()) {
7576 NewNestedNameSpec
7577 = getDerived().TransformNestedNameSpecifierLoc(
7578 TL.getNestedNameSpecifierLoc());
7579 if (!NewNestedNameSpec)
7580 return QualType();
7581 }
7582 }
7583
7584 QualType Result = TL.getType();
7585 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7586 T->isDependentType() || T->isConstrained()) {
7587 // FIXME: Maybe don't rebuild if all template arguments are the same.
7588 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7589 NewArgList.reserve(N: NewTemplateArgs.size());
7590 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7591 NewArgList.push_back(Elt: ArgLoc.getArgument());
7592 Result = getDerived().RebuildAutoType(
7593 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7594 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7595 if (Result.isNull())
7596 return QualType();
7597 }
7598
7599 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7600 NewTL.setNameLoc(TL.getNameLoc());
7601 NewTL.setRParenLoc(TL.getRParenLoc());
7602 NewTL.setConceptReference(nullptr);
7603
7604 if (T->isConstrained()) {
7605 DeclarationNameInfo DNI = DeclarationNameInfo(
7606 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7607 TL.getConceptNameLoc(),
7608 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7609 auto *CR = ConceptReference::Create(
7610 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7611 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7612 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7613 NewTL.setConceptReference(CR);
7614 }
7615
7616 return Result;
7617}
7618
7619template <typename Derived>
7620QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7621 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7622 return getDerived().TransformTemplateSpecializationType(
7623 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7624 /*AllowInjectedClassName=*/false);
7625}
7626
7627template <typename Derived>
7628QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7629 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7630 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7631 const TemplateSpecializationType *T = TL.getTypePtr();
7632
7633 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7634 TemplateName Template = getDerived().TransformTemplateName(
7635 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7636 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7637 AllowInjectedClassName);
7638 if (Template.isNull())
7639 return QualType();
7640
7641 TemplateArgumentListInfo NewTemplateArgs;
7642 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7643 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7644 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7645 ArgIterator;
7646 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7647 ArgIterator(TL, TL.getNumArgs()),
7648 NewTemplateArgs))
7649 return QualType();
7650
7651 // This needs to be rebuilt if either the arguments changed, or if the
7652 // original template changed. If the template changed, and even if the
7653 // arguments didn't change, these arguments might not correspond to their
7654 // respective parameters, therefore needing conversions.
7655 QualType Result = getDerived().RebuildTemplateSpecializationType(
7656 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7657 NewTemplateArgs);
7658
7659 if (!Result.isNull()) {
7660 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7661 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7662 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7663 }
7664
7665 return Result;
7666}
7667
7668template <typename Derived>
7669QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7670 AttributedTypeLoc TL) {
7671 const AttributedType *oldType = TL.getTypePtr();
7672 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7673 if (modifiedType.isNull())
7674 return QualType();
7675
7676 // HLSL: re-validate matrix-layout markers after substitution. If the
7677 // post-substitution type is no longer a matrix, diagnose now.
7678 if (SemaRef.getLangOpts().HLSL &&
7679 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7680 K: oldType->getAttrKind(), T: modifiedType,
7681 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7682 : TL.getModifiedLoc().getBeginLoc()))
7683 return QualType();
7684
7685 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7686 const Attr *oldAttr = TL.getAttr();
7687 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7688 if (oldAttr && !newAttr)
7689 return QualType();
7690
7691 QualType result = TL.getType();
7692
7693 // FIXME: dependent operand expressions?
7694 if (getDerived().AlwaysRebuild() ||
7695 modifiedType != oldType->getModifiedType()) {
7696 // If the equivalent type is equal to the modified type, we don't want to
7697 // transform it as well because:
7698 //
7699 // 1. The transformation would yield the same result and is therefore
7700 // superfluous, and
7701 //
7702 // 2. Transforming the same type twice can cause problems, e.g. if it
7703 // is a FunctionProtoType, we may end up instantiating the function
7704 // parameters twice, which causes an assertion since the parameters
7705 // are already bound to their counterparts in the template for this
7706 // instantiation.
7707 //
7708 QualType equivalentType = modifiedType;
7709 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7710 TypeLocBuilder AuxiliaryTLB;
7711 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7712 equivalentType =
7713 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7714 if (equivalentType.isNull())
7715 return QualType();
7716 }
7717
7718 // Check whether we can add nullability; it is only represented as
7719 // type sugar, and therefore cannot be diagnosed in any other way.
7720 if (auto nullability = oldType->getImmediateNullability()) {
7721 if (!modifiedType->canHaveNullability()) {
7722 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7723 : TL.getModifiedLoc().getBeginLoc()),
7724 DiagID: diag::err_nullability_nonpointer)
7725 << DiagNullabilityKind(*nullability, false) << modifiedType;
7726 return QualType();
7727 }
7728 }
7729
7730 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7731 modifiedType,
7732 equivalentType,
7733 attr: TL.getAttr());
7734 }
7735
7736 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7737 newTL.setAttr(newAttr);
7738 return result;
7739}
7740
7741template <typename Derived>
7742QualType TreeTransform<Derived>::TransformCountAttributedType(
7743 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7744 const CountAttributedType *OldTy = TL.getTypePtr();
7745 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7746 if (InnerTy.isNull())
7747 return QualType();
7748
7749 Expr *OldCount = TL.getCountExpr();
7750 Expr *NewCount = nullptr;
7751 if (OldCount) {
7752 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7753 if (CountResult.isInvalid())
7754 return QualType();
7755 NewCount = CountResult.get();
7756 }
7757
7758 QualType Result = TL.getType();
7759 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7760 OldCount != NewCount) {
7761 // Currently, CountAttributedType can only wrap incomplete array types.
7762 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7763 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7764 }
7765
7766 TLB.push<CountAttributedTypeLoc>(T: Result);
7767 return Result;
7768}
7769
7770template <typename Derived>
7771QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7772 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7773 // The BTFTagAttributedType is available for C only.
7774 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7775}
7776
7777template <typename Derived>
7778QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7779 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7780 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7781 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7782 if (InnerTy.isNull())
7783 return QualType();
7784
7785 QualType Result = TL.getType();
7786 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7787 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7788 Wrapped: InnerTy);
7789 if (Result.isNull())
7790 return QualType();
7791 }
7792
7793 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7794 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7795 return Result;
7796}
7797
7798template <typename Derived>
7799QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7800 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7801
7802 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7803
7804 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7805 if (WrappedTy.isNull())
7806 return QualType();
7807
7808 QualType ContainedTy = QualType();
7809 QualType OldContainedTy = oldType->getContainedType();
7810 TypeSourceInfo *ContainedTSI = nullptr;
7811 if (!OldContainedTy.isNull()) {
7812 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7813 if (!oldContainedTSI)
7814 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7815 OldContainedTy, SourceLocation());
7816 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7817 if (!ContainedTSI)
7818 return QualType();
7819 ContainedTy = ContainedTSI->getType();
7820 }
7821
7822 QualType Result = TL.getType();
7823 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7824 ContainedTy != oldType->getContainedType()) {
7825 Result = SemaRef.Context.getHLSLAttributedResourceType(
7826 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7827 }
7828
7829 HLSLAttributedResourceTypeLoc NewTL =
7830 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7831 NewTL.setSourceRange(TL.getLocalSourceRange());
7832 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7833 return Result;
7834}
7835
7836template <typename Derived>
7837QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7838 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7839 // No transformations needed.
7840 return TL.getType();
7841}
7842
7843template<typename Derived>
7844QualType
7845TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7846 ParenTypeLoc TL) {
7847 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7848 if (Inner.isNull())
7849 return QualType();
7850
7851 QualType Result = TL.getType();
7852 if (getDerived().AlwaysRebuild() ||
7853 Inner != TL.getInnerLoc().getType()) {
7854 Result = getDerived().RebuildParenType(Inner);
7855 if (Result.isNull())
7856 return QualType();
7857 }
7858
7859 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7860 NewTL.setLParenLoc(TL.getLParenLoc());
7861 NewTL.setRParenLoc(TL.getRParenLoc());
7862 return Result;
7863}
7864
7865template <typename Derived>
7866QualType
7867TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7868 MacroQualifiedTypeLoc TL) {
7869 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7870 if (Inner.isNull())
7871 return QualType();
7872
7873 QualType Result = TL.getType();
7874 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7875 Result =
7876 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7877 if (Result.isNull())
7878 return QualType();
7879 }
7880
7881 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7882 NewTL.setExpansionLoc(TL.getExpansionLoc());
7883 return Result;
7884}
7885
7886template<typename Derived>
7887QualType TreeTransform<Derived>::TransformDependentNameType(
7888 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7889 return TransformDependentNameType(TLB, TL, false);
7890}
7891
7892template <typename Derived>
7893QualType TreeTransform<Derived>::TransformDependentNameType(
7894 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
7895 QualType ObjectType, NamedDecl *UnqualLookup) {
7896 const DependentNameType *T = TL.getTypePtr();
7897
7898 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7899 if (QualifierLoc) {
7900 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
7901 QualifierLoc, ObjectType, UnqualLookup);
7902 if (!QualifierLoc)
7903 return QualType();
7904 } else {
7905 assert((ObjectType.isNull() && !UnqualLookup) &&
7906 "must be transformed by TransformNestedNameSpecifierLoc");
7907 }
7908
7909 QualType Result
7910 = getDerived().RebuildDependentNameType(T->getKeyword(),
7911 TL.getElaboratedKeywordLoc(),
7912 QualifierLoc,
7913 T->getIdentifier(),
7914 TL.getNameLoc(),
7915 DeducedTSTContext);
7916 if (Result.isNull())
7917 return QualType();
7918
7919 if (isa<TagType>(Val: Result)) {
7920 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
7921 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7922 NewTL.setQualifierLoc(QualifierLoc);
7923 NewTL.setNameLoc(TL.getNameLoc());
7924 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
7925 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7926 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7927 NewTL.setTemplateNameLoc(TL.getNameLoc());
7928 NewTL.setQualifierLoc(QualifierLoc);
7929 } else if (isa<TypedefType>(Val: Result)) {
7930 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7931 QualifierLoc, NameLoc: TL.getNameLoc());
7932 } else if (isa<UnresolvedUsingType>(Val: Result)) {
7933 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
7934 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
7935 } else {
7936 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7937 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7938 NewTL.setQualifierLoc(QualifierLoc);
7939 NewTL.setNameLoc(TL.getNameLoc());
7940 }
7941 return Result;
7942}
7943
7944template<typename Derived>
7945QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7946 PackExpansionTypeLoc TL) {
7947 QualType Pattern
7948 = getDerived().TransformType(TLB, TL.getPatternLoc());
7949 if (Pattern.isNull())
7950 return QualType();
7951
7952 QualType Result = TL.getType();
7953 if (getDerived().AlwaysRebuild() ||
7954 Pattern != TL.getPatternLoc().getType()) {
7955 Result = getDerived().RebuildPackExpansionType(Pattern,
7956 TL.getPatternLoc().getSourceRange(),
7957 TL.getEllipsisLoc(),
7958 TL.getTypePtr()->getNumExpansions());
7959 if (Result.isNull())
7960 return QualType();
7961 }
7962
7963 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7964 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7965 return Result;
7966}
7967
7968template<typename Derived>
7969QualType
7970TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7971 ObjCInterfaceTypeLoc TL) {
7972 // ObjCInterfaceType is never dependent.
7973 TLB.pushFullCopy(L: TL);
7974 return TL.getType();
7975}
7976
7977template<typename Derived>
7978QualType
7979TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7980 ObjCTypeParamTypeLoc TL) {
7981 const ObjCTypeParamType *T = TL.getTypePtr();
7982 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7983 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7984 if (!OTP)
7985 return QualType();
7986
7987 QualType Result = TL.getType();
7988 if (getDerived().AlwaysRebuild() ||
7989 OTP != T->getDecl()) {
7990 Result = getDerived().RebuildObjCTypeParamType(
7991 OTP, TL.getProtocolLAngleLoc(),
7992 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7993 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7994 if (Result.isNull())
7995 return QualType();
7996 }
7997
7998 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7999 if (TL.getNumProtocols()) {
8000 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8001 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8002 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8003 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8004 }
8005 return Result;
8006}
8007
8008template<typename Derived>
8009QualType
8010TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8011 ObjCObjectTypeLoc TL) {
8012 // Transform base type.
8013 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8014 if (BaseType.isNull())
8015 return QualType();
8016
8017 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8018
8019 // Transform type arguments.
8020 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8021 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8022 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8023 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8024 QualType TypeArg = TypeArgInfo->getType();
8025 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8026 AnyChanged = true;
8027
8028 // We have a pack expansion. Instantiate it.
8029 const auto *PackExpansion = PackExpansionLoc.getType()
8030 ->castAs<PackExpansionType>();
8031 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8032 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8033 Unexpanded);
8034 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8035
8036 // Determine whether the set of unexpanded parameter packs can
8037 // and should be expanded.
8038 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8039 bool Expand = false;
8040 bool RetainExpansion = false;
8041 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8042 if (getDerived().TryExpandParameterPacks(
8043 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8044 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8045 RetainExpansion, NumExpansions))
8046 return QualType();
8047
8048 if (!Expand) {
8049 // We can't expand this pack expansion into separate arguments yet;
8050 // just substitute into the pattern and create a new pack expansion
8051 // type.
8052 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8053
8054 TypeLocBuilder TypeArgBuilder;
8055 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8056 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8057 PatternLoc);
8058 if (NewPatternType.isNull())
8059 return QualType();
8060
8061 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8062 Pattern: NewPatternType, NumExpansions);
8063 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8064 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8065 NewTypeArgInfos.push_back(
8066 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8067 continue;
8068 }
8069
8070 // Substitute into the pack expansion pattern for each slice of the
8071 // pack.
8072 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8073 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8074
8075 TypeLocBuilder TypeArgBuilder;
8076 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8077
8078 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8079 PatternLoc);
8080 if (NewTypeArg.isNull())
8081 return QualType();
8082
8083 NewTypeArgInfos.push_back(
8084 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8085 }
8086
8087 continue;
8088 }
8089
8090 TypeLocBuilder TypeArgBuilder;
8091 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8092 QualType NewTypeArg =
8093 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8094 if (NewTypeArg.isNull())
8095 return QualType();
8096
8097 // If nothing changed, just keep the old TypeSourceInfo.
8098 if (NewTypeArg == TypeArg) {
8099 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8100 continue;
8101 }
8102
8103 NewTypeArgInfos.push_back(
8104 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8105 AnyChanged = true;
8106 }
8107
8108 QualType Result = TL.getType();
8109 if (getDerived().AlwaysRebuild() || AnyChanged) {
8110 // Rebuild the type.
8111 Result = getDerived().RebuildObjCObjectType(
8112 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8113 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8114 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8115 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8116
8117 if (Result.isNull())
8118 return QualType();
8119 }
8120
8121 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8122 NewT.setHasBaseTypeAsWritten(true);
8123 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8124 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8125 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8126 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8127 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8128 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8129 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8130 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8131 return Result;
8132}
8133
8134template<typename Derived>
8135QualType
8136TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8137 ObjCObjectPointerTypeLoc TL) {
8138 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8139 if (PointeeType.isNull())
8140 return QualType();
8141
8142 QualType Result = TL.getType();
8143 if (getDerived().AlwaysRebuild() ||
8144 PointeeType != TL.getPointeeLoc().getType()) {
8145 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8146 TL.getStarLoc());
8147 if (Result.isNull())
8148 return QualType();
8149 }
8150
8151 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8152 NewT.setStarLoc(TL.getStarLoc());
8153 return Result;
8154}
8155
8156//===----------------------------------------------------------------------===//
8157// Statement transformation
8158//===----------------------------------------------------------------------===//
8159template<typename Derived>
8160StmtResult
8161TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8162 return S;
8163}
8164
8165template<typename Derived>
8166StmtResult
8167TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8168 return getDerived().TransformCompoundStmt(S, false);
8169}
8170
8171template<typename Derived>
8172StmtResult
8173TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8174 bool IsStmtExpr) {
8175 Sema::CompoundScopeRAII CompoundScope(getSema());
8176 Sema::FPFeaturesStateRAII FPSave(getSema());
8177 if (S->hasStoredFPFeatures())
8178 getSema().resetFPOptions(
8179 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8180
8181 bool SubStmtInvalid = false;
8182 bool SubStmtChanged = false;
8183 SmallVector<Stmt*, 8> Statements;
8184 for (auto *B : S->body()) {
8185 StmtResult Result = getDerived().TransformStmt(
8186 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8187 : StmtDiscardKind::Discarded);
8188
8189 if (Result.isInvalid()) {
8190 // Immediately fail if this was a DeclStmt, since it's very
8191 // likely that this will cause problems for future statements.
8192 if (isa<DeclStmt>(Val: B))
8193 return StmtError();
8194
8195 // Otherwise, just keep processing substatements and fail later.
8196 SubStmtInvalid = true;
8197 continue;
8198 }
8199
8200 SubStmtChanged = SubStmtChanged || Result.get() != B;
8201 Statements.push_back(Elt: Result.getAs<Stmt>());
8202 }
8203
8204 if (SubStmtInvalid)
8205 return StmtError();
8206
8207 if (!getDerived().AlwaysRebuild() &&
8208 !SubStmtChanged)
8209 return S;
8210
8211 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8212 Statements,
8213 S->getRBracLoc(),
8214 IsStmtExpr);
8215}
8216
8217template<typename Derived>
8218StmtResult
8219TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8220 ExprResult LHS, RHS;
8221 {
8222 EnterExpressionEvaluationContext Unevaluated(
8223 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8224
8225 // Transform the left-hand case value.
8226 LHS = getDerived().TransformExpr(S->getLHS());
8227 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8228 if (LHS.isInvalid())
8229 return StmtError();
8230
8231 // Transform the right-hand case value (for the GNU case-range extension).
8232 RHS = getDerived().TransformExpr(S->getRHS());
8233 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8234 if (RHS.isInvalid())
8235 return StmtError();
8236 }
8237
8238 // Build the case statement.
8239 // Case statements are always rebuilt so that they will attached to their
8240 // transformed switch statement.
8241 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8242 LHS.get(),
8243 S->getEllipsisLoc(),
8244 RHS.get(),
8245 S->getColonLoc());
8246 if (Case.isInvalid())
8247 return StmtError();
8248
8249 // Transform the statement following the case
8250 StmtResult SubStmt =
8251 getDerived().TransformStmt(S->getSubStmt());
8252 if (SubStmt.isInvalid())
8253 return StmtError();
8254
8255 // Attach the body to the case statement
8256 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8257}
8258
8259template <typename Derived>
8260StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8261 // Transform the statement following the default case
8262 StmtResult SubStmt =
8263 getDerived().TransformStmt(S->getSubStmt());
8264 if (SubStmt.isInvalid())
8265 return StmtError();
8266
8267 // Default statements are always rebuilt
8268 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8269 SubStmt.get());
8270}
8271
8272template<typename Derived>
8273StmtResult
8274TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8275 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8276 if (SubStmt.isInvalid())
8277 return StmtError();
8278
8279 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8280 S->getDecl());
8281 if (!LD)
8282 return StmtError();
8283
8284 // If we're transforming "in-place" (we're not creating new local
8285 // declarations), assume we're replacing the old label statement
8286 // and clear out the reference to it.
8287 if (LD == S->getDecl())
8288 S->getDecl()->setStmt(nullptr);
8289
8290 // FIXME: Pass the real colon location in.
8291 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8292 cast<LabelDecl>(Val: LD), SourceLocation(),
8293 SubStmt.get());
8294}
8295
8296template <typename Derived>
8297const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8298 if (!R)
8299 return R;
8300
8301 switch (R->getKind()) {
8302// Transform attributes by calling TransformXXXAttr.
8303#define ATTR(X) \
8304 case attr::X: \
8305 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8306#include "clang/Basic/AttrList.inc"
8307 }
8308 return R;
8309}
8310
8311template <typename Derived>
8312const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8313 const Stmt *InstS,
8314 const Attr *R) {
8315 if (!R)
8316 return R;
8317
8318 switch (R->getKind()) {
8319// Transform attributes by calling TransformStmtXXXAttr.
8320#define ATTR(X) \
8321 case attr::X: \
8322 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8323#include "clang/Basic/AttrList.inc"
8324 }
8325 return TransformAttr(R);
8326}
8327
8328template <typename Derived>
8329StmtResult
8330TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8331 StmtDiscardKind SDK) {
8332 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8333 if (SubStmt.isInvalid())
8334 return StmtError();
8335
8336 bool AttrsChanged = false;
8337 SmallVector<const Attr *, 1> Attrs;
8338
8339 // Visit attributes and keep track if any are transformed.
8340 for (const auto *I : S->getAttrs()) {
8341 const Attr *R =
8342 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8343 AttrsChanged |= (I != R);
8344 if (R)
8345 Attrs.push_back(Elt: R);
8346 }
8347
8348 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8349 return S;
8350
8351 // If transforming the attributes failed for all of the attributes in the
8352 // statement, don't make an AttributedStmt without attributes.
8353 if (Attrs.empty())
8354 return SubStmt;
8355
8356 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8357 SubStmt.get());
8358}
8359
8360template<typename Derived>
8361StmtResult
8362TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8363 // Transform the initialization statement
8364 StmtResult Init = getDerived().TransformStmt(S->getInit());
8365 if (Init.isInvalid())
8366 return StmtError();
8367
8368 Sema::ConditionResult Cond;
8369 if (!S->isConsteval()) {
8370 // Transform the condition
8371 Cond = getDerived().TransformCondition(
8372 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8373 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8374 : Sema::ConditionKind::Boolean);
8375 if (Cond.isInvalid())
8376 return StmtError();
8377 }
8378
8379 // If this is a constexpr if, determine which arm we should instantiate.
8380 std::optional<bool> ConstexprConditionValue;
8381 if (S->isConstexpr())
8382 ConstexprConditionValue = Cond.getKnownValue();
8383
8384 // Transform the "then" branch.
8385 StmtResult Then;
8386 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8387 EnterExpressionEvaluationContext Ctx(
8388 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8389 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8390 S->isNonNegatedConsteval());
8391
8392 Then = getDerived().TransformStmt(S->getThen());
8393 if (Then.isInvalid())
8394 return StmtError();
8395 } else {
8396 // Discarded branch is replaced with empty CompoundStmt so we can keep
8397 // proper source location for start and end of original branch, so
8398 // subsequent transformations like CoverageMapping work properly
8399 Then = new (getSema().Context)
8400 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8401 }
8402
8403 // Transform the "else" branch.
8404 StmtResult Else;
8405 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8406 EnterExpressionEvaluationContext Ctx(
8407 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8408 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8409 S->isNegatedConsteval());
8410
8411 Else = getDerived().TransformStmt(S->getElse());
8412 if (Else.isInvalid())
8413 return StmtError();
8414 } else if (S->getElse() && ConstexprConditionValue &&
8415 *ConstexprConditionValue) {
8416 // Same thing here as with <then> branch, we are discarding it, we can't
8417 // replace it with NULL nor NullStmt as we need to keep for source location
8418 // range, for CoverageMapping
8419 Else = new (getSema().Context)
8420 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8421 }
8422
8423 if (!getDerived().AlwaysRebuild() &&
8424 Init.get() == S->getInit() &&
8425 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8426 Then.get() == S->getThen() &&
8427 Else.get() == S->getElse())
8428 return S;
8429
8430 return getDerived().RebuildIfStmt(
8431 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8432 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8433}
8434
8435template<typename Derived>
8436StmtResult
8437TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8438 // Transform the initialization statement
8439 StmtResult Init = getDerived().TransformStmt(S->getInit());
8440 if (Init.isInvalid())
8441 return StmtError();
8442
8443 // Transform the condition.
8444 Sema::ConditionResult Cond = getDerived().TransformCondition(
8445 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8446 Sema::ConditionKind::Switch);
8447 if (Cond.isInvalid())
8448 return StmtError();
8449
8450 // Rebuild the switch statement.
8451 StmtResult Switch =
8452 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8453 Init.get(), Cond, S->getRParenLoc());
8454 if (Switch.isInvalid())
8455 return StmtError();
8456
8457 // Transform the body of the switch statement.
8458 StmtResult Body = getDerived().TransformStmt(S->getBody());
8459 if (Body.isInvalid())
8460 return StmtError();
8461
8462 // Complete the switch statement.
8463 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8464 Body.get());
8465}
8466
8467template<typename Derived>
8468StmtResult
8469TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8470 // Transform the condition
8471 Sema::ConditionResult Cond = getDerived().TransformCondition(
8472 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8473 Sema::ConditionKind::Boolean);
8474 if (Cond.isInvalid())
8475 return StmtError();
8476
8477 // OpenACC Restricts a while-loop inside of certain construct/clause
8478 // combinations, so diagnose that here in OpenACC mode.
8479 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8480 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8481
8482 // Transform the body
8483 StmtResult Body = getDerived().TransformStmt(S->getBody());
8484 if (Body.isInvalid())
8485 return StmtError();
8486
8487 if (!getDerived().AlwaysRebuild() &&
8488 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8489 Body.get() == S->getBody())
8490 return Owned(S);
8491
8492 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8493 Cond, S->getRParenLoc(), Body.get());
8494}
8495
8496template<typename Derived>
8497StmtResult
8498TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8499 // OpenACC Restricts a do-loop inside of certain construct/clause
8500 // combinations, so diagnose that here in OpenACC mode.
8501 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8502 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8503
8504 // Transform the body
8505 StmtResult Body = getDerived().TransformStmt(S->getBody());
8506 if (Body.isInvalid())
8507 return StmtError();
8508
8509 // Transform the condition
8510 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8511 if (Cond.isInvalid())
8512 return StmtError();
8513
8514 if (!getDerived().AlwaysRebuild() &&
8515 Cond.get() == S->getCond() &&
8516 Body.get() == S->getBody())
8517 return S;
8518
8519 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8520 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8521 S->getRParenLoc());
8522}
8523
8524template<typename Derived>
8525StmtResult
8526TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8527 if (getSema().getLangOpts().OpenMP)
8528 getSema().OpenMP().startOpenMPLoop();
8529
8530 // Transform the initialization statement
8531 StmtResult Init = getDerived().TransformStmt(S->getInit());
8532 if (Init.isInvalid())
8533 return StmtError();
8534
8535 // In OpenMP loop region loop control variable must be captured and be
8536 // private. Perform analysis of first part (if any).
8537 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8538 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8539 Init.get());
8540
8541 // Transform the condition
8542 Sema::ConditionResult Cond = getDerived().TransformCondition(
8543 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8544 Sema::ConditionKind::Boolean);
8545 if (Cond.isInvalid())
8546 return StmtError();
8547
8548 // Transform the increment
8549 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8550 if (Inc.isInvalid())
8551 return StmtError();
8552
8553 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8554 if (S->getInc() && !FullInc.get())
8555 return StmtError();
8556
8557 // OpenACC Restricts a for-loop inside of certain construct/clause
8558 // combinations, so diagnose that here in OpenACC mode.
8559 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8560 SemaRef.OpenACC().ActOnForStmtBegin(
8561 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8562 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8563
8564 // Transform the body
8565 StmtResult Body = getDerived().TransformStmt(S->getBody());
8566 if (Body.isInvalid())
8567 return StmtError();
8568
8569 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8570
8571 if (!getDerived().AlwaysRebuild() &&
8572 Init.get() == S->getInit() &&
8573 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8574 Inc.get() == S->getInc() &&
8575 Body.get() == S->getBody())
8576 return S;
8577
8578 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8579 Init.get(), Cond, FullInc,
8580 S->getRParenLoc(), Body.get());
8581}
8582
8583template<typename Derived>
8584StmtResult
8585TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8586 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8587 S->getLabel());
8588 if (!LD)
8589 return StmtError();
8590
8591 // Goto statements must always be rebuilt, to resolve the label.
8592 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8593 cast<LabelDecl>(Val: LD));
8594}
8595
8596template<typename Derived>
8597StmtResult
8598TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8599 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8600 if (Target.isInvalid())
8601 return StmtError();
8602 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8603
8604 if (!getDerived().AlwaysRebuild() &&
8605 Target.get() == S->getTarget())
8606 return S;
8607
8608 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8609 Target.get());
8610}
8611
8612template<typename Derived>
8613StmtResult
8614TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8615 if (!S->hasLabelTarget())
8616 return S;
8617
8618 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8619 S->getLabelDecl());
8620 if (!LD)
8621 return StmtError();
8622
8623 return new (SemaRef.Context)
8624 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8625}
8626
8627template<typename Derived>
8628StmtResult
8629TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8630 if (!S->hasLabelTarget())
8631 return S;
8632
8633 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8634 S->getLabelDecl());
8635 if (!LD)
8636 return StmtError();
8637
8638 return new (SemaRef.Context)
8639 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8640}
8641
8642template <typename Derived>
8643StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8644 StmtResult Result = getDerived().TransformStmt(S->getBody());
8645 if (!Result.isUsable())
8646 return StmtError();
8647 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8648}
8649
8650template<typename Derived>
8651StmtResult
8652TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8653 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8654 /*NotCopyInit*/false);
8655 if (Result.isInvalid())
8656 return StmtError();
8657
8658 // FIXME: We always rebuild the return statement because there is no way
8659 // to tell whether the return type of the function has changed.
8660 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8661}
8662
8663template<typename Derived>
8664StmtResult
8665TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8666 bool DeclChanged = false;
8667 SmallVector<Decl *, 4> Decls;
8668 LambdaScopeInfo *LSI = getSema().getCurLambda();
8669 for (auto *D : S->decls()) {
8670 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8671 if (!Transformed)
8672 return StmtError();
8673
8674 if (Transformed != D)
8675 DeclChanged = true;
8676
8677 if (LSI) {
8678 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8679 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8680 LSI->ContainsUnexpandedParameterPack |=
8681 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8682 } else {
8683 LSI->ContainsUnexpandedParameterPack |=
8684 getSema()
8685 .getASTContext()
8686 .getTypeDeclType(TD)
8687 ->containsUnexpandedParameterPack();
8688 }
8689 }
8690 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8691 LSI->ContainsUnexpandedParameterPack |=
8692 VD->getType()->containsUnexpandedParameterPack();
8693 }
8694
8695 Decls.push_back(Elt: Transformed);
8696 }
8697
8698 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8699 return S;
8700
8701 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8702}
8703
8704template<typename Derived>
8705StmtResult
8706TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8707
8708 SmallVector<Expr*, 8> Constraints;
8709 SmallVector<Expr*, 8> Exprs;
8710 SmallVector<IdentifierInfo *, 4> Names;
8711
8712 SmallVector<Expr*, 8> Clobbers;
8713
8714 bool ExprsChanged = false;
8715
8716 auto RebuildString = [&](Expr *E) {
8717 ExprResult Result = getDerived().TransformExpr(E);
8718 if (!Result.isUsable())
8719 return Result;
8720 if (Result.get() != E) {
8721 ExprsChanged = true;
8722 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8723 }
8724 return Result;
8725 };
8726
8727 // Go through the outputs.
8728 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8729 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8730
8731 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8732 if (Result.isInvalid())
8733 return StmtError();
8734
8735 Constraints.push_back(Elt: Result.get());
8736
8737 // Transform the output expr.
8738 Expr *OutputExpr = S->getOutputExpr(i: I);
8739 Result = getDerived().TransformExpr(OutputExpr);
8740 if (Result.isInvalid())
8741 return StmtError();
8742
8743 ExprsChanged |= Result.get() != OutputExpr;
8744
8745 Exprs.push_back(Elt: Result.get());
8746 }
8747
8748 // Go through the inputs.
8749 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8750 Names.push_back(Elt: S->getInputIdentifier(i: I));
8751
8752 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8753 if (Result.isInvalid())
8754 return StmtError();
8755
8756 Constraints.push_back(Elt: Result.get());
8757
8758 // Transform the input expr.
8759 Expr *InputExpr = S->getInputExpr(i: I);
8760 Result = getDerived().TransformExpr(InputExpr);
8761 if (Result.isInvalid())
8762 return StmtError();
8763
8764 ExprsChanged |= Result.get() != InputExpr;
8765
8766 Exprs.push_back(Elt: Result.get());
8767 }
8768
8769 // Go through the Labels.
8770 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8771 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8772
8773 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8774 if (Result.isInvalid())
8775 return StmtError();
8776 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8777 Exprs.push_back(Elt: Result.get());
8778 }
8779
8780 // Go through the clobbers.
8781 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8782 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8783 if (Result.isInvalid())
8784 return StmtError();
8785 Clobbers.push_back(Elt: Result.get());
8786 }
8787
8788 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8789 if (AsmString.isInvalid())
8790 return StmtError();
8791
8792 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8793 return S;
8794
8795 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8796 S->isVolatile(), S->getNumOutputs(),
8797 S->getNumInputs(), Names.data(),
8798 Constraints, Exprs, AsmString.get(),
8799 Clobbers, S->getNumLabels(),
8800 S->getRParenLoc());
8801}
8802
8803template<typename Derived>
8804StmtResult
8805TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8806 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8807
8808 bool HadError = false, HadChange = false;
8809
8810 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8811 SmallVector<Expr*, 8> TransformedExprs;
8812 TransformedExprs.reserve(N: SrcExprs.size());
8813 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8814 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8815 if (!Result.isUsable()) {
8816 HadError = true;
8817 } else {
8818 HadChange |= (Result.get() != SrcExprs[i]);
8819 TransformedExprs.push_back(Elt: Result.get());
8820 }
8821 }
8822
8823 if (HadError) return StmtError();
8824 if (!HadChange && !getDerived().AlwaysRebuild())
8825 return Owned(S);
8826
8827 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8828 AsmToks, S->getAsmString(),
8829 S->getNumOutputs(), S->getNumInputs(),
8830 S->getAllConstraints(), S->getClobbers(),
8831 TransformedExprs, S->getEndLoc());
8832}
8833
8834// C++ Coroutines
8835template<typename Derived>
8836StmtResult
8837TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8838 auto *ScopeInfo = SemaRef.getCurFunction();
8839 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8840 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8841 ScopeInfo->NeedsCoroutineSuspends &&
8842 ScopeInfo->CoroutineSuspends.first == nullptr &&
8843 ScopeInfo->CoroutineSuspends.second == nullptr &&
8844 "expected clean scope info");
8845
8846 // Set that we have (possibly-invalid) suspend points before we do anything
8847 // that may fail.
8848 ScopeInfo->setNeedsCoroutineSuspends(false);
8849
8850 // We re-build the coroutine promise object (and the coroutine parameters its
8851 // type and constructor depend on) based on the types used in our current
8852 // function. We must do so, and set it on the current FunctionScopeInfo,
8853 // before attempting to transform the other parts of the coroutine body
8854 // statement, such as the implicit suspend statements (because those
8855 // statements reference the FunctionScopeInfo::CoroutinePromise).
8856 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8857 return StmtError();
8858 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8859 if (!Promise)
8860 return StmtError();
8861 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8862 ScopeInfo->CoroutinePromise = Promise;
8863
8864 // Transform the implicit coroutine statements constructed using dependent
8865 // types during the previous parse: initial and final suspensions, the return
8866 // object, and others. We also transform the coroutine function's body.
8867 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8868 if (InitSuspend.isInvalid())
8869 return StmtError();
8870 StmtResult FinalSuspend =
8871 getDerived().TransformStmt(S->getFinalSuspendStmt());
8872 if (FinalSuspend.isInvalid() ||
8873 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8874 return StmtError();
8875 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8876 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8877
8878 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8879 if (BodyRes.isInvalid())
8880 return StmtError();
8881
8882 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8883 if (Builder.isInvalid())
8884 return StmtError();
8885
8886 Expr *ReturnObject = S->getReturnValueInit();
8887 assert(ReturnObject && "the return object is expected to be valid");
8888 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8889 /*NoCopyInit*/ false);
8890 if (Res.isInvalid())
8891 return StmtError();
8892 Builder.ReturnValue = Res.get();
8893
8894 // If during the previous parse the coroutine still had a dependent promise
8895 // statement, we may need to build some implicit coroutine statements
8896 // (such as exception and fallthrough handlers) for the first time.
8897 if (S->hasDependentPromiseType()) {
8898 // We can only build these statements, however, if the current promise type
8899 // is not dependent.
8900 if (!Promise->getType()->isDependentType()) {
8901 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8902 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8903 "these nodes should not have been built yet");
8904 if (!Builder.buildDependentStatements())
8905 return StmtError();
8906 }
8907 } else {
8908 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8909 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8910 if (Res.isInvalid())
8911 return StmtError();
8912 Builder.OnFallthrough = Res.get();
8913 }
8914
8915 if (auto *OnException = S->getExceptionHandler()) {
8916 StmtResult Res = getDerived().TransformStmt(OnException);
8917 if (Res.isInvalid())
8918 return StmtError();
8919 Builder.OnException = Res.get();
8920 }
8921
8922 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8923 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8924 if (Res.isInvalid())
8925 return StmtError();
8926 Builder.ReturnStmtOnAllocFailure = Res.get();
8927 }
8928
8929 // Transform any additional statements we may have already built
8930 assert(S->getAllocate() && S->getDeallocate() &&
8931 "allocation and deallocation calls must already be built");
8932 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8933 if (AllocRes.isInvalid())
8934 return StmtError();
8935 Builder.Allocate = AllocRes.get();
8936
8937 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8938 if (DeallocRes.isInvalid())
8939 return StmtError();
8940 Builder.Deallocate = DeallocRes.get();
8941
8942 if (auto *ResultDecl = S->getResultDecl()) {
8943 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8944 if (Res.isInvalid())
8945 return StmtError();
8946 Builder.ResultDecl = Res.get();
8947 }
8948
8949 if (auto *ReturnStmt = S->getReturnStmt()) {
8950 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8951 if (Res.isInvalid())
8952 return StmtError();
8953 Builder.ReturnStmt = Res.get();
8954 }
8955 }
8956
8957 return getDerived().RebuildCoroutineBodyStmt(Builder);
8958}
8959
8960template<typename Derived>
8961StmtResult
8962TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8963 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8964 /*NotCopyInit*/false);
8965 if (Result.isInvalid())
8966 return StmtError();
8967
8968 // Always rebuild; we don't know if this needs to be injected into a new
8969 // context or if the promise type has changed.
8970 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8971 S->isImplicit());
8972}
8973
8974template <typename Derived>
8975ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8976 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8977 /*NotCopyInit*/ false);
8978 if (Operand.isInvalid())
8979 return ExprError();
8980
8981 // Rebuild the common-expr from the operand rather than transforming it
8982 // separately.
8983
8984 // FIXME: getCurScope() should not be used during template instantiation.
8985 // We should pick up the set of unqualified lookup results for operator
8986 // co_await during the initial parse.
8987 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8988 getSema().getCurScope(), E->getKeywordLoc());
8989
8990 // Always rebuild; we don't know if this needs to be injected into a new
8991 // context or if the promise type has changed.
8992 return getDerived().RebuildCoawaitExpr(
8993 E->getKeywordLoc(), Operand.get(),
8994 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8995}
8996
8997template <typename Derived>
8998ExprResult
8999TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9000 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9001 /*NotCopyInit*/ false);
9002 if (OperandResult.isInvalid())
9003 return ExprError();
9004
9005 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9006 E->getOperatorCoawaitLookup());
9007
9008 if (LookupResult.isInvalid())
9009 return ExprError();
9010
9011 // Always rebuild; we don't know if this needs to be injected into a new
9012 // context or if the promise type has changed.
9013 return getDerived().RebuildDependentCoawaitExpr(
9014 E->getKeywordLoc(), OperandResult.get(),
9015 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9016}
9017
9018template<typename Derived>
9019ExprResult
9020TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9021 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9022 /*NotCopyInit*/false);
9023 if (Result.isInvalid())
9024 return ExprError();
9025
9026 // Always rebuild; we don't know if this needs to be injected into a new
9027 // context or if the promise type has changed.
9028 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9029}
9030
9031// Objective-C Statements.
9032
9033template<typename Derived>
9034StmtResult
9035TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9036 // Transform the body of the @try.
9037 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9038 if (TryBody.isInvalid())
9039 return StmtError();
9040
9041 // Transform the @catch statements (if present).
9042 bool AnyCatchChanged = false;
9043 SmallVector<Stmt*, 8> CatchStmts;
9044 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9045 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9046 if (Catch.isInvalid())
9047 return StmtError();
9048 if (Catch.get() != S->getCatchStmt(I))
9049 AnyCatchChanged = true;
9050 CatchStmts.push_back(Elt: Catch.get());
9051 }
9052
9053 // Transform the @finally statement (if present).
9054 StmtResult Finally;
9055 if (S->getFinallyStmt()) {
9056 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9057 if (Finally.isInvalid())
9058 return StmtError();
9059 }
9060
9061 // If nothing changed, just retain this statement.
9062 if (!getDerived().AlwaysRebuild() &&
9063 TryBody.get() == S->getTryBody() &&
9064 !AnyCatchChanged &&
9065 Finally.get() == S->getFinallyStmt())
9066 return S;
9067
9068 // Build a new statement.
9069 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9070 CatchStmts, Finally.get());
9071}
9072
9073template<typename Derived>
9074StmtResult
9075TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9076 // Transform the @catch parameter, if there is one.
9077 VarDecl *Var = nullptr;
9078 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9079 TypeSourceInfo *TSInfo = nullptr;
9080 if (FromVar->getTypeSourceInfo()) {
9081 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9082 if (!TSInfo)
9083 return StmtError();
9084 }
9085
9086 QualType T;
9087 if (TSInfo)
9088 T = TSInfo->getType();
9089 else {
9090 T = getDerived().TransformType(FromVar->getType());
9091 if (T.isNull())
9092 return StmtError();
9093 }
9094
9095 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9096 if (!Var)
9097 return StmtError();
9098 }
9099
9100 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9101 if (Body.isInvalid())
9102 return StmtError();
9103
9104 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9105 S->getRParenLoc(),
9106 Var, Body.get());
9107}
9108
9109template<typename Derived>
9110StmtResult
9111TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9112 // Transform the body.
9113 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9114 if (Body.isInvalid())
9115 return StmtError();
9116
9117 // If nothing changed, just retain this statement.
9118 if (!getDerived().AlwaysRebuild() &&
9119 Body.get() == S->getFinallyBody())
9120 return S;
9121
9122 // Build a new statement.
9123 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9124 Body.get());
9125}
9126
9127template<typename Derived>
9128StmtResult
9129TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9130 ExprResult Operand;
9131 if (S->getThrowExpr()) {
9132 Operand = getDerived().TransformExpr(S->getThrowExpr());
9133 if (Operand.isInvalid())
9134 return StmtError();
9135 }
9136
9137 if (!getDerived().AlwaysRebuild() &&
9138 Operand.get() == S->getThrowExpr())
9139 return S;
9140
9141 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9142}
9143
9144template<typename Derived>
9145StmtResult
9146TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9147 ObjCAtSynchronizedStmt *S) {
9148 // Transform the object we are locking.
9149 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9150 if (Object.isInvalid())
9151 return StmtError();
9152 Object =
9153 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9154 Object.get());
9155 if (Object.isInvalid())
9156 return StmtError();
9157
9158 // Transform the body.
9159 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9160 if (Body.isInvalid())
9161 return StmtError();
9162
9163 // If nothing change, just retain the current statement.
9164 if (!getDerived().AlwaysRebuild() &&
9165 Object.get() == S->getSynchExpr() &&
9166 Body.get() == S->getSynchBody())
9167 return S;
9168
9169 // Build a new statement.
9170 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9171 Object.get(), Body.get());
9172}
9173
9174template<typename Derived>
9175StmtResult
9176TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9177 ObjCAutoreleasePoolStmt *S) {
9178 // Transform the body.
9179 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9180 if (Body.isInvalid())
9181 return StmtError();
9182
9183 // If nothing changed, just retain this statement.
9184 if (!getDerived().AlwaysRebuild() &&
9185 Body.get() == S->getSubStmt())
9186 return S;
9187
9188 // Build a new statement.
9189 return getDerived().RebuildObjCAutoreleasePoolStmt(
9190 S->getAtLoc(), Body.get());
9191}
9192
9193template<typename Derived>
9194StmtResult
9195TreeTransform<Derived>::TransformObjCForCollectionStmt(
9196 ObjCForCollectionStmt *S) {
9197 // Transform the element statement.
9198 StmtResult Element = getDerived().TransformStmt(
9199 S->getElement(), StmtDiscardKind::NotDiscarded);
9200 if (Element.isInvalid())
9201 return StmtError();
9202
9203 // Transform the collection expression.
9204 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9205 if (Collection.isInvalid())
9206 return StmtError();
9207
9208 // Transform the body.
9209 StmtResult Body = getDerived().TransformStmt(S->getBody());
9210 if (Body.isInvalid())
9211 return StmtError();
9212
9213 // If nothing changed, just retain this statement.
9214 if (!getDerived().AlwaysRebuild() &&
9215 Element.get() == S->getElement() &&
9216 Collection.get() == S->getCollection() &&
9217 Body.get() == S->getBody())
9218 return S;
9219
9220 // Build a new statement.
9221 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9222 Element.get(),
9223 Collection.get(),
9224 S->getRParenLoc(),
9225 Body.get());
9226}
9227
9228template <typename Derived>
9229StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9230 // Transform the exception declaration, if any.
9231 VarDecl *Var = nullptr;
9232 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9233 TypeSourceInfo *T =
9234 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9235 if (!T)
9236 return StmtError();
9237
9238 Var = getDerived().RebuildExceptionDecl(
9239 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9240 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9241 if (!Var || Var->isInvalidDecl())
9242 return StmtError();
9243 }
9244
9245 // Transform the actual exception handler.
9246 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9247 if (Handler.isInvalid())
9248 return StmtError();
9249
9250 if (!getDerived().AlwaysRebuild() && !Var &&
9251 Handler.get() == S->getHandlerBlock())
9252 return S;
9253
9254 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9255}
9256
9257template <typename Derived>
9258StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9259 // Transform the try block itself.
9260 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9261 if (TryBlock.isInvalid())
9262 return StmtError();
9263
9264 // Transform the handlers.
9265 bool HandlerChanged = false;
9266 SmallVector<Stmt *, 8> Handlers;
9267 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9268 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9269 if (Handler.isInvalid())
9270 return StmtError();
9271
9272 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9273 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9274 }
9275
9276 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9277
9278 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9279 !HandlerChanged)
9280 return S;
9281
9282 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9283 Handlers);
9284}
9285
9286template<typename Derived>
9287StmtResult
9288TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9289 EnterExpressionEvaluationContext ForRangeInitContext(
9290 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9291 /*LambdaContextDecl=*/nullptr,
9292 Sema::ExpressionEvaluationContextRecord::EK_Other,
9293 getSema().getLangOpts().CPlusPlus23);
9294
9295 // P2718R0 - Lifetime extension in range-based for loops.
9296 if (getSema().getLangOpts().CPlusPlus23) {
9297 auto &LastRecord = getSema().currentEvaluationContext();
9298 LastRecord.InLifetimeExtendingContext = true;
9299 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9300 }
9301 StmtResult Init =
9302 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9303 if (Init.isInvalid())
9304 return StmtError();
9305
9306 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9307 if (Range.isInvalid())
9308 return StmtError();
9309
9310 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9311 assert(getSema().getLangOpts().CPlusPlus23 ||
9312 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9313 auto ForRangeLifetimeExtendTemps =
9314 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9315
9316 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9317 if (Begin.isInvalid())
9318 return StmtError();
9319 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9320 if (End.isInvalid())
9321 return StmtError();
9322
9323 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9324 if (Cond.isInvalid())
9325 return StmtError();
9326 if (Cond.get())
9327 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9328 if (Cond.isInvalid())
9329 return StmtError();
9330 if (Cond.get())
9331 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9332
9333 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9334 if (Inc.isInvalid())
9335 return StmtError();
9336 if (Inc.get())
9337 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9338
9339 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9340 if (LoopVar.isInvalid())
9341 return StmtError();
9342
9343 StmtResult NewStmt = S;
9344 if (getDerived().AlwaysRebuild() ||
9345 Init.get() != S->getInit() ||
9346 Range.get() != S->getRangeStmt() ||
9347 Begin.get() != S->getBeginStmt() ||
9348 End.get() != S->getEndStmt() ||
9349 Cond.get() != S->getCond() ||
9350 Inc.get() != S->getInc() ||
9351 LoopVar.get() != S->getLoopVarStmt()) {
9352 NewStmt = getDerived().RebuildCXXForRangeStmt(
9353 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9354 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9355 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9356 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9357 // Might not have attached any initializer to the loop variable.
9358 getSema().ActOnInitializerError(
9359 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9360 return StmtError();
9361 }
9362 }
9363
9364 // OpenACC Restricts a while-loop inside of certain construct/clause
9365 // combinations, so diagnose that here in OpenACC mode.
9366 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9367 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9368
9369 StmtResult Body = getDerived().TransformStmt(S->getBody());
9370 if (Body.isInvalid())
9371 return StmtError();
9372
9373 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9374
9375 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9376 // it now so we have a new statement to attach the body to.
9377 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9378 NewStmt = getDerived().RebuildCXXForRangeStmt(
9379 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9380 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9381 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9382 if (NewStmt.isInvalid())
9383 return StmtError();
9384 }
9385
9386 if (NewStmt.get() == S)
9387 return S;
9388
9389 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9390}
9391
9392template<typename Derived>
9393StmtResult
9394TreeTransform<Derived>::TransformMSDependentExistsStmt(
9395 MSDependentExistsStmt *S) {
9396 // Transform the nested-name-specifier, if any.
9397 NestedNameSpecifierLoc QualifierLoc;
9398 if (S->getQualifierLoc()) {
9399 QualifierLoc
9400 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9401 if (!QualifierLoc)
9402 return StmtError();
9403 }
9404
9405 // Transform the declaration name.
9406 DeclarationNameInfo NameInfo = S->getNameInfo();
9407 if (NameInfo.getName()) {
9408 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9409 if (!NameInfo.getName())
9410 return StmtError();
9411 }
9412
9413 // Check whether anything changed.
9414 if (!getDerived().AlwaysRebuild() &&
9415 QualifierLoc == S->getQualifierLoc() &&
9416 NameInfo.getName() == S->getNameInfo().getName())
9417 return S;
9418
9419 // Determine whether this name exists, if we can.
9420 CXXScopeSpec SS;
9421 SS.Adopt(Other: QualifierLoc);
9422 bool Dependent = false;
9423 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9424 case IfExistsResult::Exists:
9425 if (S->isIfExists())
9426 break;
9427
9428 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9429
9430 case IfExistsResult::DoesNotExist:
9431 if (S->isIfNotExists())
9432 break;
9433
9434 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9435
9436 case IfExistsResult::Dependent:
9437 Dependent = true;
9438 break;
9439
9440 case IfExistsResult::Error:
9441 return StmtError();
9442 }
9443
9444 // We need to continue with the instantiation, so do so now.
9445 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9446 if (SubStmt.isInvalid())
9447 return StmtError();
9448
9449 // If we have resolved the name, just transform to the substatement.
9450 if (!Dependent)
9451 return SubStmt;
9452
9453 // The name is still dependent, so build a dependent expression again.
9454 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9455 S->isIfExists(),
9456 QualifierLoc,
9457 NameInfo,
9458 SubStmt.get());
9459}
9460
9461template<typename Derived>
9462ExprResult
9463TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9464 NestedNameSpecifierLoc QualifierLoc;
9465 if (E->getQualifierLoc()) {
9466 QualifierLoc
9467 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9468 if (!QualifierLoc)
9469 return ExprError();
9470 }
9471
9472 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9473 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9474 if (!PD)
9475 return ExprError();
9476
9477 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9478 if (Base.isInvalid())
9479 return ExprError();
9480
9481 return new (SemaRef.getASTContext())
9482 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9483 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9484 QualifierLoc, E->getMemberLoc());
9485}
9486
9487template <typename Derived>
9488ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9489 MSPropertySubscriptExpr *E) {
9490 auto BaseRes = getDerived().TransformExpr(E->getBase());
9491 if (BaseRes.isInvalid())
9492 return ExprError();
9493 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9494 if (IdxRes.isInvalid())
9495 return ExprError();
9496
9497 if (!getDerived().AlwaysRebuild() &&
9498 BaseRes.get() == E->getBase() &&
9499 IdxRes.get() == E->getIdx())
9500 return E;
9501
9502 return getDerived().RebuildArraySubscriptExpr(
9503 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9504}
9505
9506template <typename Derived>
9507StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9508 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9509 if (TryBlock.isInvalid())
9510 return StmtError();
9511
9512 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9513 if (Handler.isInvalid())
9514 return StmtError();
9515
9516 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9517 Handler.get() == S->getHandler())
9518 return S;
9519
9520 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9521 TryBlock.get(), Handler.get());
9522}
9523
9524template <typename Derived>
9525StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9526 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9527 if (Block.isInvalid())
9528 return StmtError();
9529
9530 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9531}
9532
9533template <typename Derived>
9534StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9535 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9536 if (FilterExpr.isInvalid())
9537 return StmtError();
9538
9539 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9540 if (Block.isInvalid())
9541 return StmtError();
9542
9543 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9544 Block.get());
9545}
9546
9547template <typename Derived>
9548StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9549 if (isa<SEHFinallyStmt>(Val: Handler))
9550 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9551 else
9552 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9553}
9554
9555template<typename Derived>
9556StmtResult
9557TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9558 return S;
9559}
9560
9561//===----------------------------------------------------------------------===//
9562// OpenMP directive transformation
9563//===----------------------------------------------------------------------===//
9564
9565template <typename Derived>
9566StmtResult
9567TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9568 // OMPCanonicalLoops are eliminated during transformation, since they will be
9569 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9570 // after transformation.
9571 return getDerived().TransformStmt(L->getLoopStmt());
9572}
9573
9574template <typename Derived>
9575StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9576 OMPExecutableDirective *D) {
9577
9578 // Transform the clauses
9579 llvm::SmallVector<OMPClause *, 16> TClauses;
9580 ArrayRef<OMPClause *> Clauses = D->clauses();
9581 TClauses.reserve(N: Clauses.size());
9582 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9583 I != E; ++I) {
9584 if (*I) {
9585 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9586 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9587 getDerived().getSema().OpenMP().EndOpenMPClause();
9588 if (Clause)
9589 TClauses.push_back(Elt: Clause);
9590 } else {
9591 TClauses.push_back(Elt: nullptr);
9592 }
9593 }
9594 StmtResult AssociatedStmt;
9595 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9596 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9597 D->getDirectiveKind(),
9598 /*CurScope=*/nullptr);
9599 StmtResult Body;
9600 {
9601 Sema::CompoundScopeRAII CompoundScope(getSema());
9602 Stmt *CS;
9603 if (D->getDirectiveKind() == OMPD_atomic ||
9604 D->getDirectiveKind() == OMPD_critical ||
9605 D->getDirectiveKind() == OMPD_section ||
9606 D->getDirectiveKind() == OMPD_master)
9607 CS = D->getAssociatedStmt();
9608 else
9609 CS = D->getRawStmt();
9610 Body = getDerived().TransformStmt(CS);
9611 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9612 getSema().getLangOpts().OpenMPIRBuilder)
9613 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9614 }
9615 AssociatedStmt =
9616 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9617 if (AssociatedStmt.isInvalid()) {
9618 return StmtError();
9619 }
9620 }
9621 if (TClauses.size() != Clauses.size()) {
9622 return StmtError();
9623 }
9624
9625 // Transform directive name for 'omp critical' directive.
9626 DeclarationNameInfo DirName;
9627 if (D->getDirectiveKind() == OMPD_critical) {
9628 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9629 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9630 }
9631 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9632 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9633 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9634 } else if (D->getDirectiveKind() == OMPD_cancel) {
9635 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9636 }
9637
9638 return getDerived().RebuildOMPExecutableDirective(
9639 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9640 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9641}
9642
9643/// This is mostly the same as above, but allows 'informational' class
9644/// directives when rebuilding the stmt. It still takes an
9645/// OMPExecutableDirective-type argument because we're reusing that as the
9646/// superclass for the 'assume' directive at present, instead of defining a
9647/// mostly-identical OMPInformationalDirective parent class.
9648template <typename Derived>
9649StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9650 OMPExecutableDirective *D) {
9651
9652 // Transform the clauses
9653 llvm::SmallVector<OMPClause *, 16> TClauses;
9654 ArrayRef<OMPClause *> Clauses = D->clauses();
9655 TClauses.reserve(N: Clauses.size());
9656 for (OMPClause *C : Clauses) {
9657 if (C) {
9658 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9659 OMPClause *Clause = getDerived().TransformOMPClause(C);
9660 getDerived().getSema().OpenMP().EndOpenMPClause();
9661 if (Clause)
9662 TClauses.push_back(Elt: Clause);
9663 } else {
9664 TClauses.push_back(Elt: nullptr);
9665 }
9666 }
9667 StmtResult AssociatedStmt;
9668 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9669 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9670 D->getDirectiveKind(),
9671 /*CurScope=*/nullptr);
9672 StmtResult Body;
9673 {
9674 Sema::CompoundScopeRAII CompoundScope(getSema());
9675 assert(D->getDirectiveKind() == OMPD_assume &&
9676 "Unexpected informational directive");
9677 Stmt *CS = D->getAssociatedStmt();
9678 Body = getDerived().TransformStmt(CS);
9679 }
9680 AssociatedStmt =
9681 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9682 if (AssociatedStmt.isInvalid())
9683 return StmtError();
9684 }
9685 if (TClauses.size() != Clauses.size())
9686 return StmtError();
9687
9688 DeclarationNameInfo DirName;
9689
9690 return getDerived().RebuildOMPInformationalDirective(
9691 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9692 D->getBeginLoc(), D->getEndLoc());
9693}
9694
9695template <typename Derived>
9696StmtResult
9697TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9698 // TODO: Fix This
9699 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9700 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9701 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9702 return StmtError();
9703}
9704
9705template <typename Derived>
9706StmtResult
9707TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9708 DeclarationNameInfo DirName;
9709 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9710 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9711 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9712 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9713 return Res;
9714}
9715
9716template <typename Derived>
9717StmtResult
9718TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9719 DeclarationNameInfo DirName;
9720 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9721 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9722 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9723 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9724 return Res;
9725}
9726
9727template <typename Derived>
9728StmtResult
9729TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9730 DeclarationNameInfo DirName;
9731 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9732 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9733 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9734 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9735 return Res;
9736}
9737
9738template <typename Derived>
9739StmtResult
9740TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9741 DeclarationNameInfo DirName;
9742 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9743 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9744 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9745 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9746 return Res;
9747}
9748
9749template <typename Derived>
9750StmtResult
9751TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9752 DeclarationNameInfo DirName;
9753 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9754 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9755 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9756 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9757 return Res;
9758}
9759
9760template <typename Derived>
9761StmtResult
9762TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9763 DeclarationNameInfo DirName;
9764 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9765 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9766 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9767 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9768 return Res;
9769}
9770
9771template <typename Derived>
9772StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9773 OMPInterchangeDirective *D) {
9774 DeclarationNameInfo DirName;
9775 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9776 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9777 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9778 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9779 return Res;
9780}
9781
9782template <typename Derived>
9783StmtResult
9784TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
9785 DeclarationNameInfo DirName;
9786 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9787 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9788 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9789 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9790 return Res;
9791}
9792
9793template <typename Derived>
9794StmtResult
9795TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
9796 DeclarationNameInfo DirName;
9797 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9798 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9799 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9800 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9801 return Res;
9802}
9803
9804template <typename Derived>
9805StmtResult
9806TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9807 DeclarationNameInfo DirName;
9808 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9809 OMPD_for, DirName, nullptr, D->getBeginLoc());
9810 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9811 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9812 return Res;
9813}
9814
9815template <typename Derived>
9816StmtResult
9817TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9818 DeclarationNameInfo DirName;
9819 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9820 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9821 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9822 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9823 return Res;
9824}
9825
9826template <typename Derived>
9827StmtResult
9828TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9829 DeclarationNameInfo DirName;
9830 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9831 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9832 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9833 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9834 return Res;
9835}
9836
9837template <typename Derived>
9838StmtResult
9839TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9840 DeclarationNameInfo DirName;
9841 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9842 OMPD_section, DirName, nullptr, D->getBeginLoc());
9843 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9844 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9845 return Res;
9846}
9847
9848template <typename Derived>
9849StmtResult
9850TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9851 DeclarationNameInfo DirName;
9852 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9853 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9854 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9855 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9856 return Res;
9857}
9858
9859template <typename Derived>
9860StmtResult
9861TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9862 DeclarationNameInfo DirName;
9863 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9864 OMPD_single, DirName, nullptr, D->getBeginLoc());
9865 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9866 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9867 return Res;
9868}
9869
9870template <typename Derived>
9871StmtResult
9872TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9873 DeclarationNameInfo DirName;
9874 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9875 OMPD_master, DirName, nullptr, D->getBeginLoc());
9876 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9877 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9878 return Res;
9879}
9880
9881template <typename Derived>
9882StmtResult
9883TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9884 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9885 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9886 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9887 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9888 return Res;
9889}
9890
9891template <typename Derived>
9892StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9893 OMPParallelForDirective *D) {
9894 DeclarationNameInfo DirName;
9895 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9896 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9897 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9898 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9899 return Res;
9900}
9901
9902template <typename Derived>
9903StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9904 OMPParallelForSimdDirective *D) {
9905 DeclarationNameInfo DirName;
9906 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9907 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9908 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9909 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9910 return Res;
9911}
9912
9913template <typename Derived>
9914StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9915 OMPParallelMasterDirective *D) {
9916 DeclarationNameInfo DirName;
9917 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9918 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9919 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9920 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9921 return Res;
9922}
9923
9924template <typename Derived>
9925StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9926 OMPParallelMaskedDirective *D) {
9927 DeclarationNameInfo DirName;
9928 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9929 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9930 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9931 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9932 return Res;
9933}
9934
9935template <typename Derived>
9936StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9937 OMPParallelSectionsDirective *D) {
9938 DeclarationNameInfo DirName;
9939 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9940 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9941 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9942 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9943 return Res;
9944}
9945
9946template <typename Derived>
9947StmtResult
9948TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9949 DeclarationNameInfo DirName;
9950 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9951 OMPD_task, DirName, nullptr, D->getBeginLoc());
9952 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9953 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9954 return Res;
9955}
9956
9957template <typename Derived>
9958StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9959 OMPTaskyieldDirective *D) {
9960 DeclarationNameInfo DirName;
9961 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9962 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9963 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9964 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9965 return Res;
9966}
9967
9968template <typename Derived>
9969StmtResult
9970TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9971 DeclarationNameInfo DirName;
9972 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9973 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9974 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9975 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9976 return Res;
9977}
9978
9979template <typename Derived>
9980StmtResult
9981TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9982 DeclarationNameInfo DirName;
9983 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9984 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9985 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9986 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9987 return Res;
9988}
9989
9990template <typename Derived>
9991StmtResult
9992TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9993 DeclarationNameInfo DirName;
9994 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9995 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9996 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9997 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9998 return Res;
9999}
10000
10001template <typename Derived>
10002StmtResult
10003TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10004 DeclarationNameInfo DirName;
10005 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10006 OMPD_error, DirName, nullptr, D->getBeginLoc());
10007 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10008 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10009 return Res;
10010}
10011
10012template <typename Derived>
10013StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10014 OMPTaskgroupDirective *D) {
10015 DeclarationNameInfo DirName;
10016 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10017 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10018 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10019 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10020 return Res;
10021}
10022
10023template <typename Derived>
10024StmtResult
10025TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10026 DeclarationNameInfo DirName;
10027 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10028 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10029 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10030 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10031 return Res;
10032}
10033
10034template <typename Derived>
10035StmtResult
10036TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10037 DeclarationNameInfo DirName;
10038 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10039 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10040 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10041 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10042 return Res;
10043}
10044
10045template <typename Derived>
10046StmtResult
10047TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10048 DeclarationNameInfo DirName;
10049 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10050 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10051 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10052 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10053 return Res;
10054}
10055
10056template <typename Derived>
10057StmtResult
10058TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
10059 DeclarationNameInfo DirName;
10060 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10061 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
10062 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10063 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10064 return Res;
10065}
10066
10067template <typename Derived>
10068StmtResult
10069TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10070 DeclarationNameInfo DirName;
10071 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10072 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10073 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10074 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10075 return Res;
10076}
10077
10078template <typename Derived>
10079StmtResult
10080TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10081 DeclarationNameInfo DirName;
10082 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10083 OMPD_target, DirName, nullptr, D->getBeginLoc());
10084 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10085 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10086 return Res;
10087}
10088
10089template <typename Derived>
10090StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10091 OMPTargetDataDirective *D) {
10092 DeclarationNameInfo DirName;
10093 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10094 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10095 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10096 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10097 return Res;
10098}
10099
10100template <typename Derived>
10101StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10102 OMPTargetEnterDataDirective *D) {
10103 DeclarationNameInfo DirName;
10104 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10105 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10106 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10107 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10108 return Res;
10109}
10110
10111template <typename Derived>
10112StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10113 OMPTargetExitDataDirective *D) {
10114 DeclarationNameInfo DirName;
10115 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10116 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10117 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10118 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10119 return Res;
10120}
10121
10122template <typename Derived>
10123StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10124 OMPTargetParallelDirective *D) {
10125 DeclarationNameInfo DirName;
10126 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10127 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10128 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10129 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10130 return Res;
10131}
10132
10133template <typename Derived>
10134StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10135 OMPTargetParallelForDirective *D) {
10136 DeclarationNameInfo DirName;
10137 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10138 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10139 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10140 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10141 return Res;
10142}
10143
10144template <typename Derived>
10145StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10146 OMPTargetUpdateDirective *D) {
10147 DeclarationNameInfo DirName;
10148 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10149 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10150 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10151 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10152 return Res;
10153}
10154
10155template <typename Derived>
10156StmtResult
10157TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10158 DeclarationNameInfo DirName;
10159 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10160 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10161 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10162 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10163 return Res;
10164}
10165
10166template <typename Derived>
10167StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10168 OMPCancellationPointDirective *D) {
10169 DeclarationNameInfo DirName;
10170 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10171 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10172 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10173 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10174 return Res;
10175}
10176
10177template <typename Derived>
10178StmtResult
10179TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10180 DeclarationNameInfo DirName;
10181 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10182 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10183 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10184 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10185 return Res;
10186}
10187
10188template <typename Derived>
10189StmtResult
10190TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10191 DeclarationNameInfo DirName;
10192 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10193 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10194 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10195 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10196 return Res;
10197}
10198
10199template <typename Derived>
10200StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10201 OMPTaskLoopSimdDirective *D) {
10202 DeclarationNameInfo DirName;
10203 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10204 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10205 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10206 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10207 return Res;
10208}
10209
10210template <typename Derived>
10211StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10212 OMPMasterTaskLoopDirective *D) {
10213 DeclarationNameInfo DirName;
10214 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10215 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10216 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10217 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10218 return Res;
10219}
10220
10221template <typename Derived>
10222StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10223 OMPMaskedTaskLoopDirective *D) {
10224 DeclarationNameInfo DirName;
10225 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10226 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10227 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10228 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10229 return Res;
10230}
10231
10232template <typename Derived>
10233StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10234 OMPMasterTaskLoopSimdDirective *D) {
10235 DeclarationNameInfo DirName;
10236 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10237 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10238 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10239 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10240 return Res;
10241}
10242
10243template <typename Derived>
10244StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10245 OMPMaskedTaskLoopSimdDirective *D) {
10246 DeclarationNameInfo DirName;
10247 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10248 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10249 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10250 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10251 return Res;
10252}
10253
10254template <typename Derived>
10255StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10256 OMPParallelMasterTaskLoopDirective *D) {
10257 DeclarationNameInfo DirName;
10258 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10259 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10260 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10261 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10262 return Res;
10263}
10264
10265template <typename Derived>
10266StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10267 OMPParallelMaskedTaskLoopDirective *D) {
10268 DeclarationNameInfo DirName;
10269 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10270 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10271 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10272 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10273 return Res;
10274}
10275
10276template <typename Derived>
10277StmtResult
10278TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10279 OMPParallelMasterTaskLoopSimdDirective *D) {
10280 DeclarationNameInfo DirName;
10281 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10282 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10283 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10284 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10285 return Res;
10286}
10287
10288template <typename Derived>
10289StmtResult
10290TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10291 OMPParallelMaskedTaskLoopSimdDirective *D) {
10292 DeclarationNameInfo DirName;
10293 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10294 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10295 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10296 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10297 return Res;
10298}
10299
10300template <typename Derived>
10301StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10302 OMPDistributeDirective *D) {
10303 DeclarationNameInfo DirName;
10304 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10305 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10306 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10307 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10308 return Res;
10309}
10310
10311template <typename Derived>
10312StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10313 OMPDistributeParallelForDirective *D) {
10314 DeclarationNameInfo DirName;
10315 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10316 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10317 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10318 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10319 return Res;
10320}
10321
10322template <typename Derived>
10323StmtResult
10324TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10325 OMPDistributeParallelForSimdDirective *D) {
10326 DeclarationNameInfo DirName;
10327 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10328 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10329 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10330 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10331 return Res;
10332}
10333
10334template <typename Derived>
10335StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10336 OMPDistributeSimdDirective *D) {
10337 DeclarationNameInfo DirName;
10338 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10339 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10340 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10341 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10342 return Res;
10343}
10344
10345template <typename Derived>
10346StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10347 OMPTargetParallelForSimdDirective *D) {
10348 DeclarationNameInfo DirName;
10349 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10350 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10351 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10352 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10353 return Res;
10354}
10355
10356template <typename Derived>
10357StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10358 OMPTargetSimdDirective *D) {
10359 DeclarationNameInfo DirName;
10360 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10361 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10362 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10363 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10364 return Res;
10365}
10366
10367template <typename Derived>
10368StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10369 OMPTeamsDistributeDirective *D) {
10370 DeclarationNameInfo DirName;
10371 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10372 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10373 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10374 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10375 return Res;
10376}
10377
10378template <typename Derived>
10379StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10380 OMPTeamsDistributeSimdDirective *D) {
10381 DeclarationNameInfo DirName;
10382 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10383 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10384 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10385 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10386 return Res;
10387}
10388
10389template <typename Derived>
10390StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10391 OMPTeamsDistributeParallelForSimdDirective *D) {
10392 DeclarationNameInfo DirName;
10393 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10394 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10395 D->getBeginLoc());
10396 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10397 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10398 return Res;
10399}
10400
10401template <typename Derived>
10402StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10403 OMPTeamsDistributeParallelForDirective *D) {
10404 DeclarationNameInfo DirName;
10405 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10406 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10407 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10408 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10409 return Res;
10410}
10411
10412template <typename Derived>
10413StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10414 OMPTargetTeamsDirective *D) {
10415 DeclarationNameInfo DirName;
10416 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10417 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10418 auto Res = getDerived().TransformOMPExecutableDirective(D);
10419 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10420 return Res;
10421}
10422
10423template <typename Derived>
10424StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10425 OMPTargetTeamsDistributeDirective *D) {
10426 DeclarationNameInfo DirName;
10427 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10428 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10429 auto Res = getDerived().TransformOMPExecutableDirective(D);
10430 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10431 return Res;
10432}
10433
10434template <typename Derived>
10435StmtResult
10436TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10437 OMPTargetTeamsDistributeParallelForDirective *D) {
10438 DeclarationNameInfo DirName;
10439 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10440 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10441 D->getBeginLoc());
10442 auto Res = getDerived().TransformOMPExecutableDirective(D);
10443 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10444 return Res;
10445}
10446
10447template <typename Derived>
10448StmtResult TreeTransform<Derived>::
10449 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10450 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10451 DeclarationNameInfo DirName;
10452 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10453 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10454 D->getBeginLoc());
10455 auto Res = getDerived().TransformOMPExecutableDirective(D);
10456 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10457 return Res;
10458}
10459
10460template <typename Derived>
10461StmtResult
10462TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10463 OMPTargetTeamsDistributeSimdDirective *D) {
10464 DeclarationNameInfo DirName;
10465 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10466 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10467 auto Res = getDerived().TransformOMPExecutableDirective(D);
10468 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10469 return Res;
10470}
10471
10472template <typename Derived>
10473StmtResult
10474TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10475 DeclarationNameInfo DirName;
10476 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10477 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10478 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10479 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10480 return Res;
10481}
10482
10483template <typename Derived>
10484StmtResult
10485TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10486 DeclarationNameInfo DirName;
10487 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10488 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10489 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10490 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10491 return Res;
10492}
10493
10494template <typename Derived>
10495StmtResult
10496TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10497 DeclarationNameInfo DirName;
10498 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10499 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10500 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10501 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10502 return Res;
10503}
10504
10505template <typename Derived>
10506StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10507 OMPGenericLoopDirective *D) {
10508 DeclarationNameInfo DirName;
10509 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10510 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10511 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10512 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10513 return Res;
10514}
10515
10516template <typename Derived>
10517StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10518 OMPTeamsGenericLoopDirective *D) {
10519 DeclarationNameInfo DirName;
10520 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10521 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10522 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10523 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10524 return Res;
10525}
10526
10527template <typename Derived>
10528StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10529 OMPTargetTeamsGenericLoopDirective *D) {
10530 DeclarationNameInfo DirName;
10531 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10532 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10533 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10534 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10535 return Res;
10536}
10537
10538template <typename Derived>
10539StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10540 OMPParallelGenericLoopDirective *D) {
10541 DeclarationNameInfo DirName;
10542 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10543 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10544 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10545 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10546 return Res;
10547}
10548
10549template <typename Derived>
10550StmtResult
10551TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10552 OMPTargetParallelGenericLoopDirective *D) {
10553 DeclarationNameInfo DirName;
10554 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10555 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10556 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10557 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10558 return Res;
10559}
10560
10561//===----------------------------------------------------------------------===//
10562// OpenMP clause transformation
10563//===----------------------------------------------------------------------===//
10564template <typename Derived>
10565OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10566 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10567 if (Cond.isInvalid())
10568 return nullptr;
10569 return getDerived().RebuildOMPIfClause(
10570 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10571 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10572}
10573
10574template <typename Derived>
10575OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10576 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10577 if (Cond.isInvalid())
10578 return nullptr;
10579 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10580 C->getLParenLoc(), C->getEndLoc());
10581}
10582
10583template <typename Derived>
10584OMPClause *
10585TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10586 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10587 if (NumThreads.isInvalid())
10588 return nullptr;
10589 return getDerived().RebuildOMPNumThreadsClause(
10590 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10591 C->getModifierLoc(), C->getEndLoc());
10592}
10593
10594template <typename Derived>
10595OMPClause *
10596TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10597 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10598 if (E.isInvalid())
10599 return nullptr;
10600 return getDerived().RebuildOMPSafelenClause(
10601 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10602}
10603
10604template <typename Derived>
10605OMPClause *
10606TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10607 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10608 if (E.isInvalid())
10609 return nullptr;
10610 return getDerived().RebuildOMPAllocatorClause(
10611 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10612}
10613
10614template <typename Derived>
10615OMPClause *
10616TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10617 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10618 if (E.isInvalid())
10619 return nullptr;
10620 return getDerived().RebuildOMPSimdlenClause(
10621 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10622}
10623
10624template <typename Derived>
10625OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10626 SmallVector<Expr *, 4> TransformedSizes;
10627 TransformedSizes.reserve(N: C->getNumSizes());
10628 bool Changed = false;
10629 for (Expr *E : C->getSizesRefs()) {
10630 if (!E) {
10631 TransformedSizes.push_back(Elt: nullptr);
10632 continue;
10633 }
10634
10635 ExprResult T = getDerived().TransformExpr(E);
10636 if (T.isInvalid())
10637 return nullptr;
10638 if (E != T.get())
10639 Changed = true;
10640 TransformedSizes.push_back(Elt: T.get());
10641 }
10642
10643 if (!Changed && !getDerived().AlwaysRebuild())
10644 return C;
10645 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10646 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10647}
10648
10649template <typename Derived>
10650OMPClause *
10651TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
10652 SmallVector<Expr *, 4> TransformedCounts;
10653 TransformedCounts.reserve(N: C->getNumCounts());
10654 for (Expr *E : C->getCountsRefs()) {
10655 if (!E) {
10656 TransformedCounts.push_back(Elt: nullptr);
10657 continue;
10658 }
10659
10660 ExprResult T = getDerived().TransformExpr(E);
10661 if (T.isInvalid())
10662 return nullptr;
10663 TransformedCounts.push_back(Elt: T.get());
10664 }
10665
10666 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
10667 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
10668 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
10669}
10670
10671template <typename Derived>
10672OMPClause *
10673TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10674 SmallVector<Expr *> TransformedArgs;
10675 TransformedArgs.reserve(N: C->getNumLoops());
10676 bool Changed = false;
10677 for (Expr *E : C->getArgsRefs()) {
10678 if (!E) {
10679 TransformedArgs.push_back(Elt: nullptr);
10680 continue;
10681 }
10682
10683 ExprResult T = getDerived().TransformExpr(E);
10684 if (T.isInvalid())
10685 return nullptr;
10686 if (E != T.get())
10687 Changed = true;
10688 TransformedArgs.push_back(Elt: T.get());
10689 }
10690
10691 if (!Changed && !getDerived().AlwaysRebuild())
10692 return C;
10693 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10694 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10695}
10696
10697template <typename Derived>
10698OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10699 if (!getDerived().AlwaysRebuild())
10700 return C;
10701 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10702}
10703
10704template <typename Derived>
10705OMPClause *
10706TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10707 ExprResult T = getDerived().TransformExpr(C->getFactor());
10708 if (T.isInvalid())
10709 return nullptr;
10710 Expr *Factor = T.get();
10711 bool Changed = Factor != C->getFactor();
10712
10713 if (!Changed && !getDerived().AlwaysRebuild())
10714 return C;
10715 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10716 EndLoc: C->getEndLoc());
10717}
10718
10719template <typename Derived>
10720OMPClause *
10721TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
10722 ExprResult F = getDerived().TransformExpr(C->getFirst());
10723 if (F.isInvalid())
10724 return nullptr;
10725
10726 ExprResult Cn = getDerived().TransformExpr(C->getCount());
10727 if (Cn.isInvalid())
10728 return nullptr;
10729
10730 Expr *First = F.get();
10731 Expr *Count = Cn.get();
10732
10733 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
10734
10735 // If no changes and AlwaysRebuild() is false, return the original clause
10736 if (!Changed && !getDerived().AlwaysRebuild())
10737 return C;
10738
10739 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
10740 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
10741 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
10742}
10743
10744template <typename Derived>
10745OMPClause *
10746TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10747 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10748 if (E.isInvalid())
10749 return nullptr;
10750 return getDerived().RebuildOMPCollapseClause(
10751 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10752}
10753
10754template <typename Derived>
10755OMPClause *
10756TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10757 return getDerived().RebuildOMPDefaultClause(
10758 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
10759 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
10760 C->getEndLoc());
10761}
10762
10763template <typename Derived>
10764OMPClause *
10765TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
10766 // No need to rebuild this clause, no template-dependent parameters.
10767 return C;
10768}
10769
10770template <typename Derived>
10771OMPClause *
10772TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
10773 Expr *Impex = C->getImpexType();
10774 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
10775
10776 if (TransformedImpex.isInvalid())
10777 return nullptr;
10778
10779 return getDerived().RebuildOMPTransparentClause(
10780 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
10781 C->getEndLoc());
10782}
10783
10784template <typename Derived>
10785OMPClause *
10786TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10787 return getDerived().RebuildOMPProcBindClause(
10788 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10789 C->getLParenLoc(), C->getEndLoc());
10790}
10791
10792template <typename Derived>
10793OMPClause *
10794TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10795 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10796 if (E.isInvalid())
10797 return nullptr;
10798 return getDerived().RebuildOMPScheduleClause(
10799 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10800 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10801 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10802 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10803}
10804
10805template <typename Derived>
10806OMPClause *
10807TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10808 ExprResult E;
10809 if (auto *Num = C->getNumForLoops()) {
10810 E = getDerived().TransformExpr(Num);
10811 if (E.isInvalid())
10812 return nullptr;
10813 }
10814 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10815 C->getLParenLoc(), E.get());
10816}
10817
10818template <typename Derived>
10819OMPClause *
10820TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10821 ExprResult E;
10822 if (Expr *Evt = C->getEventHandler()) {
10823 E = getDerived().TransformExpr(Evt);
10824 if (E.isInvalid())
10825 return nullptr;
10826 }
10827 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10828 C->getLParenLoc(), C->getEndLoc());
10829}
10830
10831template <typename Derived>
10832OMPClause *
10833TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10834 ExprResult Cond;
10835 if (auto *Condition = C->getCondition()) {
10836 Cond = getDerived().TransformExpr(Condition);
10837 if (Cond.isInvalid())
10838 return nullptr;
10839 }
10840 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
10841 C->getLParenLoc(), C->getEndLoc());
10842}
10843
10844template <typename Derived>
10845OMPClause *
10846TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10847 // No need to rebuild this clause, no template-dependent parameters.
10848 return C;
10849}
10850
10851template <typename Derived>
10852OMPClause *
10853TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10854 // No need to rebuild this clause, no template-dependent parameters.
10855 return C;
10856}
10857
10858template <typename Derived>
10859OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10860 // No need to rebuild this clause, no template-dependent parameters.
10861 return C;
10862}
10863
10864template <typename Derived>
10865OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10866 // No need to rebuild this clause, no template-dependent parameters.
10867 return C;
10868}
10869
10870template <typename Derived>
10871OMPClause *
10872TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10873 // No need to rebuild this clause, no template-dependent parameters.
10874 return C;
10875}
10876
10877template <typename Derived>
10878OMPClause *
10879TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10880 // No need to rebuild this clause, no template-dependent parameters.
10881 return C;
10882}
10883
10884template <typename Derived>
10885OMPClause *
10886TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10887 // No need to rebuild this clause, no template-dependent parameters.
10888 return C;
10889}
10890
10891template <typename Derived>
10892OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10893 // No need to rebuild this clause, no template-dependent parameters.
10894 return C;
10895}
10896
10897template <typename Derived>
10898OMPClause *
10899TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10900 return C;
10901}
10902
10903template <typename Derived>
10904OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10905 ExprResult E = getDerived().TransformExpr(C->getExpr());
10906 if (E.isInvalid())
10907 return nullptr;
10908 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10909 C->getLParenLoc(), C->getEndLoc());
10910}
10911
10912template <typename Derived>
10913OMPClause *
10914TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10915 return C;
10916}
10917
10918template <typename Derived>
10919OMPClause *
10920TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10921 return C;
10922}
10923template <typename Derived>
10924OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10925 OMPNoOpenMPRoutinesClause *C) {
10926 return C;
10927}
10928template <typename Derived>
10929OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10930 OMPNoOpenMPConstructsClause *C) {
10931 return C;
10932}
10933template <typename Derived>
10934OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10935 OMPNoParallelismClause *C) {
10936 return C;
10937}
10938
10939template <typename Derived>
10940OMPClause *
10941TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10942 // No need to rebuild this clause, no template-dependent parameters.
10943 return C;
10944}
10945
10946template <typename Derived>
10947OMPClause *
10948TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10949 // No need to rebuild this clause, no template-dependent parameters.
10950 return C;
10951}
10952
10953template <typename Derived>
10954OMPClause *
10955TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10956 // No need to rebuild this clause, no template-dependent parameters.
10957 return C;
10958}
10959
10960template <typename Derived>
10961OMPClause *
10962TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10963 // No need to rebuild this clause, no template-dependent parameters.
10964 return C;
10965}
10966
10967template <typename Derived>
10968OMPClause *
10969TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10970 // No need to rebuild this clause, no template-dependent parameters.
10971 return C;
10972}
10973
10974template <typename Derived>
10975OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10976 // No need to rebuild this clause, no template-dependent parameters.
10977 return C;
10978}
10979
10980template <typename Derived>
10981OMPClause *
10982TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10983 // No need to rebuild this clause, no template-dependent parameters.
10984 return C;
10985}
10986
10987template <typename Derived>
10988OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10989 // No need to rebuild this clause, no template-dependent parameters.
10990 return C;
10991}
10992
10993template <typename Derived>
10994OMPClause *
10995TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10996 // No need to rebuild this clause, no template-dependent parameters.
10997 return C;
10998}
10999
11000template <typename Derived>
11001OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11002 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11003 if (IVR.isInvalid())
11004 return nullptr;
11005
11006 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11007 for (OMPInitClause::PrefView P : C->prefs()) {
11008 Expr *NewFr = nullptr;
11009 if (P.Fr) {
11010 ExprResult ER = getDerived().TransformExpr(P.Fr);
11011 if (ER.isInvalid())
11012 return nullptr;
11013 NewFr = ER.get();
11014 }
11015 SmallVector<Expr *, 2> NewAttrs;
11016 NewAttrs.reserve(N: P.Attrs.size());
11017 for (Expr *A : P.Attrs) {
11018 ExprResult ER = getDerived().TransformExpr(A);
11019 if (ER.isInvalid())
11020 return nullptr;
11021 NewAttrs.push_back(Elt: ER.get());
11022 }
11023 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11024 }
11025 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11026 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11027 C->getBeginLoc(), C->getLParenLoc(),
11028 C->getVarLoc(), C->getEndLoc());
11029}
11030
11031template <typename Derived>
11032OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11033 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11034 if (ER.isInvalid())
11035 return nullptr;
11036 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11037 C->getLParenLoc(), C->getVarLoc(),
11038 C->getEndLoc());
11039}
11040
11041template <typename Derived>
11042OMPClause *
11043TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11044 ExprResult ER;
11045 if (Expr *IV = C->getInteropVar()) {
11046 ER = getDerived().TransformExpr(IV);
11047 if (ER.isInvalid())
11048 return nullptr;
11049 }
11050 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11051 C->getLParenLoc(), C->getVarLoc(),
11052 C->getEndLoc());
11053}
11054
11055template <typename Derived>
11056OMPClause *
11057TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11058 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11059 if (Cond.isInvalid())
11060 return nullptr;
11061 return getDerived().RebuildOMPNovariantsClause(
11062 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11063}
11064
11065template <typename Derived>
11066OMPClause *
11067TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11068 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11069 if (Cond.isInvalid())
11070 return nullptr;
11071 return getDerived().RebuildOMPNocontextClause(
11072 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11073}
11074
11075template <typename Derived>
11076OMPClause *
11077TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11078 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11079 if (ThreadID.isInvalid())
11080 return nullptr;
11081 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11082 C->getLParenLoc(), C->getEndLoc());
11083}
11084
11085template <typename Derived>
11086OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11087 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11088 if (E.isInvalid())
11089 return nullptr;
11090 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11091 C->getLParenLoc(), C->getEndLoc());
11092}
11093
11094template <typename Derived>
11095OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11096 OMPUnifiedAddressClause *C) {
11097 llvm_unreachable("unified_address clause cannot appear in dependent context");
11098}
11099
11100template <typename Derived>
11101OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11102 OMPUnifiedSharedMemoryClause *C) {
11103 llvm_unreachable(
11104 "unified_shared_memory clause cannot appear in dependent context");
11105}
11106
11107template <typename Derived>
11108OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11109 OMPReverseOffloadClause *C) {
11110 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11111}
11112
11113template <typename Derived>
11114OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11115 OMPDynamicAllocatorsClause *C) {
11116 llvm_unreachable(
11117 "dynamic_allocators clause cannot appear in dependent context");
11118}
11119
11120template <typename Derived>
11121OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11122 OMPAtomicDefaultMemOrderClause *C) {
11123 llvm_unreachable(
11124 "atomic_default_mem_order clause cannot appear in dependent context");
11125}
11126
11127template <typename Derived>
11128OMPClause *
11129TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11130 llvm_unreachable("self_maps clause cannot appear in dependent context");
11131}
11132
11133template <typename Derived>
11134OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11135 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11136 C->getBeginLoc(), C->getLParenLoc(),
11137 C->getEndLoc());
11138}
11139
11140template <typename Derived>
11141OMPClause *
11142TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11143 return getDerived().RebuildOMPSeverityClause(
11144 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11145 C->getLParenLoc(), C->getEndLoc());
11146}
11147
11148template <typename Derived>
11149OMPClause *
11150TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11151 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11152 if (E.isInvalid())
11153 return nullptr;
11154 return getDerived().RebuildOMPMessageClause(
11155 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11156}
11157
11158template <typename Derived>
11159OMPClause *
11160TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11161 llvm::SmallVector<Expr *, 16> Vars;
11162 Vars.reserve(N: C->varlist_size());
11163 for (auto *VE : C->varlist()) {
11164 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11165 if (EVar.isInvalid())
11166 return nullptr;
11167 Vars.push_back(Elt: EVar.get());
11168 }
11169 return getDerived().RebuildOMPPrivateClause(
11170 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11171}
11172
11173template <typename Derived>
11174OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11175 OMPFirstprivateClause *C) {
11176 llvm::SmallVector<Expr *, 16> Vars;
11177 Vars.reserve(N: C->varlist_size());
11178 for (auto *VE : C->varlist()) {
11179 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11180 if (EVar.isInvalid())
11181 return nullptr;
11182 Vars.push_back(Elt: EVar.get());
11183 }
11184 return getDerived().RebuildOMPFirstprivateClause(
11185 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11186}
11187
11188template <typename Derived>
11189OMPClause *
11190TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11191 llvm::SmallVector<Expr *, 16> Vars;
11192 Vars.reserve(N: C->varlist_size());
11193 for (auto *VE : C->varlist()) {
11194 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11195 if (EVar.isInvalid())
11196 return nullptr;
11197 Vars.push_back(Elt: EVar.get());
11198 }
11199 return getDerived().RebuildOMPLastprivateClause(
11200 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11201 C->getLParenLoc(), C->getEndLoc());
11202}
11203
11204template <typename Derived>
11205OMPClause *
11206TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11207 llvm::SmallVector<Expr *, 16> Vars;
11208 Vars.reserve(N: C->varlist_size());
11209 for (auto *VE : C->varlist()) {
11210 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11211 if (EVar.isInvalid())
11212 return nullptr;
11213 Vars.push_back(Elt: EVar.get());
11214 }
11215 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11216 C->getLParenLoc(), C->getEndLoc());
11217}
11218
11219template <typename Derived>
11220OMPClause *
11221TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11222 llvm::SmallVector<Expr *, 16> Vars;
11223 Vars.reserve(N: C->varlist_size());
11224 for (auto *VE : C->varlist()) {
11225 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11226 if (EVar.isInvalid())
11227 return nullptr;
11228 Vars.push_back(Elt: EVar.get());
11229 }
11230 CXXScopeSpec ReductionIdScopeSpec;
11231 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11232
11233 DeclarationNameInfo NameInfo = C->getNameInfo();
11234 if (NameInfo.getName()) {
11235 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11236 if (!NameInfo.getName())
11237 return nullptr;
11238 }
11239 // Build a list of all UDR decls with the same names ranged by the Scopes.
11240 // The Scope boundary is a duplication of the previous decl.
11241 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11242 for (auto *E : C->reduction_ops()) {
11243 // Transform all the decls.
11244 if (E) {
11245 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11246 UnresolvedSet<8> Decls;
11247 for (auto *D : ULE->decls()) {
11248 NamedDecl *InstD =
11249 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11250 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11251 }
11252 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11253 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11254 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11255 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11256 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11257 } else
11258 UnresolvedReductions.push_back(Elt: nullptr);
11259 }
11260 return getDerived().RebuildOMPReductionClause(
11261 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11262 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11263 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11264}
11265
11266template <typename Derived>
11267OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11268 OMPTaskReductionClause *C) {
11269 llvm::SmallVector<Expr *, 16> Vars;
11270 Vars.reserve(N: C->varlist_size());
11271 for (auto *VE : C->varlist()) {
11272 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11273 if (EVar.isInvalid())
11274 return nullptr;
11275 Vars.push_back(Elt: EVar.get());
11276 }
11277 CXXScopeSpec ReductionIdScopeSpec;
11278 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11279
11280 DeclarationNameInfo NameInfo = C->getNameInfo();
11281 if (NameInfo.getName()) {
11282 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11283 if (!NameInfo.getName())
11284 return nullptr;
11285 }
11286 // Build a list of all UDR decls with the same names ranged by the Scopes.
11287 // The Scope boundary is a duplication of the previous decl.
11288 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11289 for (auto *E : C->reduction_ops()) {
11290 // Transform all the decls.
11291 if (E) {
11292 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11293 UnresolvedSet<8> Decls;
11294 for (auto *D : ULE->decls()) {
11295 NamedDecl *InstD =
11296 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11297 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11298 }
11299 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11300 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11301 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11302 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11303 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11304 } else
11305 UnresolvedReductions.push_back(Elt: nullptr);
11306 }
11307 return getDerived().RebuildOMPTaskReductionClause(
11308 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11309 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11310}
11311
11312template <typename Derived>
11313OMPClause *
11314TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11315 llvm::SmallVector<Expr *, 16> Vars;
11316 Vars.reserve(N: C->varlist_size());
11317 for (auto *VE : C->varlist()) {
11318 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11319 if (EVar.isInvalid())
11320 return nullptr;
11321 Vars.push_back(Elt: EVar.get());
11322 }
11323 CXXScopeSpec ReductionIdScopeSpec;
11324 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11325
11326 DeclarationNameInfo NameInfo = C->getNameInfo();
11327 if (NameInfo.getName()) {
11328 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11329 if (!NameInfo.getName())
11330 return nullptr;
11331 }
11332 // Build a list of all UDR decls with the same names ranged by the Scopes.
11333 // The Scope boundary is a duplication of the previous decl.
11334 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11335 for (auto *E : C->reduction_ops()) {
11336 // Transform all the decls.
11337 if (E) {
11338 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11339 UnresolvedSet<8> Decls;
11340 for (auto *D : ULE->decls()) {
11341 NamedDecl *InstD =
11342 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11343 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11344 }
11345 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11346 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11347 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11348 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11349 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11350 } else
11351 UnresolvedReductions.push_back(Elt: nullptr);
11352 }
11353 return getDerived().RebuildOMPInReductionClause(
11354 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11355 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11356}
11357
11358template <typename Derived>
11359OMPClause *
11360TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11361 llvm::SmallVector<Expr *, 16> Vars;
11362 Vars.reserve(N: C->varlist_size());
11363 for (auto *VE : C->varlist()) {
11364 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11365 if (EVar.isInvalid())
11366 return nullptr;
11367 Vars.push_back(Elt: EVar.get());
11368 }
11369 ExprResult Step = getDerived().TransformExpr(C->getStep());
11370 if (Step.isInvalid())
11371 return nullptr;
11372 return getDerived().RebuildOMPLinearClause(
11373 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11374 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11375 C->getEndLoc());
11376}
11377
11378template <typename Derived>
11379OMPClause *
11380TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11381 llvm::SmallVector<Expr *, 16> Vars;
11382 Vars.reserve(N: C->varlist_size());
11383 for (auto *VE : C->varlist()) {
11384 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11385 if (EVar.isInvalid())
11386 return nullptr;
11387 Vars.push_back(Elt: EVar.get());
11388 }
11389 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11390 if (Alignment.isInvalid())
11391 return nullptr;
11392 return getDerived().RebuildOMPAlignedClause(
11393 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11394 C->getColonLoc(), C->getEndLoc());
11395}
11396
11397template <typename Derived>
11398OMPClause *
11399TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11400 llvm::SmallVector<Expr *, 16> Vars;
11401 Vars.reserve(N: C->varlist_size());
11402 for (auto *VE : C->varlist()) {
11403 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11404 if (EVar.isInvalid())
11405 return nullptr;
11406 Vars.push_back(Elt: EVar.get());
11407 }
11408 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11409 C->getLParenLoc(), C->getEndLoc());
11410}
11411
11412template <typename Derived>
11413OMPClause *
11414TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11415 llvm::SmallVector<Expr *, 16> Vars;
11416 Vars.reserve(N: C->varlist_size());
11417 for (auto *VE : C->varlist()) {
11418 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11419 if (EVar.isInvalid())
11420 return nullptr;
11421 Vars.push_back(Elt: EVar.get());
11422 }
11423 return getDerived().RebuildOMPCopyprivateClause(
11424 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11425}
11426
11427template <typename Derived>
11428OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11429 llvm::SmallVector<Expr *, 16> Vars;
11430 Vars.reserve(N: C->varlist_size());
11431 for (auto *VE : C->varlist()) {
11432 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11433 if (EVar.isInvalid())
11434 return nullptr;
11435 Vars.push_back(Elt: EVar.get());
11436 }
11437 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11438 C->getLParenLoc(), C->getEndLoc());
11439}
11440
11441template <typename Derived>
11442OMPClause *
11443TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11444 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11445 if (E.isInvalid())
11446 return nullptr;
11447 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11448 C->getLParenLoc(), C->getEndLoc());
11449}
11450
11451template <typename Derived>
11452OMPClause *
11453TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11454 llvm::SmallVector<Expr *, 16> Vars;
11455 Expr *DepModifier = C->getModifier();
11456 if (DepModifier) {
11457 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11458 if (DepModRes.isInvalid())
11459 return nullptr;
11460 DepModifier = DepModRes.get();
11461 }
11462 Vars.reserve(N: C->varlist_size());
11463 for (auto *VE : C->varlist()) {
11464 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11465 if (EVar.isInvalid())
11466 return nullptr;
11467 Vars.push_back(Elt: EVar.get());
11468 }
11469 return getDerived().RebuildOMPDependClause(
11470 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11471 C->getOmpAllMemoryLoc()},
11472 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11473}
11474
11475template <typename Derived>
11476OMPClause *
11477TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11478 ExprResult E = getDerived().TransformExpr(C->getDevice());
11479 if (E.isInvalid())
11480 return nullptr;
11481 return getDerived().RebuildOMPDeviceClause(
11482 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11483 C->getModifierLoc(), C->getEndLoc());
11484}
11485
11486template <typename Derived, class T>
11487bool transformOMPMappableExprListClause(
11488 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11489 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11490 DeclarationNameInfo &MapperIdInfo,
11491 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11492 // Transform expressions in the list.
11493 Vars.reserve(N: C->varlist_size());
11494 for (auto *VE : C->varlist()) {
11495 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11496 if (EVar.isInvalid())
11497 return true;
11498 Vars.push_back(Elt: EVar.get());
11499 }
11500 // Transform mapper scope specifier and identifier.
11501 NestedNameSpecifierLoc QualifierLoc;
11502 if (C->getMapperQualifierLoc()) {
11503 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11504 C->getMapperQualifierLoc());
11505 if (!QualifierLoc)
11506 return true;
11507 }
11508 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11509 MapperIdInfo = C->getMapperIdInfo();
11510 if (MapperIdInfo.getName()) {
11511 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11512 if (!MapperIdInfo.getName())
11513 return true;
11514 }
11515 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11516 // the previous user-defined mapper lookup in dependent environment.
11517 for (auto *E : C->mapperlists()) {
11518 // Transform all the decls.
11519 if (E) {
11520 auto *ULE = cast<UnresolvedLookupExpr>(E);
11521 UnresolvedSet<8> Decls;
11522 for (auto *D : ULE->decls()) {
11523 NamedDecl *InstD =
11524 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11525 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11526 }
11527 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11528 TT.getSema().Context, /*NamingClass=*/nullptr,
11529 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11530 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11531 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11532 } else {
11533 UnresolvedMappers.push_back(Elt: nullptr);
11534 }
11535 }
11536 return false;
11537}
11538
11539template <typename Derived>
11540OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11541 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11542 llvm::SmallVector<Expr *, 16> Vars;
11543 Expr *IteratorModifier = C->getIteratorModifier();
11544 if (IteratorModifier) {
11545 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11546 if (MapModRes.isInvalid())
11547 return nullptr;
11548 IteratorModifier = MapModRes.get();
11549 }
11550 CXXScopeSpec MapperIdScopeSpec;
11551 DeclarationNameInfo MapperIdInfo;
11552 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11553 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11554 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11555 return nullptr;
11556 return getDerived().RebuildOMPMapClause(
11557 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11558 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11559 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11560}
11561
11562template <typename Derived>
11563OMPClause *
11564TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11565 Expr *Allocator = C->getAllocator();
11566 if (Allocator) {
11567 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11568 if (AllocatorRes.isInvalid())
11569 return nullptr;
11570 Allocator = AllocatorRes.get();
11571 }
11572 Expr *Alignment = C->getAlignment();
11573 if (Alignment) {
11574 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11575 if (AlignmentRes.isInvalid())
11576 return nullptr;
11577 Alignment = AlignmentRes.get();
11578 }
11579 llvm::SmallVector<Expr *, 16> Vars;
11580 Vars.reserve(N: C->varlist_size());
11581 for (auto *VE : C->varlist()) {
11582 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11583 if (EVar.isInvalid())
11584 return nullptr;
11585 Vars.push_back(Elt: EVar.get());
11586 }
11587 return getDerived().RebuildOMPAllocateClause(
11588 Allocator, Alignment, C->getFirstAllocateModifier(),
11589 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11590 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11591 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11592}
11593
11594template <typename Derived>
11595OMPClause *
11596TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11597 llvm::SmallVector<Expr *, 3> Vars;
11598 Vars.reserve(N: C->varlist_size());
11599 for (auto *VE : C->varlist()) {
11600 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11601 if (EVar.isInvalid())
11602 return nullptr;
11603 Vars.push_back(Elt: EVar.get());
11604 }
11605 Expr *ModifierExpr = C->getModifierExpr();
11606 if (ModifierExpr) {
11607 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
11608 if (EVar.isInvalid())
11609 return nullptr;
11610 ModifierExpr = EVar.get();
11611 }
11612 return getDerived().RebuildOMPNumTeamsClause(
11613 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
11614 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11615}
11616
11617template <typename Derived>
11618OMPClause *
11619TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11620 llvm::SmallVector<Expr *, 3> Vars;
11621 Vars.reserve(N: C->varlist_size());
11622 for (auto *VE : C->varlist()) {
11623 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11624 if (EVar.isInvalid())
11625 return nullptr;
11626 Vars.push_back(Elt: EVar.get());
11627 }
11628 return getDerived().RebuildOMPThreadLimitClause(
11629 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11630}
11631
11632template <typename Derived>
11633OMPClause *
11634TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11635 ExprResult E = getDerived().TransformExpr(C->getPriority());
11636 if (E.isInvalid())
11637 return nullptr;
11638 return getDerived().RebuildOMPPriorityClause(
11639 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11640}
11641
11642template <typename Derived>
11643OMPClause *
11644TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11645 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11646 if (E.isInvalid())
11647 return nullptr;
11648 return getDerived().RebuildOMPGrainsizeClause(
11649 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11650 C->getModifierLoc(), C->getEndLoc());
11651}
11652
11653template <typename Derived>
11654OMPClause *
11655TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11656 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11657 if (E.isInvalid())
11658 return nullptr;
11659 return getDerived().RebuildOMPNumTasksClause(
11660 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11661 C->getModifierLoc(), C->getEndLoc());
11662}
11663
11664template <typename Derived>
11665OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11666 ExprResult E = getDerived().TransformExpr(C->getHint());
11667 if (E.isInvalid())
11668 return nullptr;
11669 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11670 C->getLParenLoc(), C->getEndLoc());
11671}
11672
11673template <typename Derived>
11674OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11675 OMPDistScheduleClause *C) {
11676 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11677 if (E.isInvalid())
11678 return nullptr;
11679 return getDerived().RebuildOMPDistScheduleClause(
11680 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11681 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11682}
11683
11684template <typename Derived>
11685OMPClause *
11686TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11687 // Rebuild Defaultmap Clause since we need to invoke the checking of
11688 // defaultmap(none:variable-category) after template initialization.
11689 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11690 C->getDefaultmapKind(),
11691 C->getBeginLoc(),
11692 C->getLParenLoc(),
11693 C->getDefaultmapModifierLoc(),
11694 C->getDefaultmapKindLoc(),
11695 C->getEndLoc());
11696}
11697
11698template <typename Derived>
11699OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11700 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11701 llvm::SmallVector<Expr *, 16> Vars;
11702 Expr *IteratorModifier = C->getIteratorModifier();
11703 if (IteratorModifier) {
11704 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11705 if (MapModRes.isInvalid())
11706 return nullptr;
11707 IteratorModifier = MapModRes.get();
11708 }
11709 CXXScopeSpec MapperIdScopeSpec;
11710 DeclarationNameInfo MapperIdInfo;
11711 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11712 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11713 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11714 return nullptr;
11715 return getDerived().RebuildOMPToClause(
11716 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11717 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11718 UnresolvedMappers);
11719}
11720
11721template <typename Derived>
11722OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11723 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11724 llvm::SmallVector<Expr *, 16> Vars;
11725 Expr *IteratorModifier = C->getIteratorModifier();
11726 if (IteratorModifier) {
11727 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11728 if (MapModRes.isInvalid())
11729 return nullptr;
11730 IteratorModifier = MapModRes.get();
11731 }
11732 CXXScopeSpec MapperIdScopeSpec;
11733 DeclarationNameInfo MapperIdInfo;
11734 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11735 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11736 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11737 return nullptr;
11738 return getDerived().RebuildOMPFromClause(
11739 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11740 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11741 UnresolvedMappers);
11742}
11743
11744template <typename Derived>
11745OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11746 OMPUseDevicePtrClause *C) {
11747 llvm::SmallVector<Expr *, 16> Vars;
11748 Vars.reserve(N: C->varlist_size());
11749 for (auto *VE : C->varlist()) {
11750 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11751 if (EVar.isInvalid())
11752 return nullptr;
11753 Vars.push_back(Elt: EVar.get());
11754 }
11755 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11756 return getDerived().RebuildOMPUseDevicePtrClause(
11757 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
11758}
11759
11760template <typename Derived>
11761OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11762 OMPUseDeviceAddrClause *C) {
11763 llvm::SmallVector<Expr *, 16> Vars;
11764 Vars.reserve(N: C->varlist_size());
11765 for (auto *VE : C->varlist()) {
11766 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11767 if (EVar.isInvalid())
11768 return nullptr;
11769 Vars.push_back(Elt: EVar.get());
11770 }
11771 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11772 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11773}
11774
11775template <typename Derived>
11776OMPClause *
11777TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11778 llvm::SmallVector<Expr *, 16> Vars;
11779 Vars.reserve(N: C->varlist_size());
11780 for (auto *VE : C->varlist()) {
11781 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11782 if (EVar.isInvalid())
11783 return nullptr;
11784 Vars.push_back(Elt: EVar.get());
11785 }
11786 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11787 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11788}
11789
11790template <typename Derived>
11791OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11792 OMPHasDeviceAddrClause *C) {
11793 llvm::SmallVector<Expr *, 16> Vars;
11794 Vars.reserve(N: C->varlist_size());
11795 for (auto *VE : C->varlist()) {
11796 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11797 if (EVar.isInvalid())
11798 return nullptr;
11799 Vars.push_back(Elt: EVar.get());
11800 }
11801 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11802 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11803}
11804
11805template <typename Derived>
11806OMPClause *
11807TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11808 llvm::SmallVector<Expr *, 16> Vars;
11809 Vars.reserve(N: C->varlist_size());
11810 for (auto *VE : C->varlist()) {
11811 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11812 if (EVar.isInvalid())
11813 return nullptr;
11814 Vars.push_back(Elt: EVar.get());
11815 }
11816 return getDerived().RebuildOMPNontemporalClause(
11817 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11818}
11819
11820template <typename Derived>
11821OMPClause *
11822TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11823 llvm::SmallVector<Expr *, 16> Vars;
11824 Vars.reserve(N: C->varlist_size());
11825 for (auto *VE : C->varlist()) {
11826 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11827 if (EVar.isInvalid())
11828 return nullptr;
11829 Vars.push_back(Elt: EVar.get());
11830 }
11831 return getDerived().RebuildOMPInclusiveClause(
11832 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11833}
11834
11835template <typename Derived>
11836OMPClause *
11837TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11838 llvm::SmallVector<Expr *, 16> Vars;
11839 Vars.reserve(N: C->varlist_size());
11840 for (auto *VE : C->varlist()) {
11841 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11842 if (EVar.isInvalid())
11843 return nullptr;
11844 Vars.push_back(Elt: EVar.get());
11845 }
11846 return getDerived().RebuildOMPExclusiveClause(
11847 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11848}
11849
11850template <typename Derived>
11851OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11852 OMPUsesAllocatorsClause *C) {
11853 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11854 Data.reserve(N: C->getNumberOfAllocators());
11855 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11856 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11857 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11858 if (Allocator.isInvalid())
11859 continue;
11860 ExprResult AllocatorTraits;
11861 if (Expr *AT = D.AllocatorTraits) {
11862 AllocatorTraits = getDerived().TransformExpr(AT);
11863 if (AllocatorTraits.isInvalid())
11864 continue;
11865 }
11866 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11867 NewD.Allocator = Allocator.get();
11868 NewD.AllocatorTraits = AllocatorTraits.get();
11869 NewD.LParenLoc = D.LParenLoc;
11870 NewD.RParenLoc = D.RParenLoc;
11871 }
11872 return getDerived().RebuildOMPUsesAllocatorsClause(
11873 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11874}
11875
11876template <typename Derived>
11877OMPClause *
11878TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11879 SmallVector<Expr *, 4> Locators;
11880 Locators.reserve(N: C->varlist_size());
11881 ExprResult ModifierRes;
11882 if (Expr *Modifier = C->getModifier()) {
11883 ModifierRes = getDerived().TransformExpr(Modifier);
11884 if (ModifierRes.isInvalid())
11885 return nullptr;
11886 }
11887 for (Expr *E : C->varlist()) {
11888 ExprResult Locator = getDerived().TransformExpr(E);
11889 if (Locator.isInvalid())
11890 continue;
11891 Locators.push_back(Elt: Locator.get());
11892 }
11893 return getDerived().RebuildOMPAffinityClause(
11894 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11895 ModifierRes.get(), Locators);
11896}
11897
11898template <typename Derived>
11899OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11900 return getDerived().RebuildOMPOrderClause(
11901 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11902 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11903}
11904
11905template <typename Derived>
11906OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11907 return getDerived().RebuildOMPBindClause(
11908 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11909 C->getLParenLoc(), C->getEndLoc());
11910}
11911
11912template <typename Derived>
11913OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11914 OMPXDynCGroupMemClause *C) {
11915 ExprResult Size = getDerived().TransformExpr(C->getSize());
11916 if (Size.isInvalid())
11917 return nullptr;
11918 return getDerived().RebuildOMPXDynCGroupMemClause(
11919 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11920}
11921
11922template <typename Derived>
11923OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
11924 OMPDynGroupprivateClause *C) {
11925 ExprResult Size = getDerived().TransformExpr(C->getSize());
11926 if (Size.isInvalid())
11927 return nullptr;
11928 return getDerived().RebuildOMPDynGroupprivateClause(
11929 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
11930 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
11931 C->getDynGroupprivateModifierLoc(),
11932 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
11933}
11934
11935template <typename Derived>
11936OMPClause *
11937TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11938 llvm::SmallVector<Expr *, 16> Vars;
11939 Vars.reserve(N: C->varlist_size());
11940 for (auto *VE : C->varlist()) {
11941 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11942 if (EVar.isInvalid())
11943 return nullptr;
11944 Vars.push_back(Elt: EVar.get());
11945 }
11946 return getDerived().RebuildOMPDoacrossClause(
11947 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11948 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11949}
11950
11951template <typename Derived>
11952OMPClause *
11953TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11954 SmallVector<const Attr *> NewAttrs;
11955 for (auto *A : C->getAttrs())
11956 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11957 return getDerived().RebuildOMPXAttributeClause(
11958 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11959}
11960
11961template <typename Derived>
11962OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11963 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11964}
11965
11966//===----------------------------------------------------------------------===//
11967// OpenACC transformation
11968//===----------------------------------------------------------------------===//
11969namespace {
11970template <typename Derived>
11971class OpenACCClauseTransform final
11972 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11973 TreeTransform<Derived> &Self;
11974 ArrayRef<const OpenACCClause *> ExistingClauses;
11975 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11976 OpenACCClause *NewClause = nullptr;
11977
11978 ExprResult VisitVar(Expr *VarRef) {
11979 ExprResult Res = Self.TransformExpr(VarRef);
11980
11981 if (!Res.isUsable())
11982 return Res;
11983
11984 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11985 ParsedClause.getClauseKind(),
11986 Res.get());
11987
11988 return Res;
11989 }
11990
11991 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11992 llvm::SmallVector<Expr *> InstantiatedVarList;
11993 for (Expr *CurVar : VarList) {
11994 ExprResult VarRef = VisitVar(VarRef: CurVar);
11995
11996 if (VarRef.isUsable())
11997 InstantiatedVarList.push_back(Elt: VarRef.get());
11998 }
11999
12000 return InstantiatedVarList;
12001 }
12002
12003public:
12004 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12005 ArrayRef<const OpenACCClause *> ExistingClauses,
12006 SemaOpenACC::OpenACCParsedClause &PC)
12007 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12008
12009 OpenACCClause *CreatedClause() const { return NewClause; }
12010
12011#define VISIT_CLAUSE(CLAUSE_NAME) \
12012 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12013#include "clang/Basic/OpenACCClauses.def"
12014};
12015
12016template <typename Derived>
12017void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12018 const OpenACCDefaultClause &C) {
12019 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12020
12021 NewClause = OpenACCDefaultClause::Create(
12022 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12023 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12024 EndLoc: ParsedClause.getEndLoc());
12025}
12026
12027template <typename Derived>
12028void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12029 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12030 assert(Cond && "If constructed with invalid Condition");
12031 Sema::ConditionResult Res = Self.TransformCondition(
12032 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12033
12034 if (Res.isInvalid() || !Res.get().second)
12035 return;
12036
12037 ParsedClause.setConditionDetails(Res.get().second);
12038
12039 NewClause = OpenACCIfClause::Create(
12040 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12041 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12042 EndLoc: ParsedClause.getEndLoc());
12043}
12044
12045template <typename Derived>
12046void OpenACCClauseTransform<Derived>::VisitSelfClause(
12047 const OpenACCSelfClause &C) {
12048
12049 // If this is an 'update' 'self' clause, this is actually a var list instead.
12050 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12051 llvm::SmallVector<Expr *> InstantiatedVarList;
12052 for (Expr *CurVar : C.getVarList()) {
12053 ExprResult Res = Self.TransformExpr(CurVar);
12054
12055 if (!Res.isUsable())
12056 continue;
12057
12058 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12059 ParsedClause.getClauseKind(),
12060 Res.get());
12061
12062 if (Res.isUsable())
12063 InstantiatedVarList.push_back(Elt: Res.get());
12064 }
12065
12066 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12067 ModKind: OpenACCModifierKind::Invalid);
12068
12069 NewClause = OpenACCSelfClause::Create(
12070 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12071 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12072 ParsedClause.getEndLoc());
12073 } else {
12074
12075 if (C.hasConditionExpr()) {
12076 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12077 Sema::ConditionResult Res =
12078 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12079 Sema::ConditionKind::Boolean);
12080
12081 if (Res.isInvalid() || !Res.get().second)
12082 return;
12083
12084 ParsedClause.setConditionDetails(Res.get().second);
12085 }
12086
12087 NewClause = OpenACCSelfClause::Create(
12088 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12089 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12090 ParsedClause.getEndLoc());
12091 }
12092}
12093
12094template <typename Derived>
12095void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12096 const OpenACCNumGangsClause &C) {
12097 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12098
12099 for (Expr *CurIntExpr : C.getIntExprs()) {
12100 ExprResult Res = Self.TransformExpr(CurIntExpr);
12101
12102 if (!Res.isUsable())
12103 return;
12104
12105 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12106 C.getClauseKind(),
12107 C.getBeginLoc(), Res.get());
12108 if (!Res.isUsable())
12109 return;
12110
12111 InstantiatedIntExprs.push_back(Elt: Res.get());
12112 }
12113
12114 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12115 NewClause = OpenACCNumGangsClause::Create(
12116 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12117 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12118 EndLoc: ParsedClause.getEndLoc());
12119}
12120
12121template <typename Derived>
12122void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12123 const OpenACCPrivateClause &C) {
12124 llvm::SmallVector<Expr *> InstantiatedVarList;
12125 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12126
12127 for (const auto [RefExpr, InitRecipe] :
12128 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12129 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12130
12131 if (VarRef.isUsable()) {
12132 InstantiatedVarList.push_back(Elt: VarRef.get());
12133
12134 // We only have to create a new one if it is dependent, and Sema won't
12135 // make one of these unless the type is non-dependent.
12136 if (InitRecipe.isSet())
12137 InitRecipes.push_back(Elt: InitRecipe);
12138 else
12139 InitRecipes.push_back(
12140 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12141 }
12142 }
12143 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12144 ModKind: OpenACCModifierKind::Invalid);
12145
12146 NewClause = OpenACCPrivateClause::Create(
12147 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12148 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12149 EndLoc: ParsedClause.getEndLoc());
12150}
12151
12152template <typename Derived>
12153void OpenACCClauseTransform<Derived>::VisitHostClause(
12154 const OpenACCHostClause &C) {
12155 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12156 OpenACCModifierKind::Invalid);
12157
12158 NewClause = OpenACCHostClause::Create(
12159 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12160 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12161 EndLoc: ParsedClause.getEndLoc());
12162}
12163
12164template <typename Derived>
12165void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12166 const OpenACCDeviceClause &C) {
12167 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12168 OpenACCModifierKind::Invalid);
12169
12170 NewClause = OpenACCDeviceClause::Create(
12171 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12172 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12173 EndLoc: ParsedClause.getEndLoc());
12174}
12175
12176template <typename Derived>
12177void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12178 const OpenACCFirstPrivateClause &C) {
12179 llvm::SmallVector<Expr *> InstantiatedVarList;
12180 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12181
12182 for (const auto [RefExpr, InitRecipe] :
12183 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12184 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12185
12186 if (VarRef.isUsable()) {
12187 InstantiatedVarList.push_back(Elt: VarRef.get());
12188
12189 // We only have to create a new one if it is dependent, and Sema won't
12190 // make one of these unless the type is non-dependent.
12191 if (InitRecipe.isSet())
12192 InitRecipes.push_back(Elt: InitRecipe);
12193 else
12194 InitRecipes.push_back(
12195 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12196 VarRef.get()));
12197 }
12198 }
12199 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12200 ModKind: OpenACCModifierKind::Invalid);
12201
12202 NewClause = OpenACCFirstPrivateClause::Create(
12203 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12204 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12205 EndLoc: ParsedClause.getEndLoc());
12206}
12207
12208template <typename Derived>
12209void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12210 const OpenACCNoCreateClause &C) {
12211 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12212 OpenACCModifierKind::Invalid);
12213
12214 NewClause = OpenACCNoCreateClause::Create(
12215 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12216 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12217 EndLoc: ParsedClause.getEndLoc());
12218}
12219
12220template <typename Derived>
12221void OpenACCClauseTransform<Derived>::VisitPresentClause(
12222 const OpenACCPresentClause &C) {
12223 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12224 OpenACCModifierKind::Invalid);
12225
12226 NewClause = OpenACCPresentClause::Create(
12227 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12228 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12229 EndLoc: ParsedClause.getEndLoc());
12230}
12231
12232template <typename Derived>
12233void OpenACCClauseTransform<Derived>::VisitCopyClause(
12234 const OpenACCCopyClause &C) {
12235 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12236 C.getModifierList());
12237
12238 NewClause = OpenACCCopyClause::Create(
12239 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12240 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12241 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12242 EndLoc: ParsedClause.getEndLoc());
12243}
12244
12245template <typename Derived>
12246void OpenACCClauseTransform<Derived>::VisitLinkClause(
12247 const OpenACCLinkClause &C) {
12248 llvm_unreachable("link clause not valid unless a decl transform");
12249}
12250
12251template <typename Derived>
12252void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12253 const OpenACCDeviceResidentClause &C) {
12254 llvm_unreachable("device_resident clause not valid unless a decl transform");
12255}
12256template <typename Derived>
12257void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12258 const OpenACCNoHostClause &C) {
12259 llvm_unreachable("nohost clause not valid unless a decl transform");
12260}
12261template <typename Derived>
12262void OpenACCClauseTransform<Derived>::VisitBindClause(
12263 const OpenACCBindClause &C) {
12264 llvm_unreachable("bind clause not valid unless a decl transform");
12265}
12266
12267template <typename Derived>
12268void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12269 const OpenACCCopyInClause &C) {
12270 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12271 C.getModifierList());
12272
12273 NewClause = OpenACCCopyInClause::Create(
12274 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12275 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12276 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12277 EndLoc: ParsedClause.getEndLoc());
12278}
12279
12280template <typename Derived>
12281void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12282 const OpenACCCopyOutClause &C) {
12283 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12284 C.getModifierList());
12285
12286 NewClause = OpenACCCopyOutClause::Create(
12287 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12288 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12289 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12290 EndLoc: ParsedClause.getEndLoc());
12291}
12292
12293template <typename Derived>
12294void OpenACCClauseTransform<Derived>::VisitCreateClause(
12295 const OpenACCCreateClause &C) {
12296 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12297 C.getModifierList());
12298
12299 NewClause = OpenACCCreateClause::Create(
12300 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12301 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12302 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12303 EndLoc: ParsedClause.getEndLoc());
12304}
12305template <typename Derived>
12306void OpenACCClauseTransform<Derived>::VisitAttachClause(
12307 const OpenACCAttachClause &C) {
12308 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12309
12310 // Ensure each var is a pointer type.
12311 llvm::erase_if(VarList, [&](Expr *E) {
12312 return Self.getSema().OpenACC().CheckVarIsPointerType(
12313 OpenACCClauseKind::Attach, E);
12314 });
12315
12316 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12317 NewClause = OpenACCAttachClause::Create(
12318 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12319 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12320 EndLoc: ParsedClause.getEndLoc());
12321}
12322
12323template <typename Derived>
12324void OpenACCClauseTransform<Derived>::VisitDetachClause(
12325 const OpenACCDetachClause &C) {
12326 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12327
12328 // Ensure each var is a pointer type.
12329 llvm::erase_if(VarList, [&](Expr *E) {
12330 return Self.getSema().OpenACC().CheckVarIsPointerType(
12331 OpenACCClauseKind::Detach, E);
12332 });
12333
12334 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12335 NewClause = OpenACCDetachClause::Create(
12336 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12337 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12338 EndLoc: ParsedClause.getEndLoc());
12339}
12340
12341template <typename Derived>
12342void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12343 const OpenACCDeleteClause &C) {
12344 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12345 OpenACCModifierKind::Invalid);
12346 NewClause = OpenACCDeleteClause::Create(
12347 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12348 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12349 EndLoc: ParsedClause.getEndLoc());
12350}
12351
12352template <typename Derived>
12353void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12354 const OpenACCUseDeviceClause &C) {
12355 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12356 OpenACCModifierKind::Invalid);
12357 NewClause = OpenACCUseDeviceClause::Create(
12358 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12359 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12360 EndLoc: ParsedClause.getEndLoc());
12361}
12362
12363template <typename Derived>
12364void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12365 const OpenACCDevicePtrClause &C) {
12366 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12367
12368 // Ensure each var is a pointer type.
12369 llvm::erase_if(VarList, [&](Expr *E) {
12370 return Self.getSema().OpenACC().CheckVarIsPointerType(
12371 OpenACCClauseKind::DevicePtr, E);
12372 });
12373
12374 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12375 NewClause = OpenACCDevicePtrClause::Create(
12376 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12377 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12378 EndLoc: ParsedClause.getEndLoc());
12379}
12380
12381template <typename Derived>
12382void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12383 const OpenACCNumWorkersClause &C) {
12384 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12385 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12386
12387 ExprResult Res = Self.TransformExpr(IntExpr);
12388 if (!Res.isUsable())
12389 return;
12390
12391 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12392 C.getClauseKind(),
12393 C.getBeginLoc(), Res.get());
12394 if (!Res.isUsable())
12395 return;
12396
12397 ParsedClause.setIntExprDetails(Res.get());
12398 NewClause = OpenACCNumWorkersClause::Create(
12399 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12400 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12401 EndLoc: ParsedClause.getEndLoc());
12402}
12403
12404template <typename Derived>
12405void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12406 const OpenACCDeviceNumClause &C) {
12407 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12408 assert(IntExpr && "device_num clause constructed with invalid int expr");
12409
12410 ExprResult Res = Self.TransformExpr(IntExpr);
12411 if (!Res.isUsable())
12412 return;
12413
12414 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12415 C.getClauseKind(),
12416 C.getBeginLoc(), Res.get());
12417 if (!Res.isUsable())
12418 return;
12419
12420 ParsedClause.setIntExprDetails(Res.get());
12421 NewClause = OpenACCDeviceNumClause::Create(
12422 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12423 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12424 EndLoc: ParsedClause.getEndLoc());
12425}
12426
12427template <typename Derived>
12428void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12429 const OpenACCDefaultAsyncClause &C) {
12430 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12431 assert(IntExpr && "default_async clause constructed with invalid int expr");
12432
12433 ExprResult Res = Self.TransformExpr(IntExpr);
12434 if (!Res.isUsable())
12435 return;
12436
12437 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12438 C.getClauseKind(),
12439 C.getBeginLoc(), Res.get());
12440 if (!Res.isUsable())
12441 return;
12442
12443 ParsedClause.setIntExprDetails(Res.get());
12444 NewClause = OpenACCDefaultAsyncClause::Create(
12445 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12446 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12447 EndLoc: ParsedClause.getEndLoc());
12448}
12449
12450template <typename Derived>
12451void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12452 const OpenACCVectorLengthClause &C) {
12453 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12454 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12455
12456 ExprResult Res = Self.TransformExpr(IntExpr);
12457 if (!Res.isUsable())
12458 return;
12459
12460 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12461 C.getClauseKind(),
12462 C.getBeginLoc(), Res.get());
12463 if (!Res.isUsable())
12464 return;
12465
12466 ParsedClause.setIntExprDetails(Res.get());
12467 NewClause = OpenACCVectorLengthClause::Create(
12468 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12469 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12470 EndLoc: ParsedClause.getEndLoc());
12471}
12472
12473template <typename Derived>
12474void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12475 const OpenACCAsyncClause &C) {
12476 if (C.hasIntExpr()) {
12477 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12478 if (!Res.isUsable())
12479 return;
12480
12481 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12482 C.getClauseKind(),
12483 C.getBeginLoc(), Res.get());
12484 if (!Res.isUsable())
12485 return;
12486 ParsedClause.setIntExprDetails(Res.get());
12487 }
12488
12489 NewClause = OpenACCAsyncClause::Create(
12490 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12491 LParenLoc: ParsedClause.getLParenLoc(),
12492 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12493 : nullptr,
12494 EndLoc: ParsedClause.getEndLoc());
12495}
12496
12497template <typename Derived>
12498void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12499 const OpenACCWorkerClause &C) {
12500 if (C.hasIntExpr()) {
12501 // restrictions on this expression are all "does it exist in certain
12502 // situations" that are not possible to be dependent, so the only check we
12503 // have is that it transforms, and is an int expression.
12504 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12505 if (!Res.isUsable())
12506 return;
12507
12508 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12509 C.getClauseKind(),
12510 C.getBeginLoc(), Res.get());
12511 if (!Res.isUsable())
12512 return;
12513 ParsedClause.setIntExprDetails(Res.get());
12514 }
12515
12516 NewClause = OpenACCWorkerClause::Create(
12517 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12518 LParenLoc: ParsedClause.getLParenLoc(),
12519 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12520 : nullptr,
12521 EndLoc: ParsedClause.getEndLoc());
12522}
12523
12524template <typename Derived>
12525void OpenACCClauseTransform<Derived>::VisitVectorClause(
12526 const OpenACCVectorClause &C) {
12527 if (C.hasIntExpr()) {
12528 // restrictions on this expression are all "does it exist in certain
12529 // situations" that are not possible to be dependent, so the only check we
12530 // have is that it transforms, and is an int expression.
12531 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12532 if (!Res.isUsable())
12533 return;
12534
12535 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12536 C.getClauseKind(),
12537 C.getBeginLoc(), Res.get());
12538 if (!Res.isUsable())
12539 return;
12540 ParsedClause.setIntExprDetails(Res.get());
12541 }
12542
12543 NewClause = OpenACCVectorClause::Create(
12544 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12545 LParenLoc: ParsedClause.getLParenLoc(),
12546 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12547 : nullptr,
12548 EndLoc: ParsedClause.getEndLoc());
12549}
12550
12551template <typename Derived>
12552void OpenACCClauseTransform<Derived>::VisitWaitClause(
12553 const OpenACCWaitClause &C) {
12554 if (C.hasExprs()) {
12555 Expr *DevNumExpr = nullptr;
12556 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12557
12558 // Instantiate devnum expr if it exists.
12559 if (C.getDevNumExpr()) {
12560 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12561 if (!Res.isUsable())
12562 return;
12563 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12564 C.getClauseKind(),
12565 C.getBeginLoc(), Res.get());
12566 if (!Res.isUsable())
12567 return;
12568
12569 DevNumExpr = Res.get();
12570 }
12571
12572 // Instantiate queue ids.
12573 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12574 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12575 if (!Res.isUsable())
12576 return;
12577 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12578 C.getClauseKind(),
12579 C.getBeginLoc(), Res.get());
12580 if (!Res.isUsable())
12581 return;
12582
12583 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12584 }
12585
12586 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12587 IntExprs: std::move(InstantiatedQueueIdExprs));
12588 }
12589
12590 NewClause = OpenACCWaitClause::Create(
12591 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12592 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12593 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12594 EndLoc: ParsedClause.getEndLoc());
12595}
12596
12597template <typename Derived>
12598void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12599 const OpenACCDeviceTypeClause &C) {
12600 // Nothing to transform here, just create a new version of 'C'.
12601 NewClause = OpenACCDeviceTypeClause::Create(
12602 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12603 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12604 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12605}
12606
12607template <typename Derived>
12608void OpenACCClauseTransform<Derived>::VisitAutoClause(
12609 const OpenACCAutoClause &C) {
12610 // Nothing to do, so just create a new node.
12611 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12612 BeginLoc: ParsedClause.getBeginLoc(),
12613 EndLoc: ParsedClause.getEndLoc());
12614}
12615
12616template <typename Derived>
12617void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12618 const OpenACCIndependentClause &C) {
12619 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12620 BeginLoc: ParsedClause.getBeginLoc(),
12621 EndLoc: ParsedClause.getEndLoc());
12622}
12623
12624template <typename Derived>
12625void OpenACCClauseTransform<Derived>::VisitSeqClause(
12626 const OpenACCSeqClause &C) {
12627 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12628 BeginLoc: ParsedClause.getBeginLoc(),
12629 EndLoc: ParsedClause.getEndLoc());
12630}
12631template <typename Derived>
12632void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12633 const OpenACCFinalizeClause &C) {
12634 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12635 BeginLoc: ParsedClause.getBeginLoc(),
12636 EndLoc: ParsedClause.getEndLoc());
12637}
12638
12639template <typename Derived>
12640void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12641 const OpenACCIfPresentClause &C) {
12642 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12643 BeginLoc: ParsedClause.getBeginLoc(),
12644 EndLoc: ParsedClause.getEndLoc());
12645}
12646
12647template <typename Derived>
12648void OpenACCClauseTransform<Derived>::VisitReductionClause(
12649 const OpenACCReductionClause &C) {
12650 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12651 SmallVector<Expr *> ValidVars;
12652 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
12653
12654 for (const auto [Var, OrigRecipe] :
12655 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
12656 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12657 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12658 if (Res.isUsable()) {
12659 ValidVars.push_back(Elt: Res.get());
12660
12661 if (OrigRecipe.isSet())
12662 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
12663 else
12664 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
12665 C.getReductionOp(), Res.get()));
12666 }
12667 }
12668
12669 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12670 ExistingClauses, ParsedClause.getDirectiveKind(),
12671 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12672 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
12673}
12674
12675template <typename Derived>
12676void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12677 const OpenACCCollapseClause &C) {
12678 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12679 assert(LoopCount && "collapse clause constructed with invalid loop count");
12680
12681 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12682
12683 if (!NewLoopCount.isUsable())
12684 return;
12685
12686 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12687 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12688 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12689
12690 // FIXME: It isn't clear whether this is properly tested here, we should
12691 // probably see if we can come up with a test for this.
12692 if (!NewLoopCount.isUsable())
12693 return;
12694
12695 NewLoopCount =
12696 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12697
12698 // FIXME: It isn't clear whether this is properly tested here, we should
12699 // probably see if we can come up with a test for this.
12700 if (!NewLoopCount.isUsable())
12701 return;
12702
12703 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12704 NewClause = OpenACCCollapseClause::Create(
12705 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12706 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12707 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12708}
12709
12710template <typename Derived>
12711void OpenACCClauseTransform<Derived>::VisitTileClause(
12712 const OpenACCTileClause &C) {
12713
12714 llvm::SmallVector<Expr *> TransformedExprs;
12715
12716 for (Expr *E : C.getSizeExprs()) {
12717 ExprResult NewSizeExpr = Self.TransformExpr(E);
12718
12719 if (!NewSizeExpr.isUsable())
12720 return;
12721
12722 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12723 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12724 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12725
12726 // FIXME: It isn't clear whether this is properly tested here, we should
12727 // probably see if we can come up with a test for this.
12728 if (!NewSizeExpr.isUsable())
12729 return;
12730
12731 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12732
12733 if (!NewSizeExpr.isUsable())
12734 return;
12735 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12736 }
12737
12738 ParsedClause.setIntExprDetails(TransformedExprs);
12739 NewClause = OpenACCTileClause::Create(
12740 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12741 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12742 EndLoc: ParsedClause.getEndLoc());
12743}
12744template <typename Derived>
12745void OpenACCClauseTransform<Derived>::VisitGangClause(
12746 const OpenACCGangClause &C) {
12747 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12748 llvm::SmallVector<Expr *> TransformedIntExprs;
12749
12750 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12751 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12752 if (!ER.isUsable())
12753 continue;
12754
12755 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12756 ParsedClause.getDirectiveKind(),
12757 C.getExpr(I).first, ER.get());
12758 if (!ER.isUsable())
12759 continue;
12760 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12761 TransformedIntExprs.push_back(Elt: ER.get());
12762 }
12763
12764 NewClause = Self.getSema().OpenACC().CheckGangClause(
12765 ParsedClause.getDirectiveKind(), ExistingClauses,
12766 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12767 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12768}
12769} // namespace
12770template <typename Derived>
12771OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12772 ArrayRef<const OpenACCClause *> ExistingClauses,
12773 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12774
12775 SemaOpenACC::OpenACCParsedClause ParsedClause(
12776 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12777 ParsedClause.setEndLoc(OldClause->getEndLoc());
12778
12779 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12780 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12781
12782 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12783 ParsedClause};
12784 Transform.Visit(OldClause);
12785
12786 return Transform.CreatedClause();
12787}
12788
12789template <typename Derived>
12790llvm::SmallVector<OpenACCClause *>
12791TreeTransform<Derived>::TransformOpenACCClauseList(
12792 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12793 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12794 for (const auto *Clause : OldClauses) {
12795 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12796 TransformedClauses, DirKind, Clause))
12797 TransformedClauses.push_back(Elt: TransformedClause);
12798 }
12799 return TransformedClauses;
12800}
12801
12802template <typename Derived>
12803StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12804 OpenACCComputeConstruct *C) {
12805 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12806
12807 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12808 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12809 C->clauses());
12810
12811 if (getSema().OpenACC().ActOnStartStmtDirective(
12812 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12813 return StmtError();
12814
12815 // Transform Structured Block.
12816 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12817 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12818 C->clauses(), TransformedClauses);
12819 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12820 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12821 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12822
12823 return getDerived().RebuildOpenACCComputeConstruct(
12824 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12825 C->getEndLoc(), TransformedClauses, StrBlock);
12826}
12827
12828template <typename Derived>
12829StmtResult
12830TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12831
12832 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12833
12834 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12835 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12836 C->clauses());
12837
12838 if (getSema().OpenACC().ActOnStartStmtDirective(
12839 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12840 return StmtError();
12841
12842 // Transform Loop.
12843 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12844 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12845 C->clauses(), TransformedClauses);
12846 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12847 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12848 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12849
12850 return getDerived().RebuildOpenACCLoopConstruct(
12851 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12852 TransformedClauses, Loop);
12853}
12854
12855template <typename Derived>
12856StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12857 OpenACCCombinedConstruct *C) {
12858 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12859
12860 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12861 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12862 C->clauses());
12863
12864 if (getSema().OpenACC().ActOnStartStmtDirective(
12865 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12866 return StmtError();
12867
12868 // Transform Loop.
12869 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12870 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12871 C->clauses(), TransformedClauses);
12872 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12873 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12874 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12875
12876 return getDerived().RebuildOpenACCCombinedConstruct(
12877 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12878 C->getEndLoc(), TransformedClauses, Loop);
12879}
12880
12881template <typename Derived>
12882StmtResult
12883TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12884 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12885
12886 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12887 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12888 C->clauses());
12889 if (getSema().OpenACC().ActOnStartStmtDirective(
12890 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12891 return StmtError();
12892
12893 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12894 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12895 C->clauses(), TransformedClauses);
12896 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12897 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12898 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12899
12900 return getDerived().RebuildOpenACCDataConstruct(
12901 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12902 TransformedClauses, StrBlock);
12903}
12904
12905template <typename Derived>
12906StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12907 OpenACCEnterDataConstruct *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().RebuildOpenACCEnterDataConstruct(
12918 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12919 TransformedClauses);
12920}
12921
12922template <typename Derived>
12923StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12924 OpenACCExitDataConstruct *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().RebuildOpenACCExitDataConstruct(
12935 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12936 TransformedClauses);
12937}
12938
12939template <typename Derived>
12940StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12941 OpenACCHostDataConstruct *C) {
12942 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12943
12944 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12945 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12946 C->clauses());
12947 if (getSema().OpenACC().ActOnStartStmtDirective(
12948 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12949 return StmtError();
12950
12951 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12952 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12953 C->clauses(), TransformedClauses);
12954 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12955 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12956 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12957
12958 return getDerived().RebuildOpenACCHostDataConstruct(
12959 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12960 TransformedClauses, StrBlock);
12961}
12962
12963template <typename Derived>
12964StmtResult
12965TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12966 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12967
12968 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12969 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12970 C->clauses());
12971 if (getSema().OpenACC().ActOnStartStmtDirective(
12972 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12973 return StmtError();
12974
12975 return getDerived().RebuildOpenACCInitConstruct(
12976 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12977 TransformedClauses);
12978}
12979
12980template <typename Derived>
12981StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12982 OpenACCShutdownConstruct *C) {
12983 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12984
12985 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12986 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12987 C->clauses());
12988 if (getSema().OpenACC().ActOnStartStmtDirective(
12989 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12990 return StmtError();
12991
12992 return getDerived().RebuildOpenACCShutdownConstruct(
12993 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12994 TransformedClauses);
12995}
12996template <typename Derived>
12997StmtResult
12998TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12999 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13000
13001 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13002 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13003 C->clauses());
13004 if (getSema().OpenACC().ActOnStartStmtDirective(
13005 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13006 return StmtError();
13007
13008 return getDerived().RebuildOpenACCSetConstruct(
13009 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13010 TransformedClauses);
13011}
13012
13013template <typename Derived>
13014StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13015 OpenACCUpdateConstruct *C) {
13016 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13017
13018 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13019 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13020 C->clauses());
13021 if (getSema().OpenACC().ActOnStartStmtDirective(
13022 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13023 return StmtError();
13024
13025 return getDerived().RebuildOpenACCUpdateConstruct(
13026 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13027 TransformedClauses);
13028}
13029
13030template <typename Derived>
13031StmtResult
13032TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13033 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13034
13035 ExprResult DevNumExpr;
13036 if (C->hasDevNumExpr()) {
13037 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13038
13039 if (DevNumExpr.isUsable())
13040 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13041 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13042 C->getBeginLoc(), DevNumExpr.get());
13043 }
13044
13045 llvm::SmallVector<Expr *> QueueIdExprs;
13046
13047 for (Expr *QE : C->getQueueIdExprs()) {
13048 assert(QE && "Null queue id expr?");
13049 ExprResult NewEQ = getDerived().TransformExpr(QE);
13050
13051 if (!NewEQ.isUsable())
13052 break;
13053 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13054 OpenACCClauseKind::Invalid,
13055 C->getBeginLoc(), NewEQ.get());
13056 if (NewEQ.isUsable())
13057 QueueIdExprs.push_back(Elt: NewEQ.get());
13058 }
13059
13060 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13061 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13062 C->clauses());
13063
13064 if (getSema().OpenACC().ActOnStartStmtDirective(
13065 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13066 return StmtError();
13067
13068 return getDerived().RebuildOpenACCWaitConstruct(
13069 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13070 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13071 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13072}
13073template <typename Derived>
13074StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13075 OpenACCCacheConstruct *C) {
13076 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13077
13078 llvm::SmallVector<Expr *> TransformedVarList;
13079 for (Expr *Var : C->getVarList()) {
13080 assert(Var && "Null var listexpr?");
13081
13082 ExprResult NewVar = getDerived().TransformExpr(Var);
13083
13084 if (!NewVar.isUsable())
13085 break;
13086
13087 NewVar = getSema().OpenACC().ActOnVar(
13088 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13089 if (!NewVar.isUsable())
13090 break;
13091
13092 TransformedVarList.push_back(Elt: NewVar.get());
13093 }
13094
13095 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13096 C->getBeginLoc(), {}))
13097 return StmtError();
13098
13099 return getDerived().RebuildOpenACCCacheConstruct(
13100 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13101 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13102 C->getEndLoc());
13103}
13104
13105template <typename Derived>
13106StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13107 OpenACCAtomicConstruct *C) {
13108 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13109
13110 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13111 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13112 C->clauses());
13113
13114 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13115 C->getBeginLoc(), {}))
13116 return StmtError();
13117
13118 // Transform Associated Stmt.
13119 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13120 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13121
13122 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13123 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13124 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13125 AssocStmt);
13126
13127 return getDerived().RebuildOpenACCAtomicConstruct(
13128 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13129 C->getEndLoc(), TransformedClauses, AssocStmt);
13130}
13131
13132template <typename Derived>
13133ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13134 OpenACCAsteriskSizeExpr *E) {
13135 if (getDerived().AlwaysRebuild())
13136 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13137 // Nothing can ever change, so there is never anything to transform.
13138 return E;
13139}
13140
13141//===----------------------------------------------------------------------===//
13142// Expression transformation
13143//===----------------------------------------------------------------------===//
13144template<typename Derived>
13145ExprResult
13146TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13147 return TransformExpr(E: E->getSubExpr());
13148}
13149
13150template <typename Derived>
13151ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13152 SYCLUniqueStableNameExpr *E) {
13153 if (!E->isTypeDependent())
13154 return E;
13155
13156 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13157
13158 if (!NewT)
13159 return ExprError();
13160
13161 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13162 return E;
13163
13164 return getDerived().RebuildSYCLUniqueStableNameExpr(
13165 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13166}
13167
13168template <typename Derived>
13169StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13170 UnresolvedSYCLKernelCallStmt *S) {
13171 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13172 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13173 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13174 return StmtError();
13175
13176 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13177 if (IdExpr.isInvalid())
13178 return StmtError();
13179
13180 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13181 if (Body.isInvalid())
13182 return StmtError();
13183
13184 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13185 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13186 LaunchIdExpr: IdExpr.get());
13187 if (SR.isInvalid())
13188 return StmtError();
13189
13190 return SR;
13191}
13192
13193template <typename Derived>
13194ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13195 // TODO(reflection): Implement its transform
13196 assert(false && "not implemented yet");
13197 return ExprError();
13198}
13199
13200template<typename Derived>
13201ExprResult
13202TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13203 if (!E->isTypeDependent())
13204 return E;
13205
13206 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13207 E->getIdentKind());
13208}
13209
13210template<typename Derived>
13211ExprResult
13212TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13213 NestedNameSpecifierLoc QualifierLoc;
13214 if (E->getQualifierLoc()) {
13215 QualifierLoc
13216 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13217 if (!QualifierLoc)
13218 return ExprError();
13219 }
13220
13221 ValueDecl *ND
13222 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13223 E->getDecl()));
13224 if (!ND || ND->isInvalidDecl())
13225 return ExprError();
13226
13227 NamedDecl *Found = ND;
13228 if (E->getFoundDecl() != E->getDecl()) {
13229 Found = cast_or_null<NamedDecl>(
13230 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13231 if (!Found)
13232 return ExprError();
13233 }
13234
13235 DeclarationNameInfo NameInfo = E->getNameInfo();
13236 if (NameInfo.getName()) {
13237 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13238 if (!NameInfo.getName())
13239 return ExprError();
13240 }
13241
13242 if (!getDerived().AlwaysRebuild() &&
13243 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13244 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13245 Found == E->getFoundDecl() &&
13246 NameInfo.getName() == E->getDecl()->getDeclName() &&
13247 !E->hasExplicitTemplateArgs()) {
13248
13249 // Mark it referenced in the new context regardless.
13250 // FIXME: this is a bit instantiation-specific.
13251 SemaRef.MarkDeclRefReferenced(E);
13252
13253 return E;
13254 }
13255
13256 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13257 if (E->hasExplicitTemplateArgs()) {
13258 TemplateArgs = &TransArgs;
13259 TransArgs.setLAngleLoc(E->getLAngleLoc());
13260 TransArgs.setRAngleLoc(E->getRAngleLoc());
13261 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13262 E->getNumTemplateArgs(),
13263 TransArgs))
13264 return ExprError();
13265 }
13266
13267 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13268 Found, TemplateArgs);
13269}
13270
13271template<typename Derived>
13272ExprResult
13273TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13274 return E;
13275}
13276
13277template <typename Derived>
13278ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13279 FixedPointLiteral *E) {
13280 return E;
13281}
13282
13283template<typename Derived>
13284ExprResult
13285TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13286 return E;
13287}
13288
13289template<typename Derived>
13290ExprResult
13291TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13292 return E;
13293}
13294
13295template<typename Derived>
13296ExprResult
13297TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13298 return E;
13299}
13300
13301template<typename Derived>
13302ExprResult
13303TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13304 return E;
13305}
13306
13307template<typename Derived>
13308ExprResult
13309TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13310 return getDerived().TransformCallExpr(E);
13311}
13312
13313template<typename Derived>
13314ExprResult
13315TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13316 ExprResult ControllingExpr;
13317 TypeSourceInfo *ControllingType = nullptr;
13318 if (E->isExprPredicate())
13319 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13320 else
13321 ControllingType = getDerived().TransformType(E->getControllingType());
13322
13323 if (ControllingExpr.isInvalid() && !ControllingType)
13324 return ExprError();
13325
13326 SmallVector<Expr *, 4> AssocExprs;
13327 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13328 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13329 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13330 if (TSI) {
13331 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13332 if (!AssocType)
13333 return ExprError();
13334 AssocTypes.push_back(Elt: AssocType);
13335 } else {
13336 AssocTypes.push_back(Elt: nullptr);
13337 }
13338
13339 ExprResult AssocExpr =
13340 getDerived().TransformExpr(Assoc.getAssociationExpr());
13341 if (AssocExpr.isInvalid())
13342 return ExprError();
13343 AssocExprs.push_back(Elt: AssocExpr.get());
13344 }
13345
13346 if (!ControllingType)
13347 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13348 E->getDefaultLoc(),
13349 E->getRParenLoc(),
13350 ControllingExpr.get(),
13351 AssocTypes,
13352 AssocExprs);
13353 return getDerived().RebuildGenericSelectionExpr(
13354 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13355 ControllingType, AssocTypes, AssocExprs);
13356}
13357
13358template<typename Derived>
13359ExprResult
13360TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13361 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13362 if (SubExpr.isInvalid())
13363 return ExprError();
13364
13365 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13366 return E;
13367
13368 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13369 E->getRParen());
13370}
13371
13372/// The operand of a unary address-of operator has special rules: it's
13373/// allowed to refer to a non-static member of a class even if there's no 'this'
13374/// object available.
13375template<typename Derived>
13376ExprResult
13377TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13378 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13379 return getDerived().TransformDependentScopeDeclRefExpr(
13380 DRE, /*IsAddressOfOperand=*/true, nullptr);
13381 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13382 return getDerived().TransformUnresolvedLookupExpr(
13383 ULE, /*IsAddressOfOperand=*/true);
13384 else
13385 return getDerived().TransformExpr(E);
13386}
13387
13388template<typename Derived>
13389ExprResult
13390TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13391 ExprResult SubExpr;
13392 if (E->getOpcode() == UO_AddrOf)
13393 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13394 else
13395 SubExpr = TransformExpr(E: E->getSubExpr());
13396 if (SubExpr.isInvalid())
13397 return ExprError();
13398
13399 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13400 return E;
13401
13402 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13403 E->getOpcode(),
13404 SubExpr.get());
13405}
13406
13407template<typename Derived>
13408ExprResult
13409TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13410 // Transform the type.
13411 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13412 if (!Type)
13413 return ExprError();
13414
13415 // Transform all of the components into a Designation similar to what the
13416 // parser builds.
13417 // FIXME: It would be slightly more efficient in the non-dependent case to
13418 // just map FieldDecls, rather than requiring the rebuilder to look for
13419 // the fields again. However, __builtin_offsetof is rare enough in
13420 // template code that we don't care.
13421 bool ExprChanged = false;
13422 Designation Desig;
13423 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13424 const OffsetOfNode &ON = E->getComponent(Idx: I);
13425 switch (ON.getKind()) {
13426 case OffsetOfNode::Array: {
13427 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13428 ExprResult Index = getDerived().TransformExpr(FromIndex);
13429 if (Index.isInvalid())
13430 return ExprError();
13431
13432 ExprChanged = ExprChanged || Index.get() != FromIndex;
13433 Designator AD =
13434 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13435 AD.setRBracketLoc(ON.getEndLoc());
13436 Desig.AddDesignator(D: AD);
13437 break;
13438 }
13439
13440 case OffsetOfNode::Field:
13441 case OffsetOfNode::Identifier: {
13442 const IdentifierInfo *Name = ON.getFieldName();
13443 if (!Name)
13444 continue;
13445 // The leading designator has no '.'; subsequent ones do.
13446 SourceLocation DotLoc =
13447 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13448 Desig.AddDesignator(
13449 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13450 break;
13451 }
13452
13453 case OffsetOfNode::Base:
13454 // Will be recomputed during the rebuild.
13455 continue;
13456 }
13457 }
13458
13459 // If nothing changed, retain the existing expression.
13460 if (!getDerived().AlwaysRebuild() &&
13461 Type == E->getTypeSourceInfo() &&
13462 !ExprChanged)
13463 return E;
13464
13465 // Build a new offsetof expression.
13466 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13467 E->getRParenLoc());
13468}
13469
13470template<typename Derived>
13471ExprResult
13472TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13473 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13474 "opaque value expression requires transformation");
13475 return E;
13476}
13477
13478template <typename Derived>
13479ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13480 llvm::SmallVector<Expr *, 8> Children;
13481 bool Changed = false;
13482 for (Expr *C : E->subExpressions()) {
13483 ExprResult NewC = getDerived().TransformExpr(C);
13484 if (NewC.isInvalid())
13485 return ExprError();
13486 Children.push_back(Elt: NewC.get());
13487
13488 Changed |= NewC.get() != C;
13489 }
13490 if (!getDerived().AlwaysRebuild() && !Changed)
13491 return E;
13492 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13493 Children, E->getType());
13494}
13495
13496template<typename Derived>
13497ExprResult
13498TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13499 // Rebuild the syntactic form. The original syntactic form has
13500 // opaque-value expressions in it, so strip those away and rebuild
13501 // the result. This is a really awful way of doing this, but the
13502 // better solution (rebuilding the semantic expressions and
13503 // rebinding OVEs as necessary) doesn't work; we'd need
13504 // TreeTransform to not strip away implicit conversions.
13505 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13506 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13507 if (result.isInvalid()) return ExprError();
13508
13509 // If that gives us a pseudo-object result back, the pseudo-object
13510 // expression must have been an lvalue-to-rvalue conversion which we
13511 // should reapply.
13512 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13513 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13514
13515 return result;
13516}
13517
13518template<typename Derived>
13519ExprResult
13520TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13521 UnaryExprOrTypeTraitExpr *E) {
13522 if (E->isArgumentType()) {
13523 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13524
13525 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13526 if (!NewT)
13527 return ExprError();
13528
13529 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13530 return E;
13531
13532 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13533 E->getKind(),
13534 E->getSourceRange());
13535 }
13536
13537 // C++0x [expr.sizeof]p1:
13538 // The operand is either an expression, which is an unevaluated operand
13539 // [...]
13540 EnterExpressionEvaluationContext Unevaluated(
13541 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13542 Sema::ReuseLambdaContextDecl);
13543
13544 // Try to recover if we have something like sizeof(T::X) where X is a type.
13545 // Notably, there must be *exactly* one set of parens if X is a type.
13546 TypeSourceInfo *RecoveryTSI = nullptr;
13547 ExprResult SubExpr;
13548 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13549 if (auto *DRE =
13550 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13551 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13552 PE, DRE, false, &RecoveryTSI);
13553 else
13554 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13555
13556 if (RecoveryTSI) {
13557 return getDerived().RebuildUnaryExprOrTypeTrait(
13558 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13559 } else if (SubExpr.isInvalid())
13560 return ExprError();
13561
13562 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13563 return E;
13564
13565 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13566 E->getOperatorLoc(),
13567 E->getKind(),
13568 E->getSourceRange());
13569}
13570
13571template<typename Derived>
13572ExprResult
13573TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13574 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13575 if (LHS.isInvalid())
13576 return ExprError();
13577
13578 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13579 if (RHS.isInvalid())
13580 return ExprError();
13581
13582
13583 if (!getDerived().AlwaysRebuild() &&
13584 LHS.get() == E->getLHS() &&
13585 RHS.get() == E->getRHS())
13586 return E;
13587
13588 return getDerived().RebuildArraySubscriptExpr(
13589 LHS.get(),
13590 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13591}
13592
13593template <typename Derived>
13594ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13595 MatrixSingleSubscriptExpr *E) {
13596 ExprResult Base = getDerived().TransformExpr(E->getBase());
13597 if (Base.isInvalid())
13598 return ExprError();
13599
13600 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13601 if (RowIdx.isInvalid())
13602 return ExprError();
13603
13604 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13605 RowIdx.get() == E->getRowIdx())
13606 return E;
13607
13608 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
13609 E->getRBracketLoc());
13610}
13611
13612template <typename Derived>
13613ExprResult
13614TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13615 ExprResult Base = getDerived().TransformExpr(E->getBase());
13616 if (Base.isInvalid())
13617 return ExprError();
13618
13619 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13620 if (RowIdx.isInvalid())
13621 return ExprError();
13622
13623 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13624 if (ColumnIdx.isInvalid())
13625 return ExprError();
13626
13627 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13628 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13629 return E;
13630
13631 return getDerived().RebuildMatrixSubscriptExpr(
13632 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13633}
13634
13635template <typename Derived>
13636ExprResult
13637TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13638 ExprResult Base = getDerived().TransformExpr(E->getBase());
13639 if (Base.isInvalid())
13640 return ExprError();
13641
13642 ExprResult LowerBound;
13643 if (E->getLowerBound()) {
13644 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13645 if (LowerBound.isInvalid())
13646 return ExprError();
13647 }
13648
13649 ExprResult Length;
13650 if (E->getLength()) {
13651 Length = getDerived().TransformExpr(E->getLength());
13652 if (Length.isInvalid())
13653 return ExprError();
13654 }
13655
13656 ExprResult Stride;
13657 if (E->isOMPArraySection()) {
13658 if (Expr *Str = E->getStride()) {
13659 Stride = getDerived().TransformExpr(Str);
13660 if (Stride.isInvalid())
13661 return ExprError();
13662 }
13663 }
13664
13665 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13666 LowerBound.get() == E->getLowerBound() &&
13667 Length.get() == E->getLength() &&
13668 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13669 return E;
13670
13671 return getDerived().RebuildArraySectionExpr(
13672 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13673 LowerBound.get(), E->getColonLocFirst(),
13674 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13675 Length.get(), Stride.get(), E->getRBracketLoc());
13676}
13677
13678template <typename Derived>
13679ExprResult
13680TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13681 ExprResult Base = getDerived().TransformExpr(E->getBase());
13682 if (Base.isInvalid())
13683 return ExprError();
13684
13685 SmallVector<Expr *, 4> Dims;
13686 bool ErrorFound = false;
13687 for (Expr *Dim : E->getDimensions()) {
13688 ExprResult DimRes = getDerived().TransformExpr(Dim);
13689 if (DimRes.isInvalid()) {
13690 ErrorFound = true;
13691 continue;
13692 }
13693 Dims.push_back(Elt: DimRes.get());
13694 }
13695
13696 if (ErrorFound)
13697 return ExprError();
13698 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13699 E->getRParenLoc(), Dims,
13700 E->getBracketsRanges());
13701}
13702
13703template <typename Derived>
13704ExprResult
13705TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13706 unsigned NumIterators = E->numOfIterators();
13707 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13708
13709 bool ErrorFound = false;
13710 bool NeedToRebuild = getDerived().AlwaysRebuild();
13711 for (unsigned I = 0; I < NumIterators; ++I) {
13712 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13713 Data[I].DeclIdent = D->getIdentifier();
13714 Data[I].DeclIdentLoc = D->getLocation();
13715 if (D->getLocation() == D->getBeginLoc()) {
13716 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13717 "Implicit type must be int.");
13718 } else {
13719 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13720 QualType DeclTy = getDerived().TransformType(D->getType());
13721 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13722 }
13723 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13724 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13725 ExprResult End = getDerived().TransformExpr(Range.End);
13726 ExprResult Step = getDerived().TransformExpr(Range.Step);
13727 ErrorFound = ErrorFound ||
13728 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13729 !Data[I].Type.get().isNull())) ||
13730 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13731 if (ErrorFound)
13732 continue;
13733 Data[I].Range.Begin = Begin.get();
13734 Data[I].Range.End = End.get();
13735 Data[I].Range.Step = Step.get();
13736 Data[I].AssignLoc = E->getAssignLoc(I);
13737 Data[I].ColonLoc = E->getColonLoc(I);
13738 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13739 NeedToRebuild =
13740 NeedToRebuild ||
13741 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13742 D->getType().getTypePtrOrNull()) ||
13743 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13744 Range.Step != Data[I].Range.Step;
13745 }
13746 if (ErrorFound)
13747 return ExprError();
13748 if (!NeedToRebuild)
13749 return E;
13750
13751 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13752 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13753 if (!Res.isUsable())
13754 return Res;
13755 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13756 for (unsigned I = 0; I < NumIterators; ++I)
13757 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13758 IE->getIteratorDecl(I));
13759 return Res;
13760}
13761
13762template<typename Derived>
13763ExprResult
13764TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13765 // Transform the callee.
13766 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13767 if (Callee.isInvalid())
13768 return ExprError();
13769
13770 // Transform arguments.
13771 bool ArgChanged = false;
13772 SmallVector<Expr*, 8> Args;
13773 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13774 &ArgChanged))
13775 return ExprError();
13776
13777 if (!getDerived().AlwaysRebuild() &&
13778 Callee.get() == E->getCallee() &&
13779 !ArgChanged)
13780 return SemaRef.MaybeBindToTemporary(E);
13781
13782 // FIXME: Wrong source location information for the '('.
13783 SourceLocation FakeLParenLoc
13784 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13785
13786 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13787 if (E->hasStoredFPFeatures()) {
13788 FPOptionsOverride NewOverrides = E->getFPFeatures();
13789 getSema().CurFPFeatures =
13790 NewOverrides.applyOverrides(getSema().getLangOpts());
13791 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13792 }
13793
13794 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13795 Args,
13796 E->getRParenLoc());
13797}
13798
13799template<typename Derived>
13800ExprResult
13801TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13802 ExprResult Base = getDerived().TransformExpr(E->getBase());
13803 if (Base.isInvalid())
13804 return ExprError();
13805
13806 NestedNameSpecifierLoc QualifierLoc;
13807 if (E->hasQualifier()) {
13808 QualifierLoc
13809 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13810
13811 if (!QualifierLoc)
13812 return ExprError();
13813 }
13814 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13815
13816 ValueDecl *Member
13817 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13818 E->getMemberDecl()));
13819 if (!Member)
13820 return ExprError();
13821
13822 NamedDecl *FoundDecl = E->getFoundDecl();
13823 if (FoundDecl == E->getMemberDecl()) {
13824 FoundDecl = Member;
13825 } else {
13826 FoundDecl = cast_or_null<NamedDecl>(
13827 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13828 if (!FoundDecl)
13829 return ExprError();
13830 }
13831
13832 if (!getDerived().AlwaysRebuild() &&
13833 Base.get() == E->getBase() &&
13834 QualifierLoc == E->getQualifierLoc() &&
13835 Member == E->getMemberDecl() &&
13836 FoundDecl == E->getFoundDecl() &&
13837 !E->hasExplicitTemplateArgs()) {
13838
13839 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13840 // for Openmp where the field need to be privatizized in the case.
13841 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13842 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13843 cast<ValueDecl>(Val: Member)))) {
13844 // Mark it referenced in the new context regardless.
13845 // FIXME: this is a bit instantiation-specific.
13846 SemaRef.MarkMemberReferenced(E);
13847 return E;
13848 }
13849 }
13850
13851 TemplateArgumentListInfo TransArgs;
13852 if (E->hasExplicitTemplateArgs()) {
13853 TransArgs.setLAngleLoc(E->getLAngleLoc());
13854 TransArgs.setRAngleLoc(E->getRAngleLoc());
13855 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13856 E->getNumTemplateArgs(),
13857 TransArgs))
13858 return ExprError();
13859 }
13860
13861 // FIXME: Bogus source location for the operator
13862 SourceLocation FakeOperatorLoc =
13863 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13864
13865 // FIXME: to do this check properly, we will need to preserve the
13866 // first-qualifier-in-scope here, just in case we had a dependent
13867 // base (and therefore couldn't do the check) and a
13868 // nested-name-qualifier (and therefore could do the lookup).
13869 NamedDecl *FirstQualifierInScope = nullptr;
13870 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13871 if (MemberNameInfo.getName()) {
13872 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13873 if (!MemberNameInfo.getName())
13874 return ExprError();
13875 }
13876
13877 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13878 E->isArrow(),
13879 QualifierLoc,
13880 TemplateKWLoc,
13881 MemberNameInfo,
13882 Member,
13883 FoundDecl,
13884 (E->hasExplicitTemplateArgs()
13885 ? &TransArgs : nullptr),
13886 FirstQualifierInScope);
13887}
13888
13889template<typename Derived>
13890ExprResult
13891TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13892 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13893 if (LHS.isInvalid())
13894 return ExprError();
13895
13896 ExprResult RHS =
13897 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13898 if (RHS.isInvalid())
13899 return ExprError();
13900
13901 if (!getDerived().AlwaysRebuild() &&
13902 LHS.get() == E->getLHS() &&
13903 RHS.get() == E->getRHS())
13904 return E;
13905
13906 if (E->isCompoundAssignmentOp())
13907 // FPFeatures has already been established from trailing storage
13908 return getDerived().RebuildBinaryOperator(
13909 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13910 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13911 FPOptionsOverride NewOverrides(E->getFPFeatures());
13912 getSema().CurFPFeatures =
13913 NewOverrides.applyOverrides(getSema().getLangOpts());
13914 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13915 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13916 LHS.get(), RHS.get());
13917}
13918
13919template <typename Derived>
13920ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13921 CXXRewrittenBinaryOperator *E) {
13922 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13923
13924 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13925 if (LHS.isInvalid())
13926 return ExprError();
13927
13928 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13929 if (RHS.isInvalid())
13930 return ExprError();
13931
13932 // Extract the already-resolved callee declarations so that we can restrict
13933 // ourselves to using them as the unqualified lookup results when rebuilding.
13934 UnresolvedSet<2> UnqualLookups;
13935 bool ChangedAnyLookups = false;
13936 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13937 const_cast<Expr *>(Decomp.InnerBinOp)};
13938 for (Expr *PossibleBinOp : PossibleBinOps) {
13939 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13940 if (!Op)
13941 continue;
13942 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13943 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13944 continue;
13945
13946 // Transform the callee in case we built a call to a local extern
13947 // declaration.
13948 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13949 E->getOperatorLoc(), Callee->getFoundDecl()));
13950 if (!Found)
13951 return ExprError();
13952 if (Found != Callee->getFoundDecl())
13953 ChangedAnyLookups = true;
13954 UnqualLookups.addDecl(D: Found);
13955 }
13956
13957 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13958 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13959 // Mark all functions used in the rewrite as referenced. Note that when
13960 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13961 // function calls, and/or there might be a user-defined conversion sequence
13962 // applied to the operands of the <.
13963 // FIXME: this is a bit instantiation-specific.
13964 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13965 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13966 return E;
13967 }
13968
13969 return getDerived().RebuildCXXRewrittenBinaryOperator(
13970 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13971}
13972
13973template<typename Derived>
13974ExprResult
13975TreeTransform<Derived>::TransformCompoundAssignOperator(
13976 CompoundAssignOperator *E) {
13977 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13978 FPOptionsOverride NewOverrides(E->getFPFeatures());
13979 getSema().CurFPFeatures =
13980 NewOverrides.applyOverrides(getSema().getLangOpts());
13981 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13982 return getDerived().TransformBinaryOperator(E);
13983}
13984
13985template<typename Derived>
13986ExprResult TreeTransform<Derived>::
13987TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13988 // Just rebuild the common and RHS expressions and see whether we
13989 // get any changes.
13990
13991 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13992 if (commonExpr.isInvalid())
13993 return ExprError();
13994
13995 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13996 if (rhs.isInvalid())
13997 return ExprError();
13998
13999 if (!getDerived().AlwaysRebuild() &&
14000 commonExpr.get() == e->getCommon() &&
14001 rhs.get() == e->getFalseExpr())
14002 return e;
14003
14004 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14005 e->getQuestionLoc(),
14006 nullptr,
14007 e->getColonLoc(),
14008 rhs.get());
14009}
14010
14011template<typename Derived>
14012ExprResult
14013TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14014 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14015 if (Cond.isInvalid())
14016 return ExprError();
14017
14018 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14019 if (LHS.isInvalid())
14020 return ExprError();
14021
14022 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14023 if (RHS.isInvalid())
14024 return ExprError();
14025
14026 if (!getDerived().AlwaysRebuild() &&
14027 Cond.get() == E->getCond() &&
14028 LHS.get() == E->getLHS() &&
14029 RHS.get() == E->getRHS())
14030 return E;
14031
14032 return getDerived().RebuildConditionalOperator(Cond.get(),
14033 E->getQuestionLoc(),
14034 LHS.get(),
14035 E->getColonLoc(),
14036 RHS.get());
14037}
14038
14039template<typename Derived>
14040ExprResult
14041TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14042 // Implicit casts are eliminated during transformation, since they
14043 // will be recomputed by semantic analysis after transformation.
14044 return getDerived().TransformExpr(E->getSubExprAsWritten());
14045}
14046
14047template<typename Derived>
14048ExprResult
14049TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14050 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14051 if (!Type)
14052 return ExprError();
14053
14054 ExprResult SubExpr
14055 = getDerived().TransformExpr(E->getSubExprAsWritten());
14056 if (SubExpr.isInvalid())
14057 return ExprError();
14058
14059 if (!getDerived().AlwaysRebuild() &&
14060 Type == E->getTypeInfoAsWritten() &&
14061 SubExpr.get() == E->getSubExpr())
14062 return E;
14063
14064 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14065 Type,
14066 E->getRParenLoc(),
14067 SubExpr.get());
14068}
14069
14070template<typename Derived>
14071ExprResult
14072TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14073 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14074 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14075 if (!NewT)
14076 return ExprError();
14077
14078 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14079 if (Init.isInvalid())
14080 return ExprError();
14081
14082 if (!getDerived().AlwaysRebuild() &&
14083 OldT == NewT &&
14084 Init.get() == E->getInitializer())
14085 return SemaRef.MaybeBindToTemporary(E);
14086
14087 // Note: the expression type doesn't necessarily match the
14088 // type-as-written, but that's okay, because it should always be
14089 // derivable from the initializer.
14090
14091 return getDerived().RebuildCompoundLiteralExpr(
14092 E->getLParenLoc(), NewT,
14093 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14094}
14095
14096template<typename Derived>
14097ExprResult
14098TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14099 ExprResult Base = getDerived().TransformExpr(E->getBase());
14100 if (Base.isInvalid())
14101 return ExprError();
14102
14103 if (!getDerived().AlwaysRebuild() &&
14104 Base.get() == E->getBase())
14105 return E;
14106
14107 // FIXME: Bad source location
14108 SourceLocation FakeOperatorLoc =
14109 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14110 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14111 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14112 E->getAccessor());
14113}
14114
14115template <typename Derived>
14116ExprResult
14117TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14118 ExprResult Base = getDerived().TransformExpr(E->getBase());
14119 if (Base.isInvalid())
14120 return ExprError();
14121
14122 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14123 return E;
14124
14125 // FIXME: Bad source location
14126 SourceLocation FakeOperatorLoc =
14127 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14128 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14129 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14130 E->getAccessor());
14131}
14132
14133template<typename Derived>
14134ExprResult
14135TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14136 if (InitListExpr *Syntactic = E->getSyntacticForm())
14137 E = Syntactic;
14138
14139 bool InitChanged = false;
14140
14141 EnterExpressionEvaluationContext Context(
14142 getSema(), EnterExpressionEvaluationContext::InitList);
14143
14144 SmallVector<Expr*, 4> Inits;
14145 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14146 Inits, &InitChanged))
14147 return ExprError();
14148
14149 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14150 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14151 // in some cases. We can't reuse it in general, because the syntactic and
14152 // semantic forms are linked, and we can't know that semantic form will
14153 // match even if the syntactic form does.
14154 }
14155
14156 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14157 E->getRBraceLoc(), E->isExplicit());
14158}
14159
14160template<typename Derived>
14161ExprResult
14162TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14163 Designation Desig;
14164
14165 // transform the initializer value
14166 ExprResult Init = getDerived().TransformExpr(E->getInit());
14167 if (Init.isInvalid())
14168 return ExprError();
14169
14170 // transform the designators.
14171 SmallVector<Expr*, 4> ArrayExprs;
14172 bool ExprChanged = false;
14173 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14174 if (D.isFieldDesignator()) {
14175 if (D.getFieldDecl()) {
14176 FieldDecl *Field = cast_or_null<FieldDecl>(
14177 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14178 if (Field != D.getFieldDecl())
14179 // Rebuild the expression when the transformed FieldDecl is
14180 // different to the already assigned FieldDecl.
14181 ExprChanged = true;
14182 if (Field->isAnonymousStructOrUnion())
14183 continue;
14184 } else {
14185 // Ensure that the designator expression is rebuilt when there isn't
14186 // a resolved FieldDecl in the designator as we don't want to assign
14187 // a FieldDecl to a pattern designator that will be instantiated again.
14188 ExprChanged = true;
14189 }
14190 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14191 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14192 continue;
14193 }
14194
14195 if (D.isArrayDesignator()) {
14196 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14197 if (Index.isInvalid())
14198 return ExprError();
14199
14200 Desig.AddDesignator(
14201 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14202
14203 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14204 ArrayExprs.push_back(Elt: Index.get());
14205 continue;
14206 }
14207
14208 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14209 ExprResult Start
14210 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14211 if (Start.isInvalid())
14212 return ExprError();
14213
14214 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14215 if (End.isInvalid())
14216 return ExprError();
14217
14218 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14219 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14220
14221 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14222 End.get() != E->getArrayRangeEnd(D);
14223
14224 ArrayExprs.push_back(Elt: Start.get());
14225 ArrayExprs.push_back(Elt: End.get());
14226 }
14227
14228 if (!getDerived().AlwaysRebuild() &&
14229 Init.get() == E->getInit() &&
14230 !ExprChanged)
14231 return E;
14232
14233 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14234 E->getEqualOrColonLoc(),
14235 E->usesGNUSyntax(), Init.get());
14236}
14237
14238// Seems that if TransformInitListExpr() only works on the syntactic form of an
14239// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14240template<typename Derived>
14241ExprResult
14242TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14243 DesignatedInitUpdateExpr *E) {
14244 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14245 "initializer");
14246 return ExprError();
14247}
14248
14249template<typename Derived>
14250ExprResult
14251TreeTransform<Derived>::TransformNoInitExpr(
14252 NoInitExpr *E) {
14253 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14254 return ExprError();
14255}
14256
14257template<typename Derived>
14258ExprResult
14259TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14260 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14261 return ExprError();
14262}
14263
14264template<typename Derived>
14265ExprResult
14266TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14267 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14268 return ExprError();
14269}
14270
14271template<typename Derived>
14272ExprResult
14273TreeTransform<Derived>::TransformImplicitValueInitExpr(
14274 ImplicitValueInitExpr *E) {
14275 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14276
14277 // FIXME: Will we ever have proper type location here? Will we actually
14278 // need to transform the type?
14279 QualType T = getDerived().TransformType(E->getType());
14280 if (T.isNull())
14281 return ExprError();
14282
14283 if (!getDerived().AlwaysRebuild() &&
14284 T == E->getType())
14285 return E;
14286
14287 return getDerived().RebuildImplicitValueInitExpr(T);
14288}
14289
14290template<typename Derived>
14291ExprResult
14292TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14293 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14294 if (!TInfo)
14295 return ExprError();
14296
14297 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14298 if (SubExpr.isInvalid())
14299 return ExprError();
14300
14301 if (!getDerived().AlwaysRebuild() &&
14302 TInfo == E->getWrittenTypeInfo() &&
14303 SubExpr.get() == E->getSubExpr())
14304 return E;
14305
14306 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14307 TInfo, E->getRParenLoc());
14308}
14309
14310template<typename Derived>
14311ExprResult
14312TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14313 bool ArgumentChanged = false;
14314 SmallVector<Expr*, 4> Inits;
14315 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14316 ArgChanged: &ArgumentChanged))
14317 return ExprError();
14318
14319 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14320 Inits,
14321 E->getRParenLoc());
14322}
14323
14324/// Transform an address-of-label expression.
14325///
14326/// By default, the transformation of an address-of-label expression always
14327/// rebuilds the expression, so that the label identifier can be resolved to
14328/// the corresponding label statement by semantic analysis.
14329template<typename Derived>
14330ExprResult
14331TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14332 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14333 E->getLabel());
14334 if (!LD)
14335 return ExprError();
14336
14337 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14338 cast<LabelDecl>(Val: LD));
14339}
14340
14341template<typename Derived>
14342ExprResult
14343TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14344 SemaRef.ActOnStartStmtExpr();
14345 StmtResult SubStmt
14346 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14347 if (SubStmt.isInvalid()) {
14348 SemaRef.ActOnStmtExprError();
14349 return ExprError();
14350 }
14351
14352 unsigned OldDepth = E->getTemplateDepth();
14353 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14354
14355 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14356 SubStmt.get() == E->getSubStmt()) {
14357 // Calling this an 'error' is unintuitive, but it does the right thing.
14358 SemaRef.ActOnStmtExprError();
14359 return SemaRef.MaybeBindToTemporary(E);
14360 }
14361
14362 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14363 E->getRParenLoc(), NewDepth);
14364}
14365
14366template<typename Derived>
14367ExprResult
14368TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14369 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14370 if (Cond.isInvalid())
14371 return ExprError();
14372
14373 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14374 if (LHS.isInvalid())
14375 return ExprError();
14376
14377 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14378 if (RHS.isInvalid())
14379 return ExprError();
14380
14381 if (!getDerived().AlwaysRebuild() &&
14382 Cond.get() == E->getCond() &&
14383 LHS.get() == E->getLHS() &&
14384 RHS.get() == E->getRHS())
14385 return E;
14386
14387 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14388 Cond.get(), LHS.get(), RHS.get(),
14389 E->getRParenLoc());
14390}
14391
14392template<typename Derived>
14393ExprResult
14394TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14395 return E;
14396}
14397
14398template<typename Derived>
14399ExprResult
14400TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14401 switch (E->getOperator()) {
14402 case OO_New:
14403 case OO_Delete:
14404 case OO_Array_New:
14405 case OO_Array_Delete:
14406 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14407
14408 case OO_Subscript:
14409 case OO_Call: {
14410 // This is a call to an object's operator().
14411 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14412
14413 // Transform the object itself.
14414 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14415 if (Object.isInvalid())
14416 return ExprError();
14417
14418 // FIXME: Poor location information. Also, if the location for the end of
14419 // the token is within a macro expansion, getLocForEndOfToken() will return
14420 // an invalid source location. If that happens and we have an otherwise
14421 // valid end location, use the valid one instead of the invalid one.
14422 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14423 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14424 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14425 FakeLParenLoc = EndLoc;
14426
14427 // Transform the call arguments.
14428 SmallVector<Expr*, 8> Args;
14429 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14430 Args))
14431 return ExprError();
14432
14433 if (E->getOperator() == OO_Subscript)
14434 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14435 Args, E->getEndLoc());
14436
14437 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14438 E->getEndLoc());
14439 }
14440
14441#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14442 case OO_##Name: \
14443 break;
14444
14445#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14446#include "clang/Basic/OperatorKinds.def"
14447
14448 case OO_Conditional:
14449 llvm_unreachable("conditional operator is not actually overloadable");
14450
14451 case OO_None:
14452 case NUM_OVERLOADED_OPERATORS:
14453 llvm_unreachable("not an overloaded operator?");
14454 }
14455
14456 ExprResult First;
14457 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14458 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14459 else
14460 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14461 if (First.isInvalid())
14462 return ExprError();
14463
14464 ExprResult Second;
14465 if (E->getNumArgs() == 2) {
14466 Second =
14467 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14468 if (Second.isInvalid())
14469 return ExprError();
14470 }
14471
14472 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14473 FPOptionsOverride NewOverrides(E->getFPFeatures());
14474 getSema().CurFPFeatures =
14475 NewOverrides.applyOverrides(getSema().getLangOpts());
14476 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14477
14478 Expr *Callee = E->getCallee();
14479 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14480 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14481 Sema::LookupOrdinaryName);
14482 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14483 return ExprError();
14484
14485 return getDerived().RebuildCXXOperatorCallExpr(
14486 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14487 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14488 }
14489
14490 UnresolvedSet<1> Functions;
14491 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14492 Callee = ICE->getSubExprAsWritten();
14493 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14494 ValueDecl *VD = cast_or_null<ValueDecl>(
14495 getDerived().TransformDecl(DR->getLocation(), DR));
14496 if (!VD)
14497 return ExprError();
14498
14499 if (!isa<CXXMethodDecl>(Val: VD))
14500 Functions.addDecl(D: VD);
14501
14502 return getDerived().RebuildCXXOperatorCallExpr(
14503 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14504 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14505}
14506
14507template<typename Derived>
14508ExprResult
14509TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14510 return getDerived().TransformCallExpr(E);
14511}
14512
14513template <typename Derived>
14514ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14515 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14516 getSema().CurContext != E->getParentContext();
14517
14518 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14519 return E;
14520
14521 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14522 E->getBeginLoc(), E->getEndLoc(),
14523 getSema().CurContext);
14524}
14525
14526template <typename Derived>
14527ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14528 return E;
14529}
14530
14531template<typename Derived>
14532ExprResult
14533TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14534 // Transform the callee.
14535 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14536 if (Callee.isInvalid())
14537 return ExprError();
14538
14539 // Transform exec config.
14540 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14541 if (EC.isInvalid())
14542 return ExprError();
14543
14544 // Transform arguments.
14545 bool ArgChanged = false;
14546 SmallVector<Expr*, 8> Args;
14547 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14548 &ArgChanged))
14549 return ExprError();
14550
14551 if (!getDerived().AlwaysRebuild() &&
14552 Callee.get() == E->getCallee() &&
14553 !ArgChanged)
14554 return SemaRef.MaybeBindToTemporary(E);
14555
14556 // FIXME: Wrong source location information for the '('.
14557 SourceLocation FakeLParenLoc
14558 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14559 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14560 Args,
14561 E->getRParenLoc(), EC.get());
14562}
14563
14564template<typename Derived>
14565ExprResult
14566TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14567 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14568 if (!Type)
14569 return ExprError();
14570
14571 ExprResult SubExpr
14572 = getDerived().TransformExpr(E->getSubExprAsWritten());
14573 if (SubExpr.isInvalid())
14574 return ExprError();
14575
14576 if (!getDerived().AlwaysRebuild() &&
14577 Type == E->getTypeInfoAsWritten() &&
14578 SubExpr.get() == E->getSubExpr())
14579 return E;
14580 return getDerived().RebuildCXXNamedCastExpr(
14581 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14582 Type, E->getAngleBrackets().getEnd(),
14583 // FIXME. this should be '(' location
14584 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14585}
14586
14587template<typename Derived>
14588ExprResult
14589TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14590 TypeSourceInfo *TSI =
14591 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14592 if (!TSI)
14593 return ExprError();
14594
14595 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14596 if (Sub.isInvalid())
14597 return ExprError();
14598
14599 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14600 Sub.get(), BCE->getEndLoc());
14601}
14602
14603template<typename Derived>
14604ExprResult
14605TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14606 return getDerived().TransformCXXNamedCastExpr(E);
14607}
14608
14609template<typename Derived>
14610ExprResult
14611TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14612 return getDerived().TransformCXXNamedCastExpr(E);
14613}
14614
14615template<typename Derived>
14616ExprResult
14617TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14618 CXXReinterpretCastExpr *E) {
14619 return getDerived().TransformCXXNamedCastExpr(E);
14620}
14621
14622template<typename Derived>
14623ExprResult
14624TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14625 return getDerived().TransformCXXNamedCastExpr(E);
14626}
14627
14628template<typename Derived>
14629ExprResult
14630TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14631 return getDerived().TransformCXXNamedCastExpr(E);
14632}
14633
14634template<typename Derived>
14635ExprResult
14636TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14637 CXXFunctionalCastExpr *E) {
14638 TypeSourceInfo *Type =
14639 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14640 if (!Type)
14641 return ExprError();
14642
14643 ExprResult SubExpr
14644 = getDerived().TransformExpr(E->getSubExprAsWritten());
14645 if (SubExpr.isInvalid())
14646 return ExprError();
14647
14648 if (!getDerived().AlwaysRebuild() &&
14649 Type == E->getTypeInfoAsWritten() &&
14650 SubExpr.get() == E->getSubExpr())
14651 return E;
14652
14653 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14654 E->getLParenLoc(),
14655 SubExpr.get(),
14656 E->getRParenLoc(),
14657 E->isListInitialization());
14658}
14659
14660template<typename Derived>
14661ExprResult
14662TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14663 if (E->isTypeOperand()) {
14664 TypeSourceInfo *TInfo
14665 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14666 if (!TInfo)
14667 return ExprError();
14668
14669 if (!getDerived().AlwaysRebuild() &&
14670 TInfo == E->getTypeOperandSourceInfo())
14671 return E;
14672
14673 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14674 TInfo, E->getEndLoc());
14675 }
14676
14677 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14678 // type. We must not unilaterally enter unevaluated context here, as then
14679 // semantic processing can re-transform an already transformed operand.
14680 Expr *Op = E->getExprOperand();
14681 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14682 if (E->isGLValue()) {
14683 QualType OpType = Op->getType();
14684 if (auto *RD = OpType->getAsCXXRecordDecl()) {
14685 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
14686 DiagID: diag::err_incomplete_typeid))
14687 return ExprError();
14688
14689 if (RD->isPolymorphic())
14690 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14691 }
14692 }
14693
14694 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14695 Sema::ReuseLambdaContextDecl);
14696
14697 ExprResult SubExpr = getDerived().TransformExpr(Op);
14698 if (SubExpr.isInvalid())
14699 return ExprError();
14700
14701 if (!getDerived().AlwaysRebuild() &&
14702 SubExpr.get() == E->getExprOperand())
14703 return E;
14704
14705 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14706 SubExpr.get(), E->getEndLoc());
14707}
14708
14709template<typename Derived>
14710ExprResult
14711TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14712 if (E->isTypeOperand()) {
14713 TypeSourceInfo *TInfo
14714 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14715 if (!TInfo)
14716 return ExprError();
14717
14718 if (!getDerived().AlwaysRebuild() &&
14719 TInfo == E->getTypeOperandSourceInfo())
14720 return E;
14721
14722 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14723 TInfo, E->getEndLoc());
14724 }
14725
14726 EnterExpressionEvaluationContext Unevaluated(
14727 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14728
14729 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14730 if (SubExpr.isInvalid())
14731 return ExprError();
14732
14733 if (!getDerived().AlwaysRebuild() &&
14734 SubExpr.get() == E->getExprOperand())
14735 return E;
14736
14737 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14738 SubExpr.get(), E->getEndLoc());
14739}
14740
14741template<typename Derived>
14742ExprResult
14743TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14744 return E;
14745}
14746
14747template<typename Derived>
14748ExprResult
14749TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14750 CXXNullPtrLiteralExpr *E) {
14751 return E;
14752}
14753
14754template<typename Derived>
14755ExprResult
14756TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14757
14758 // In lambdas, the qualifiers of the type depends of where in
14759 // the call operator `this` appear, and we do not have a good way to
14760 // rebuild this information, so we transform the type.
14761 //
14762 // In other contexts, the type of `this` may be overrided
14763 // for type deduction, so we need to recompute it.
14764 //
14765 // Always recompute the type if we're in the body of a lambda, and
14766 // 'this' is dependent on a lambda's explicit object parameter; we
14767 // also need to always rebuild the expression in this case to clear
14768 // the flag.
14769 QualType T = [&]() {
14770 auto &S = getSema();
14771 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14772 return S.getCurrentThisType();
14773 if (S.getCurLambda())
14774 return getDerived().TransformType(E->getType());
14775 return S.getCurrentThisType();
14776 }();
14777
14778 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
14779 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
14780 // Mark it referenced in the new context regardless.
14781 // FIXME: this is a bit instantiation-specific.
14782 getSema().MarkThisReferenced(E);
14783 return E;
14784 }
14785
14786 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14787}
14788
14789template<typename Derived>
14790ExprResult
14791TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14792 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14793 if (SubExpr.isInvalid())
14794 return ExprError();
14795
14796 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14797
14798 if (!getDerived().AlwaysRebuild() &&
14799 SubExpr.get() == E->getSubExpr())
14800 return E;
14801
14802 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14803 E->isThrownVariableInScope());
14804}
14805
14806template<typename Derived>
14807ExprResult
14808TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14809 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14810 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14811 if (!Param)
14812 return ExprError();
14813
14814 ExprResult InitRes;
14815 if (E->hasRewrittenInit()) {
14816 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14817 if (InitRes.isInvalid())
14818 return ExprError();
14819 }
14820
14821 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14822 E->getUsedContext() == SemaRef.CurContext &&
14823 InitRes.get() == E->getRewrittenExpr())
14824 return E;
14825
14826 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14827 InitRes.get());
14828}
14829
14830template<typename Derived>
14831ExprResult
14832TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14833 FieldDecl *Field = cast_or_null<FieldDecl>(
14834 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14835 if (!Field)
14836 return ExprError();
14837
14838 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14839 E->getUsedContext() == SemaRef.CurContext)
14840 return E;
14841
14842 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14843}
14844
14845template<typename Derived>
14846ExprResult
14847TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14848 CXXScalarValueInitExpr *E) {
14849 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14850 if (!T)
14851 return ExprError();
14852
14853 if (!getDerived().AlwaysRebuild() &&
14854 T == E->getTypeSourceInfo())
14855 return E;
14856
14857 return getDerived().RebuildCXXScalarValueInitExpr(T,
14858 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14859 E->getRParenLoc());
14860}
14861
14862template<typename Derived>
14863ExprResult
14864TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14865 // Transform the type that we're allocating
14866 TypeSourceInfo *AllocTypeInfo =
14867 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14868 if (!AllocTypeInfo)
14869 return ExprError();
14870
14871 // Transform the size of the array we're allocating (if any).
14872 std::optional<Expr *> ArraySize;
14873 if (E->isArray()) {
14874 ExprResult NewArraySize;
14875 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14876 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14877 if (NewArraySize.isInvalid())
14878 return ExprError();
14879 }
14880 ArraySize = NewArraySize.get();
14881 }
14882
14883 // Transform the placement arguments (if any).
14884 bool ArgumentChanged = false;
14885 SmallVector<Expr*, 8> PlacementArgs;
14886 if (getDerived().TransformExprs(E->getPlacementArgs(),
14887 E->getNumPlacementArgs(), true,
14888 PlacementArgs, &ArgumentChanged))
14889 return ExprError();
14890
14891 // Transform the initializer (if any).
14892 Expr *OldInit = E->getInitializer();
14893 ExprResult NewInit;
14894 if (OldInit)
14895 NewInit = getDerived().TransformInitializer(OldInit, true);
14896 if (NewInit.isInvalid())
14897 return ExprError();
14898
14899 // Transform new operator and delete operator.
14900 FunctionDecl *OperatorNew = nullptr;
14901 if (E->getOperatorNew()) {
14902 OperatorNew = cast_or_null<FunctionDecl>(
14903 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14904 if (!OperatorNew)
14905 return ExprError();
14906 }
14907
14908 FunctionDecl *OperatorDelete = nullptr;
14909 if (E->getOperatorDelete()) {
14910 OperatorDelete = cast_or_null<FunctionDecl>(
14911 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14912 if (!OperatorDelete)
14913 return ExprError();
14914 }
14915
14916 if (!getDerived().AlwaysRebuild() &&
14917 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14918 ArraySize == E->getArraySize() &&
14919 NewInit.get() == OldInit &&
14920 OperatorNew == E->getOperatorNew() &&
14921 OperatorDelete == E->getOperatorDelete() &&
14922 !ArgumentChanged) {
14923 // Mark any declarations we need as referenced.
14924 // FIXME: instantiation-specific.
14925 if (OperatorNew)
14926 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14927 if (OperatorDelete)
14928 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14929
14930 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14931 QualType ElementType
14932 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14933 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
14934 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
14935 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14936 }
14937 }
14938
14939 return E;
14940 }
14941
14942 QualType AllocType = AllocTypeInfo->getType();
14943 if (!ArraySize) {
14944 // If no array size was specified, but the new expression was
14945 // instantiated with an array type (e.g., "new T" where T is
14946 // instantiated with "int[4]"), extract the outer bound from the
14947 // array type as our array size. We do this with constant and
14948 // dependently-sized array types.
14949 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14950 if (!ArrayT) {
14951 // Do nothing
14952 } else if (const ConstantArrayType *ConsArrayT
14953 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14954 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14955 type: SemaRef.Context.getSizeType(),
14956 /*FIXME:*/ l: E->getBeginLoc());
14957 AllocType = ConsArrayT->getElementType();
14958 } else if (const DependentSizedArrayType *DepArrayT
14959 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14960 if (DepArrayT->getSizeExpr()) {
14961 ArraySize = DepArrayT->getSizeExpr();
14962 AllocType = DepArrayT->getElementType();
14963 }
14964 }
14965 }
14966
14967 return getDerived().RebuildCXXNewExpr(
14968 E->getBeginLoc(), E->isGlobalNew(),
14969 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14970 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14971 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14972}
14973
14974template<typename Derived>
14975ExprResult
14976TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14977 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14978 if (Operand.isInvalid())
14979 return ExprError();
14980
14981 // Transform the delete operator, if known.
14982 FunctionDecl *OperatorDelete = nullptr;
14983 if (E->getOperatorDelete()) {
14984 OperatorDelete = cast_or_null<FunctionDecl>(
14985 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14986 if (!OperatorDelete)
14987 return ExprError();
14988 }
14989
14990 if (!getDerived().AlwaysRebuild() &&
14991 Operand.get() == E->getArgument() &&
14992 OperatorDelete == E->getOperatorDelete()) {
14993 // Mark any declarations we need as referenced.
14994 // FIXME: instantiation-specific.
14995 if (OperatorDelete)
14996 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14997
14998 if (!E->getArgument()->isTypeDependent()) {
14999 QualType Destroyed = SemaRef.Context.getBaseElementType(
15000 QT: E->getDestroyedType());
15001 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15002 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15003 Func: SemaRef.LookupDestructor(Class: Record));
15004 }
15005
15006 return E;
15007 }
15008
15009 return getDerived().RebuildCXXDeleteExpr(
15010 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15011}
15012
15013template<typename Derived>
15014ExprResult
15015TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15016 CXXPseudoDestructorExpr *E) {
15017 ExprResult Base = getDerived().TransformExpr(E->getBase());
15018 if (Base.isInvalid())
15019 return ExprError();
15020
15021 ParsedType ObjectTypePtr;
15022 bool MayBePseudoDestructor = false;
15023 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15024 OpLoc: E->getOperatorLoc(),
15025 OpKind: E->isArrow()? tok::arrow : tok::period,
15026 ObjectType&: ObjectTypePtr,
15027 MayBePseudoDestructor);
15028 if (Base.isInvalid())
15029 return ExprError();
15030
15031 QualType ObjectType = ObjectTypePtr.get();
15032 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15033 if (QualifierLoc) {
15034 QualifierLoc
15035 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15036 if (!QualifierLoc)
15037 return ExprError();
15038 }
15039 CXXScopeSpec SS;
15040 SS.Adopt(Other: QualifierLoc);
15041
15042 PseudoDestructorTypeStorage Destroyed;
15043 if (E->getDestroyedTypeInfo()) {
15044 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15045 E->getDestroyedTypeInfo(), ObjectType,
15046 /*FirstQualifierInScope=*/nullptr);
15047 if (!DestroyedTypeInfo)
15048 return ExprError();
15049 Destroyed = DestroyedTypeInfo;
15050 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15051 // We aren't likely to be able to resolve the identifier down to a type
15052 // now anyway, so just retain the identifier.
15053 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15054 E->getDestroyedTypeLoc());
15055 } else {
15056 // Look for a destructor known with the given name.
15057 ParsedType T = SemaRef.getDestructorName(
15058 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15059 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15060 if (!T)
15061 return ExprError();
15062
15063 Destroyed
15064 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15065 Loc: E->getDestroyedTypeLoc());
15066 }
15067
15068 TypeSourceInfo *ScopeTypeInfo = nullptr;
15069 if (E->getScopeTypeInfo()) {
15070 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15071 E->getScopeTypeInfo(), ObjectType, nullptr);
15072 if (!ScopeTypeInfo)
15073 return ExprError();
15074 }
15075
15076 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15077 E->getOperatorLoc(),
15078 E->isArrow(),
15079 SS,
15080 ScopeTypeInfo,
15081 E->getColonColonLoc(),
15082 E->getTildeLoc(),
15083 Destroyed);
15084}
15085
15086template <typename Derived>
15087bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15088 bool RequiresADL,
15089 LookupResult &R) {
15090 // Transform all the decls.
15091 bool AllEmptyPacks = true;
15092 for (auto *OldD : Old->decls()) {
15093 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15094 if (!InstD) {
15095 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15096 // This can happen because of dependent hiding.
15097 if (isa<UsingShadowDecl>(Val: OldD))
15098 continue;
15099 else {
15100 R.clear();
15101 return true;
15102 }
15103 }
15104
15105 // Expand using pack declarations.
15106 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15107 ArrayRef<NamedDecl*> Decls = SingleDecl;
15108 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15109 Decls = UPD->expansions();
15110
15111 // Expand using declarations.
15112 for (auto *D : Decls) {
15113 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15114 for (auto *SD : UD->shadows())
15115 R.addDecl(D: SD);
15116 } else {
15117 R.addDecl(D);
15118 }
15119 }
15120
15121 AllEmptyPacks &= Decls.empty();
15122 }
15123
15124 // C++ [temp.res]/8.4.2:
15125 // The program is ill-formed, no diagnostic required, if [...] lookup for
15126 // a name in the template definition found a using-declaration, but the
15127 // lookup in the corresponding scope in the instantiation odoes not find
15128 // any declarations because the using-declaration was a pack expansion and
15129 // the corresponding pack is empty
15130 if (AllEmptyPacks && !RequiresADL) {
15131 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15132 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15133 return true;
15134 }
15135
15136 // Resolve a kind, but don't do any further analysis. If it's
15137 // ambiguous, the callee needs to deal with it.
15138 R.resolveKind();
15139
15140 if (Old->hasTemplateKeyword() && !R.empty()) {
15141 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15142 getSema().FilterAcceptableTemplateNames(R,
15143 /*AllowFunctionTemplates=*/true,
15144 /*AllowDependent=*/true);
15145 if (R.empty()) {
15146 // If a 'template' keyword was used, a lookup that finds only non-template
15147 // names is an error.
15148 getSema().Diag(R.getNameLoc(),
15149 diag::err_template_kw_refers_to_non_template)
15150 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15151 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15152 getSema().Diag(FoundDecl->getLocation(),
15153 diag::note_template_kw_refers_to_non_template)
15154 << R.getLookupName();
15155 return true;
15156 }
15157 }
15158
15159 return false;
15160}
15161
15162template <typename Derived>
15163ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15164 UnresolvedLookupExpr *Old) {
15165 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15166}
15167
15168template <typename Derived>
15169ExprResult
15170TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15171 bool IsAddressOfOperand) {
15172 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15173 Sema::LookupOrdinaryName);
15174
15175 // Transform the declaration set.
15176 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15177 return ExprError();
15178
15179 // Rebuild the nested-name qualifier, if present.
15180 CXXScopeSpec SS;
15181 if (Old->getQualifierLoc()) {
15182 NestedNameSpecifierLoc QualifierLoc
15183 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15184 if (!QualifierLoc)
15185 return ExprError();
15186
15187 SS.Adopt(Other: QualifierLoc);
15188 }
15189
15190 if (Old->getNamingClass()) {
15191 CXXRecordDecl *NamingClass
15192 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15193 Old->getNameLoc(),
15194 Old->getNamingClass()));
15195 if (!NamingClass) {
15196 R.clear();
15197 return ExprError();
15198 }
15199
15200 R.setNamingClass(NamingClass);
15201 }
15202
15203 // Rebuild the template arguments, if any.
15204 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15205 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15206 if (Old->hasExplicitTemplateArgs() &&
15207 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15208 Old->getNumTemplateArgs(),
15209 TransArgs)) {
15210 R.clear();
15211 return ExprError();
15212 }
15213
15214 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15215 // a non-static data member is named in an unevaluated operand, or when
15216 // a member is named in a dependent class scope function template explicit
15217 // specialization that is neither declared static nor with an explicit object
15218 // parameter.
15219 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15220 return SemaRef.BuildPossibleImplicitMemberExpr(
15221 SS, TemplateKWLoc, R,
15222 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15223 /*S=*/S: nullptr);
15224
15225 // If we have neither explicit template arguments, nor the template keyword,
15226 // it's a normal declaration name or member reference.
15227 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15228 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15229
15230 // If we have template arguments, then rebuild the template-id expression.
15231 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15232 Old->requiresADL(), &TransArgs);
15233}
15234
15235template<typename Derived>
15236ExprResult
15237TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15238 bool ArgChanged = false;
15239 SmallVector<TypeSourceInfo *, 4> Args;
15240 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15241 TypeSourceInfo *From = E->getArg(I);
15242 TypeLoc FromTL = From->getTypeLoc();
15243 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15244 TypeLocBuilder TLB;
15245 TLB.reserve(Requested: FromTL.getFullDataSize());
15246 QualType To = getDerived().TransformType(TLB, FromTL);
15247 if (To.isNull())
15248 return ExprError();
15249
15250 if (To == From->getType())
15251 Args.push_back(Elt: From);
15252 else {
15253 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15254 ArgChanged = true;
15255 }
15256 continue;
15257 }
15258
15259 ArgChanged = true;
15260
15261 // We have a pack expansion. Instantiate it.
15262 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15263 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15264 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15265 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15266
15267 // Determine whether the set of unexpanded parameter packs can and should
15268 // be expanded.
15269 bool Expand = true;
15270 bool RetainExpansion = false;
15271 UnsignedOrNone OrigNumExpansions =
15272 ExpansionTL.getTypePtr()->getNumExpansions();
15273 UnsignedOrNone NumExpansions = OrigNumExpansions;
15274 if (getDerived().TryExpandParameterPacks(
15275 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15276 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15277 RetainExpansion, NumExpansions))
15278 return ExprError();
15279
15280 if (!Expand) {
15281 // The transform has determined that we should perform a simple
15282 // transformation on the pack expansion, producing another pack
15283 // expansion.
15284 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15285
15286 TypeLocBuilder TLB;
15287 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15288
15289 QualType To = getDerived().TransformType(TLB, PatternTL);
15290 if (To.isNull())
15291 return ExprError();
15292
15293 To = getDerived().RebuildPackExpansionType(To,
15294 PatternTL.getSourceRange(),
15295 ExpansionTL.getEllipsisLoc(),
15296 NumExpansions);
15297 if (To.isNull())
15298 return ExprError();
15299
15300 PackExpansionTypeLoc ToExpansionTL
15301 = TLB.push<PackExpansionTypeLoc>(T: To);
15302 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15303 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15304 continue;
15305 }
15306
15307 // Expand the pack expansion by substituting for each argument in the
15308 // pack(s).
15309 for (unsigned I = 0; I != *NumExpansions; ++I) {
15310 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15311 TypeLocBuilder TLB;
15312 TLB.reserve(Requested: PatternTL.getFullDataSize());
15313 QualType To = getDerived().TransformType(TLB, PatternTL);
15314 if (To.isNull())
15315 return ExprError();
15316
15317 if (To->containsUnexpandedParameterPack()) {
15318 To = getDerived().RebuildPackExpansionType(To,
15319 PatternTL.getSourceRange(),
15320 ExpansionTL.getEllipsisLoc(),
15321 NumExpansions);
15322 if (To.isNull())
15323 return ExprError();
15324
15325 PackExpansionTypeLoc ToExpansionTL
15326 = TLB.push<PackExpansionTypeLoc>(T: To);
15327 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15328 }
15329
15330 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15331 }
15332
15333 if (!RetainExpansion)
15334 continue;
15335
15336 // If we're supposed to retain a pack expansion, do so by temporarily
15337 // forgetting the partially-substituted parameter pack.
15338 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15339
15340 TypeLocBuilder TLB;
15341 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15342
15343 QualType To = getDerived().TransformType(TLB, PatternTL);
15344 if (To.isNull())
15345 return ExprError();
15346
15347 To = getDerived().RebuildPackExpansionType(To,
15348 PatternTL.getSourceRange(),
15349 ExpansionTL.getEllipsisLoc(),
15350 NumExpansions);
15351 if (To.isNull())
15352 return ExprError();
15353
15354 PackExpansionTypeLoc ToExpansionTL
15355 = TLB.push<PackExpansionTypeLoc>(T: To);
15356 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15357 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15358 }
15359
15360 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15361 return E;
15362
15363 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15364 E->getEndLoc());
15365}
15366
15367template<typename Derived>
15368ExprResult
15369TreeTransform<Derived>::TransformConceptSpecializationExpr(
15370 ConceptSpecializationExpr *E) {
15371 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15372 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15373 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15374 Old->NumTemplateArgs, TransArgs))
15375 return ExprError();
15376
15377 return getDerived().RebuildConceptSpecializationExpr(
15378 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15379 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
15380 &TransArgs);
15381}
15382
15383template<typename Derived>
15384ExprResult
15385TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15386 SmallVector<ParmVarDecl*, 4> TransParams;
15387 SmallVector<QualType, 4> TransParamTypes;
15388 Sema::ExtParameterInfoBuilder ExtParamInfos;
15389
15390 // C++2a [expr.prim.req]p2
15391 // Expressions appearing within a requirement-body are unevaluated operands.
15392 EnterExpressionEvaluationContext Ctx(
15393 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15394 Sema::ReuseLambdaContextDecl);
15395
15396 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15397 C&: getSema().Context, DC: getSema().CurContext,
15398 StartLoc: E->getBody()->getBeginLoc());
15399
15400 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15401
15402 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15403 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15404 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15405
15406 for (ParmVarDecl *Param : TransParams)
15407 if (Param)
15408 Param->setDeclContext(Body);
15409
15410 // On failure to transform, TransformRequiresTypeParams returns an expression
15411 // in the event that the transformation of the type params failed in some way.
15412 // It is expected that this will result in a 'not satisfied' Requires clause
15413 // when instantiating.
15414 if (!TypeParamResult.isUnset())
15415 return TypeParamResult;
15416
15417 SmallVector<concepts::Requirement *, 4> TransReqs;
15418 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15419 TransReqs))
15420 return ExprError();
15421
15422 for (concepts::Requirement *Req : TransReqs) {
15423 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15424 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15425 ER->getReturnTypeRequirement()
15426 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15427 ->setDeclContext(Body);
15428 }
15429 }
15430 }
15431
15432 return getDerived().RebuildRequiresExpr(
15433 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15434 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15435}
15436
15437template<typename Derived>
15438bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15439 ArrayRef<concepts::Requirement *> Reqs,
15440 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15441 for (concepts::Requirement *Req : Reqs) {
15442 concepts::Requirement *TransReq = nullptr;
15443 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15444 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15445 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15446 TransReq = getDerived().TransformExprRequirement(ExprReq);
15447 else
15448 TransReq = getDerived().TransformNestedRequirement(
15449 cast<concepts::NestedRequirement>(Val: Req));
15450 if (!TransReq)
15451 return true;
15452 Transformed.push_back(Elt: TransReq);
15453 }
15454 return false;
15455}
15456
15457template<typename Derived>
15458concepts::TypeRequirement *
15459TreeTransform<Derived>::TransformTypeRequirement(
15460 concepts::TypeRequirement *Req) {
15461 if (Req->isSubstitutionFailure()) {
15462 if (getDerived().AlwaysRebuild())
15463 return getDerived().RebuildTypeRequirement(
15464 Req->getSubstitutionDiagnostic());
15465 return Req;
15466 }
15467 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15468 if (!TransType)
15469 return nullptr;
15470 return getDerived().RebuildTypeRequirement(TransType);
15471}
15472
15473template<typename Derived>
15474concepts::ExprRequirement *
15475TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15476 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15477 if (Req->isExprSubstitutionFailure())
15478 TransExpr = Req->getExprSubstitutionDiagnostic();
15479 else {
15480 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15481 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15482 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15483 if (TransExprRes.isInvalid())
15484 return nullptr;
15485 TransExpr = TransExprRes.get();
15486 }
15487
15488 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15489 const auto &RetReq = Req->getReturnTypeRequirement();
15490 if (RetReq.isEmpty())
15491 TransRetReq.emplace();
15492 else if (RetReq.isSubstitutionFailure())
15493 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15494 else if (RetReq.isTypeConstraint()) {
15495 TemplateParameterList *OrigTPL =
15496 RetReq.getTypeConstraintTemplateParameterList();
15497 TemplateParameterList *TPL =
15498 getDerived().TransformTemplateParameterList(OrigTPL);
15499 if (!TPL)
15500 return nullptr;
15501 TransRetReq.emplace(args&: TPL);
15502 }
15503 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15504 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15505 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15506 Req->getNoexceptLoc(),
15507 std::move(*TransRetReq));
15508 return getDerived().RebuildExprRequirement(
15509 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15510 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15511}
15512
15513template<typename Derived>
15514concepts::NestedRequirement *
15515TreeTransform<Derived>::TransformNestedRequirement(
15516 concepts::NestedRequirement *Req) {
15517 if (Req->hasInvalidConstraint()) {
15518 if (getDerived().AlwaysRebuild())
15519 return getDerived().RebuildNestedRequirement(
15520 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15521 return Req;
15522 }
15523 ExprResult TransConstraint =
15524 getDerived().TransformExpr(Req->getConstraintExpr());
15525 if (TransConstraint.isInvalid())
15526 return nullptr;
15527 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15528}
15529
15530template<typename Derived>
15531ExprResult
15532TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15533 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15534 if (!T)
15535 return ExprError();
15536
15537 if (!getDerived().AlwaysRebuild() &&
15538 T == E->getQueriedTypeSourceInfo())
15539 return E;
15540
15541 ExprResult SubExpr;
15542 {
15543 EnterExpressionEvaluationContext Unevaluated(
15544 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15545 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15546 if (SubExpr.isInvalid())
15547 return ExprError();
15548 }
15549
15550 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15551 SubExpr.get(), E->getEndLoc());
15552}
15553
15554template<typename Derived>
15555ExprResult
15556TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15557 ExprResult SubExpr;
15558 {
15559 EnterExpressionEvaluationContext Unevaluated(
15560 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15561 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15562 if (SubExpr.isInvalid())
15563 return ExprError();
15564
15565 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15566 return E;
15567 }
15568
15569 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15570 SubExpr.get(), E->getEndLoc());
15571}
15572
15573template <typename Derived>
15574ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15575 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15576 TypeSourceInfo **RecoveryTSI) {
15577 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15578 DRE, AddrTaken, RecoveryTSI);
15579
15580 // Propagate both errors and recovered types, which return ExprEmpty.
15581 if (!NewDRE.isUsable())
15582 return NewDRE;
15583
15584 // We got an expr, wrap it up in parens.
15585 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15586 return PE;
15587 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15588 PE->getRParen());
15589}
15590
15591template <typename Derived>
15592ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15593 DependentScopeDeclRefExpr *E) {
15594 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15595 nullptr);
15596}
15597
15598template <typename Derived>
15599ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15600 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15601 TypeSourceInfo **RecoveryTSI) {
15602 assert(E->getQualifierLoc());
15603 NestedNameSpecifierLoc QualifierLoc =
15604 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15605 if (!QualifierLoc)
15606 return ExprError();
15607 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15608
15609 // TODO: If this is a conversion-function-id, verify that the
15610 // destination type name (if present) resolves the same way after
15611 // instantiation as it did in the local scope.
15612
15613 DeclarationNameInfo NameInfo =
15614 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15615 if (!NameInfo.getName())
15616 return ExprError();
15617
15618 if (!E->hasExplicitTemplateArgs()) {
15619 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15620 // Note: it is sufficient to compare the Name component of NameInfo:
15621 // if name has not changed, DNLoc has not changed either.
15622 NameInfo.getName() == E->getDeclName())
15623 return E;
15624
15625 return getDerived().RebuildDependentScopeDeclRefExpr(
15626 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15627 IsAddressOfOperand, RecoveryTSI);
15628 }
15629
15630 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15631 if (getDerived().TransformTemplateArguments(
15632 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15633 return ExprError();
15634
15635 return getDerived().RebuildDependentScopeDeclRefExpr(
15636 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15637 RecoveryTSI);
15638}
15639
15640template<typename Derived>
15641ExprResult
15642TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15643 // CXXConstructExprs other than for list-initialization and
15644 // CXXTemporaryObjectExpr are always implicit, so when we have
15645 // a 1-argument construction we just transform that argument.
15646 if (getDerived().AllowSkippingCXXConstructExpr() &&
15647 ((E->getNumArgs() == 1 ||
15648 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15649 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15650 !E->isListInitialization()))
15651 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15652 /*DirectInit*/ false);
15653
15654 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15655
15656 QualType T = getDerived().TransformType(E->getType());
15657 if (T.isNull())
15658 return ExprError();
15659
15660 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15661 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15662 if (!Constructor)
15663 return ExprError();
15664
15665 bool ArgumentChanged = false;
15666 SmallVector<Expr*, 8> Args;
15667 {
15668 EnterExpressionEvaluationContext Context(
15669 getSema(), EnterExpressionEvaluationContext::InitList,
15670 E->isListInitialization());
15671 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15672 &ArgumentChanged))
15673 return ExprError();
15674 }
15675
15676 if (!getDerived().AlwaysRebuild() &&
15677 T == E->getType() &&
15678 Constructor == E->getConstructor() &&
15679 !ArgumentChanged) {
15680 // Mark the constructor as referenced.
15681 // FIXME: Instantiation-specific
15682 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15683 return E;
15684 }
15685
15686 return getDerived().RebuildCXXConstructExpr(
15687 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15688 E->hadMultipleCandidates(), E->isListInitialization(),
15689 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15690 E->getConstructionKind(), E->getParenOrBraceRange());
15691}
15692
15693template<typename Derived>
15694ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15695 CXXInheritedCtorInitExpr *E) {
15696 QualType T = getDerived().TransformType(E->getType());
15697 if (T.isNull())
15698 return ExprError();
15699
15700 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15701 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15702 if (!Constructor)
15703 return ExprError();
15704
15705 if (!getDerived().AlwaysRebuild() &&
15706 T == E->getType() &&
15707 Constructor == E->getConstructor()) {
15708 // Mark the constructor as referenced.
15709 // FIXME: Instantiation-specific
15710 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15711 return E;
15712 }
15713
15714 return getDerived().RebuildCXXInheritedCtorInitExpr(
15715 T, E->getLocation(), Constructor,
15716 E->constructsVBase(), E->inheritedFromVBase());
15717}
15718
15719/// Transform a C++ temporary-binding expression.
15720///
15721/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15722/// transform the subexpression and return that.
15723template<typename Derived>
15724ExprResult
15725TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15726 if (auto *Dtor = E->getTemporary()->getDestructor())
15727 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15728 Func: const_cast<CXXDestructorDecl *>(Dtor));
15729 return getDerived().TransformExpr(E->getSubExpr());
15730}
15731
15732/// Transform a C++ expression that contains cleanups that should
15733/// be run after the expression is evaluated.
15734///
15735/// Since ExprWithCleanups nodes are implicitly generated, we
15736/// just transform the subexpression and return that.
15737template<typename Derived>
15738ExprResult
15739TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15740 return getDerived().TransformExpr(E->getSubExpr());
15741}
15742
15743template<typename Derived>
15744ExprResult
15745TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15746 CXXTemporaryObjectExpr *E) {
15747 TypeSourceInfo *T =
15748 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15749 if (!T)
15750 return ExprError();
15751
15752 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15753 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15754 if (!Constructor)
15755 return ExprError();
15756
15757 bool ArgumentChanged = false;
15758 SmallVector<Expr*, 8> Args;
15759 Args.reserve(N: E->getNumArgs());
15760 {
15761 EnterExpressionEvaluationContext Context(
15762 getSema(), EnterExpressionEvaluationContext::InitList,
15763 E->isListInitialization());
15764 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15765 ArgChanged: &ArgumentChanged))
15766 return ExprError();
15767
15768 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15769 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
15770 /*IsExplicit=*/IsExplicit: true);
15771 if (Res.isInvalid())
15772 return ExprError();
15773 Args = {Res.get()};
15774 }
15775 }
15776
15777 if (!getDerived().AlwaysRebuild() &&
15778 T == E->getTypeSourceInfo() &&
15779 Constructor == E->getConstructor() &&
15780 !ArgumentChanged) {
15781 // FIXME: Instantiation-specific
15782 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15783 return SemaRef.MaybeBindToTemporary(E);
15784 }
15785
15786 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15787 return getDerived().RebuildCXXTemporaryObjectExpr(
15788 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15789}
15790
15791template<typename Derived>
15792ExprResult
15793TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15794 // Transform any init-capture expressions before entering the scope of the
15795 // lambda body, because they are not semantically within that scope.
15796 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15797 struct TransformedInitCapture {
15798 // The location of the ... if the result is retaining a pack expansion.
15799 SourceLocation EllipsisLoc;
15800 // Zero or more expansions of the init-capture.
15801 SmallVector<InitCaptureInfoTy, 4> Expansions;
15802 };
15803 SmallVector<TransformedInitCapture, 4> InitCaptures;
15804 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15805 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15806 CEnd = E->capture_end();
15807 C != CEnd; ++C) {
15808 if (!E->isInitCapture(Capture: C))
15809 continue;
15810
15811 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15812 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15813
15814 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15815 UnsignedOrNone NumExpansions) {
15816 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15817 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15818
15819 if (NewExprInitResult.isInvalid()) {
15820 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15821 return;
15822 }
15823 Expr *NewExprInit = NewExprInitResult.get();
15824
15825 QualType NewInitCaptureType =
15826 getSema().buildLambdaInitCaptureInitialization(
15827 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15828 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15829 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15830 VarDecl::CInit,
15831 NewExprInit);
15832 Result.Expansions.push_back(
15833 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15834 };
15835
15836 // If this is an init-capture pack, consider expanding the pack now.
15837 if (OldVD->isParameterPack()) {
15838 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15839 ->getTypeLoc()
15840 .castAs<PackExpansionTypeLoc>();
15841 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15842 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15843
15844 // Determine whether the set of unexpanded parameter packs can and should
15845 // be expanded.
15846 bool Expand = true;
15847 bool RetainExpansion = false;
15848 UnsignedOrNone OrigNumExpansions =
15849 ExpansionTL.getTypePtr()->getNumExpansions();
15850 UnsignedOrNone NumExpansions = OrigNumExpansions;
15851 if (getDerived().TryExpandParameterPacks(
15852 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
15853 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15854 RetainExpansion, NumExpansions))
15855 return ExprError();
15856 assert(!RetainExpansion && "Should not need to retain expansion after a "
15857 "capture since it cannot be extended");
15858 if (Expand) {
15859 for (unsigned I = 0; I != *NumExpansions; ++I) {
15860 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15861 SubstInitCapture(SourceLocation(), std::nullopt);
15862 }
15863 } else {
15864 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15865 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15866 }
15867 } else {
15868 SubstInitCapture(SourceLocation(), std::nullopt);
15869 }
15870 }
15871
15872 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15873 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15874
15875 // Create the local class that will describe the lambda.
15876
15877 // FIXME: DependencyKind below is wrong when substituting inside a templated
15878 // context that isn't a DeclContext (such as a variable template), or when
15879 // substituting an unevaluated lambda inside of a function's parameter's type
15880 // - as parameter types are not instantiated from within a function's DC. We
15881 // use evaluation contexts to distinguish the function parameter case.
15882 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15883 CXXRecordDecl::LDK_Unknown;
15884 DeclContext *DC = getSema().CurContext;
15885 // A RequiresExprBodyDecl is not interesting for dependencies.
15886 // For the following case,
15887 //
15888 // template <typename>
15889 // concept C = requires { [] {}; };
15890 //
15891 // template <class F>
15892 // struct Widget;
15893 //
15894 // template <C F>
15895 // struct Widget<F> {};
15896 //
15897 // While we are substituting Widget<F>, the parent of DC would be
15898 // the template specialization itself. Thus, the lambda expression
15899 // will be deemed as dependent even if there are no dependent template
15900 // arguments.
15901 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15902 while (DC->isRequiresExprBody())
15903 DC = DC->getParent();
15904 if ((getSema().isUnevaluatedContext() ||
15905 getSema().isConstantEvaluatedContext()) &&
15906 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
15907 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
15908 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15909 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15910
15911 CXXRecordDecl *OldClass = E->getLambdaClass();
15912 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15913 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15914 E->getCaptureDefault());
15915 getDerived().transformedLocalDecl(OldClass, {Class});
15916
15917 CXXMethodDecl *NewCallOperator =
15918 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15919
15920 // Enter the scope of the lambda.
15921 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15922 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15923 E->hasExplicitParameters(), E->isMutable());
15924
15925 // Introduce the context of the call operator.
15926 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15927 /*NewThisContext*/false);
15928
15929 bool Invalid = false;
15930
15931 // Transform captures.
15932 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15933 CEnd = E->capture_end();
15934 C != CEnd; ++C) {
15935 // When we hit the first implicit capture, tell Sema that we've finished
15936 // the list of explicit captures.
15937 if (C->isImplicit())
15938 break;
15939
15940 // Capturing 'this' is trivial.
15941 if (C->capturesThis()) {
15942 // If this is a lambda that is part of a default member initialiser
15943 // and which we're instantiating outside the class that 'this' is
15944 // supposed to refer to, adjust the type of 'this' accordingly.
15945 //
15946 // Otherwise, leave the type of 'this' as-is.
15947 Sema::CXXThisScopeRAII ThisScope(
15948 getSema(),
15949 dyn_cast_if_present<CXXRecordDecl>(
15950 getSema().getFunctionLevelDeclContext()),
15951 Qualifiers());
15952 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15953 /*BuildAndDiagnose*/ true, nullptr,
15954 C->getCaptureKind() == LCK_StarThis);
15955 continue;
15956 }
15957 // Captured expression will be recaptured during captured variables
15958 // rebuilding.
15959 if (C->capturesVLAType())
15960 continue;
15961
15962 // Rebuild init-captures, including the implied field declaration.
15963 if (E->isInitCapture(Capture: C)) {
15964 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15965
15966 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15967 llvm::SmallVector<Decl*, 4> NewVDs;
15968
15969 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15970 ExprResult Init = Info.first;
15971 QualType InitQualType = Info.second;
15972 if (Init.isInvalid() || InitQualType.isNull()) {
15973 Invalid = true;
15974 break;
15975 }
15976 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15977 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15978 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15979 getSema().CurContext);
15980 if (!NewVD) {
15981 Invalid = true;
15982 break;
15983 }
15984 NewVDs.push_back(Elt: NewVD);
15985 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15986 // Cases we want to tackle:
15987 // ([C(Pack)] {}, ...)
15988 // But rule out cases e.g.
15989 // [...C = Pack()] {}
15990 if (NewC.EllipsisLoc.isInvalid())
15991 LSI->ContainsUnexpandedParameterPack |=
15992 Init.get()->containsUnexpandedParameterPack();
15993 }
15994
15995 if (Invalid)
15996 break;
15997
15998 getDerived().transformedLocalDecl(OldVD, NewVDs);
15999 continue;
16000 }
16001
16002 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16003
16004 // Determine the capture kind for Sema.
16005 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16006 : C->getCaptureKind() == LCK_ByCopy
16007 ? TryCaptureKind::ExplicitByVal
16008 : TryCaptureKind::ExplicitByRef;
16009 SourceLocation EllipsisLoc;
16010 if (C->isPackExpansion()) {
16011 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16012 bool ShouldExpand = false;
16013 bool RetainExpansion = false;
16014 UnsignedOrNone NumExpansions = std::nullopt;
16015 if (getDerived().TryExpandParameterPacks(
16016 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16017 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16018 RetainExpansion, NumExpansions)) {
16019 Invalid = true;
16020 continue;
16021 }
16022
16023 if (ShouldExpand) {
16024 // The transform has determined that we should perform an expansion;
16025 // transform and capture each of the arguments.
16026 // expansion of the pattern. Do so.
16027 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16028 for (unsigned I = 0; I != *NumExpansions; ++I) {
16029 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16030 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16031 getDerived().TransformDecl(C->getLocation(), Pack));
16032 if (!CapturedVar) {
16033 Invalid = true;
16034 continue;
16035 }
16036
16037 // Capture the transformed variable.
16038 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16039 }
16040
16041 // FIXME: Retain a pack expansion if RetainExpansion is true.
16042
16043 continue;
16044 }
16045
16046 EllipsisLoc = C->getEllipsisLoc();
16047 }
16048
16049 // Transform the captured variable.
16050 auto *CapturedVar = cast_or_null<ValueDecl>(
16051 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16052 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16053 Invalid = true;
16054 continue;
16055 }
16056
16057 // This is not an init-capture; however it contains an unexpanded pack e.g.
16058 // ([Pack] {}(), ...)
16059 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16060 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16061
16062 // Capture the transformed variable.
16063 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16064 EllipsisLoc);
16065 }
16066 getSema().finishLambdaExplicitCaptures(LSI);
16067
16068 // Transform the template parameters, and add them to the current
16069 // instantiation scope. The null case is handled correctly.
16070 auto TPL = getDerived().TransformTemplateParameterList(
16071 E->getTemplateParameterList());
16072 LSI->GLTemplateParameterList = TPL;
16073 if (TPL) {
16074 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16075 TPL);
16076 LSI->ContainsUnexpandedParameterPack |=
16077 TPL->containsUnexpandedParameterPack();
16078 }
16079
16080 TypeLocBuilder NewCallOpTLBuilder;
16081 TypeLoc OldCallOpTypeLoc =
16082 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16083 QualType NewCallOpType =
16084 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16085 if (NewCallOpType.isNull())
16086 return ExprError();
16087 LSI->ContainsUnexpandedParameterPack |=
16088 NewCallOpType->containsUnexpandedParameterPack();
16089 TypeSourceInfo *NewCallOpTSI =
16090 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16091
16092 // The type may be an AttributedType or some other kind of sugar;
16093 // get the actual underlying FunctionProtoType.
16094 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16095 assert(FPTL && "Not a FunctionProtoType?");
16096
16097 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16098 // If the concept refers to any outer parameter packs, we track the SubstIndex
16099 // for evaluation.
16100 if (TRC && TRC.ConstraintExpr->containsUnexpandedParameterPack() &&
16101 !TRC.ArgPackSubstIndex)
16102 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
16103
16104 getSema().CompleteLambdaCallOperator(
16105 NewCallOperator, E->getCallOperator()->getLocation(),
16106 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16107 E->getCallOperator()->getConstexprKind(),
16108 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16109 E->hasExplicitResultType());
16110
16111 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16112 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16113
16114 {
16115 // Number the lambda for linkage purposes if necessary.
16116 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16117
16118 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16119 if (getDerived().ReplacingOriginal()) {
16120 Numbering = OldClass->getLambdaNumbering();
16121 }
16122
16123 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16124 }
16125
16126 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16127 // evaluation context even if we're not transforming the function body.
16128 getSema().PushExpressionEvaluationContextForFunction(
16129 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16130 E->getCallOperator());
16131
16132 StmtResult Body;
16133 {
16134 Sema::NonSFINAEContext _(getSema());
16135 Sema::CodeSynthesisContext C;
16136 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16137 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16138 getSema().pushCodeSynthesisContext(C);
16139
16140 // Instantiate the body of the lambda expression.
16141 Body = Invalid ? StmtError()
16142 : getDerived().TransformLambdaBody(E, E->getBody());
16143
16144 getSema().popCodeSynthesisContext();
16145 }
16146
16147 // ActOnLambda* will pop the function scope for us.
16148 FuncScopeCleanup.disable();
16149
16150 if (Body.isInvalid()) {
16151 SavedContext.pop();
16152 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16153 /*IsInstantiation=*/true);
16154 return ExprError();
16155 }
16156
16157 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16158 /*IsInstantiation=*/true,
16159 /*RetainFunctionScopeInfo=*/true);
16160 SavedContext.pop();
16161
16162 // Recompute the dependency of the lambda so that we can defer the lambda call
16163 // construction until after we have all the necessary template arguments. For
16164 // example, given
16165 //
16166 // template <class> struct S {
16167 // template <class U>
16168 // using Type = decltype([](U){}(42.0));
16169 // };
16170 // void foo() {
16171 // using T = S<int>::Type<float>;
16172 // ^~~~~~
16173 // }
16174 //
16175 // We would end up here from instantiating S<int> when ensuring its
16176 // completeness. That would transform the lambda call expression regardless of
16177 // the absence of the corresponding argument for U.
16178 //
16179 // Going ahead with unsubstituted type U makes things worse: we would soon
16180 // compare the argument type (which is float) against the parameter U
16181 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16182 // error suggesting unmatched types 'U' and 'float'!
16183 //
16184 // That said, everything will be fine if we defer that semantic checking.
16185 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16186 // dependent. Since the CallExpr's dependency boils down to the lambda's
16187 // dependency in this case, we can harness that by recomputing the dependency
16188 // from the instantiation arguments.
16189 //
16190 // FIXME: Creating the type of a lambda requires us to have a dependency
16191 // value, which happens before its substitution. We update its dependency
16192 // *after* the substitution in case we can't decide the dependency
16193 // so early, e.g. because we want to see if any of the *substituted*
16194 // parameters are dependent.
16195 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16196 Class->setLambdaDependencyKind(DependencyKind);
16197
16198 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16199 Body.get()->getEndLoc(), LSI);
16200}
16201
16202template<typename Derived>
16203StmtResult
16204TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16205 return TransformStmt(S);
16206}
16207
16208template<typename Derived>
16209StmtResult
16210TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16211 // Transform captures.
16212 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16213 CEnd = E->capture_end();
16214 C != CEnd; ++C) {
16215 // When we hit the first implicit capture, tell Sema that we've finished
16216 // the list of explicit captures.
16217 if (!C->isImplicit())
16218 continue;
16219
16220 // Capturing 'this' is trivial.
16221 if (C->capturesThis()) {
16222 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16223 /*BuildAndDiagnose*/ true, nullptr,
16224 C->getCaptureKind() == LCK_StarThis);
16225 continue;
16226 }
16227 // Captured expression will be recaptured during captured variables
16228 // rebuilding.
16229 if (C->capturesVLAType())
16230 continue;
16231
16232 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16233 assert(!E->isInitCapture(C) && "implicit init-capture?");
16234
16235 // Transform the captured variable.
16236 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16237 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16238 if (!CapturedVar || CapturedVar->isInvalidDecl())
16239 return StmtError();
16240
16241 // Capture the transformed variable.
16242 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16243 }
16244
16245 return S;
16246}
16247
16248template<typename Derived>
16249ExprResult
16250TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16251 CXXUnresolvedConstructExpr *E) {
16252 TypeSourceInfo *T =
16253 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16254 if (!T)
16255 return ExprError();
16256
16257 bool ArgumentChanged = false;
16258 SmallVector<Expr*, 8> Args;
16259 Args.reserve(N: E->getNumArgs());
16260 {
16261 EnterExpressionEvaluationContext Context(
16262 getSema(), EnterExpressionEvaluationContext::InitList,
16263 E->isListInitialization());
16264 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16265 &ArgumentChanged))
16266 return ExprError();
16267 }
16268
16269 if (!getDerived().AlwaysRebuild() &&
16270 T == E->getTypeSourceInfo() &&
16271 !ArgumentChanged)
16272 return E;
16273
16274 // FIXME: we're faking the locations of the commas
16275 return getDerived().RebuildCXXUnresolvedConstructExpr(
16276 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16277}
16278
16279template<typename Derived>
16280ExprResult
16281TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16282 CXXDependentScopeMemberExpr *E) {
16283 // Transform the base of the expression.
16284 ExprResult Base((Expr*) nullptr);
16285 Expr *OldBase;
16286 QualType BaseType;
16287 QualType ObjectType;
16288 if (!E->isImplicitAccess()) {
16289 OldBase = E->getBase();
16290 Base = getDerived().TransformExpr(OldBase);
16291 if (Base.isInvalid())
16292 return ExprError();
16293
16294 // Start the member reference and compute the object's type.
16295 ParsedType ObjectTy;
16296 bool MayBePseudoDestructor = false;
16297 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16298 OpLoc: E->getOperatorLoc(),
16299 OpKind: E->isArrow()? tok::arrow : tok::period,
16300 ObjectType&: ObjectTy,
16301 MayBePseudoDestructor);
16302 if (Base.isInvalid())
16303 return ExprError();
16304
16305 ObjectType = ObjectTy.get();
16306 BaseType = ((Expr*) Base.get())->getType();
16307 } else {
16308 OldBase = nullptr;
16309 BaseType = getDerived().TransformType(E->getBaseType());
16310 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16311 }
16312
16313 // Transform the first part of the nested-name-specifier that qualifies
16314 // the member name.
16315 NamedDecl *FirstQualifierInScope
16316 = getDerived().TransformFirstQualifierInScope(
16317 E->getFirstQualifierFoundInScope(),
16318 E->getQualifierLoc().getBeginLoc());
16319
16320 NestedNameSpecifierLoc QualifierLoc;
16321 if (E->getQualifier()) {
16322 QualifierLoc
16323 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16324 ObjectType,
16325 FirstQualifierInScope);
16326 if (!QualifierLoc)
16327 return ExprError();
16328 }
16329
16330 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16331
16332 // TODO: If this is a conversion-function-id, verify that the
16333 // destination type name (if present) resolves the same way after
16334 // instantiation as it did in the local scope.
16335
16336 DeclarationNameInfo NameInfo
16337 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16338 if (!NameInfo.getName())
16339 return ExprError();
16340
16341 if (!E->hasExplicitTemplateArgs()) {
16342 // This is a reference to a member without an explicitly-specified
16343 // template argument list. Optimize for this common case.
16344 if (!getDerived().AlwaysRebuild() &&
16345 Base.get() == OldBase &&
16346 BaseType == E->getBaseType() &&
16347 QualifierLoc == E->getQualifierLoc() &&
16348 NameInfo.getName() == E->getMember() &&
16349 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16350 return E;
16351
16352 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16353 BaseType,
16354 E->isArrow(),
16355 E->getOperatorLoc(),
16356 QualifierLoc,
16357 TemplateKWLoc,
16358 FirstQualifierInScope,
16359 NameInfo,
16360 /*TemplateArgs*/nullptr);
16361 }
16362
16363 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16364 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16365 E->getNumTemplateArgs(),
16366 TransArgs))
16367 return ExprError();
16368
16369 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16370 BaseType,
16371 E->isArrow(),
16372 E->getOperatorLoc(),
16373 QualifierLoc,
16374 TemplateKWLoc,
16375 FirstQualifierInScope,
16376 NameInfo,
16377 &TransArgs);
16378}
16379
16380template <typename Derived>
16381ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16382 UnresolvedMemberExpr *Old) {
16383 // Transform the base of the expression.
16384 ExprResult Base((Expr *)nullptr);
16385 QualType BaseType;
16386 if (!Old->isImplicitAccess()) {
16387 Base = getDerived().TransformExpr(Old->getBase());
16388 if (Base.isInvalid())
16389 return ExprError();
16390 Base =
16391 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16392 if (Base.isInvalid())
16393 return ExprError();
16394 BaseType = Base.get()->getType();
16395 } else {
16396 BaseType = getDerived().TransformType(Old->getBaseType());
16397 }
16398
16399 NestedNameSpecifierLoc QualifierLoc;
16400 if (Old->getQualifierLoc()) {
16401 QualifierLoc =
16402 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16403 if (!QualifierLoc)
16404 return ExprError();
16405 }
16406
16407 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16408
16409 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16410
16411 // Transform the declaration set.
16412 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16413 return ExprError();
16414
16415 // Determine the naming class.
16416 if (Old->getNamingClass()) {
16417 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16418 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16419 if (!NamingClass)
16420 return ExprError();
16421
16422 R.setNamingClass(NamingClass);
16423 }
16424
16425 TemplateArgumentListInfo TransArgs;
16426 if (Old->hasExplicitTemplateArgs()) {
16427 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16428 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16429 if (getDerived().TransformTemplateArguments(
16430 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16431 return ExprError();
16432 }
16433
16434 // FIXME: to do this check properly, we will need to preserve the
16435 // first-qualifier-in-scope here, just in case we had a dependent
16436 // base (and therefore couldn't do the check) and a
16437 // nested-name-qualifier (and therefore could do the lookup).
16438 NamedDecl *FirstQualifierInScope = nullptr;
16439
16440 return getDerived().RebuildUnresolvedMemberExpr(
16441 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16442 TemplateKWLoc, FirstQualifierInScope, R,
16443 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16444}
16445
16446template<typename Derived>
16447ExprResult
16448TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16449 EnterExpressionEvaluationContext Unevaluated(
16450 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16451 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16452 if (SubExpr.isInvalid())
16453 return ExprError();
16454
16455 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16456 return E;
16457
16458 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16459}
16460
16461template<typename Derived>
16462ExprResult
16463TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16464 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16465 if (Pattern.isInvalid())
16466 return ExprError();
16467
16468 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16469 return E;
16470
16471 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16472 E->getNumExpansions());
16473}
16474
16475template <typename Derived>
16476UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16477 ArrayRef<TemplateArgument> PackArgs) {
16478 UnsignedOrNone Result = 0u;
16479 for (const TemplateArgument &Arg : PackArgs) {
16480 if (!Arg.isPackExpansion()) {
16481 Result = *Result + 1;
16482 continue;
16483 }
16484
16485 TemplateArgumentLoc ArgLoc;
16486 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16487
16488 // Find the pattern of the pack expansion.
16489 SourceLocation Ellipsis;
16490 UnsignedOrNone OrigNumExpansions = std::nullopt;
16491 TemplateArgumentLoc Pattern =
16492 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16493 OrigNumExpansions);
16494
16495 // Substitute under the pack expansion. Do not expand the pack (yet).
16496 TemplateArgumentLoc OutPattern;
16497 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16498 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16499 /*Uneval*/ true))
16500 return 1u;
16501
16502 // See if we can determine the number of arguments from the result.
16503 UnsignedOrNone NumExpansions =
16504 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16505 if (!NumExpansions) {
16506 // No: we must be in an alias template expansion, and we're going to
16507 // need to actually expand the packs.
16508 Result = std::nullopt;
16509 break;
16510 }
16511
16512 Result = *Result + *NumExpansions;
16513 }
16514 return Result;
16515}
16516
16517template<typename Derived>
16518ExprResult
16519TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16520 // If E is not value-dependent, then nothing will change when we transform it.
16521 // Note: This is an instantiation-centric view.
16522 if (!E->isValueDependent())
16523 return E;
16524
16525 EnterExpressionEvaluationContext Unevaluated(
16526 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16527
16528 ArrayRef<TemplateArgument> PackArgs;
16529 TemplateArgument ArgStorage;
16530
16531 // Find the argument list to transform.
16532 if (E->isPartiallySubstituted()) {
16533 PackArgs = E->getPartialArguments();
16534 } else if (E->isValueDependent()) {
16535 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16536 bool ShouldExpand = false;
16537 bool RetainExpansion = false;
16538 UnsignedOrNone NumExpansions = std::nullopt;
16539 if (getDerived().TryExpandParameterPacks(
16540 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16541 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16542 RetainExpansion, NumExpansions))
16543 return ExprError();
16544
16545 // If we need to expand the pack, build a template argument from it and
16546 // expand that.
16547 if (ShouldExpand) {
16548 auto *Pack = E->getPack();
16549 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16550 ArgStorage = getSema().Context.getPackExpansionType(
16551 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16552 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16553 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16554 } else {
16555 auto *VD = cast<ValueDecl>(Val: Pack);
16556 ExprResult DRE = getSema().BuildDeclRefExpr(
16557 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16558 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16559 E->getPackLoc());
16560 if (DRE.isInvalid())
16561 return ExprError();
16562 ArgStorage = TemplateArgument(
16563 new (getSema().Context)
16564 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16565 /*IsCanonical=*/false);
16566 }
16567 PackArgs = ArgStorage;
16568 }
16569 }
16570
16571 // If we're not expanding the pack, just transform the decl.
16572 if (!PackArgs.size()) {
16573 auto *Pack = cast_or_null<NamedDecl>(
16574 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16575 if (!Pack)
16576 return ExprError();
16577 return getDerived().RebuildSizeOfPackExpr(
16578 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16579 std::nullopt, {});
16580 }
16581
16582 // Try to compute the result without performing a partial substitution.
16583 UnsignedOrNone Result =
16584 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16585
16586 // Common case: we could determine the number of expansions without
16587 // substituting.
16588 if (Result)
16589 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16590 E->getPackLoc(),
16591 E->getRParenLoc(), *Result, {});
16592
16593 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16594 E->getPackLoc());
16595 {
16596 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16597 typedef TemplateArgumentLocInventIterator<
16598 Derived, const TemplateArgument*> PackLocIterator;
16599 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16600 PackLocIterator(*this, PackArgs.end()),
16601 TransformedPackArgs, /*Uneval*/true))
16602 return ExprError();
16603 }
16604
16605 // Check whether we managed to fully-expand the pack.
16606 // FIXME: Is it possible for us to do so and not hit the early exit path?
16607 SmallVector<TemplateArgument, 8> Args;
16608 bool PartialSubstitution = false;
16609 for (auto &Loc : TransformedPackArgs.arguments()) {
16610 Args.push_back(Elt: Loc.getArgument());
16611 if (Loc.getArgument().isPackExpansion())
16612 PartialSubstitution = true;
16613 }
16614
16615 if (PartialSubstitution)
16616 return getDerived().RebuildSizeOfPackExpr(
16617 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16618 std::nullopt, Args);
16619
16620 return getDerived().RebuildSizeOfPackExpr(
16621 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16622 /*Length=*/static_cast<unsigned>(Args.size()),
16623 /*PartialArgs=*/{});
16624}
16625
16626template <typename Derived>
16627ExprResult
16628TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16629 if (!E->isValueDependent())
16630 return E;
16631
16632 // Transform the index
16633 ExprResult IndexExpr;
16634 {
16635 EnterExpressionEvaluationContext ConstantContext(
16636 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16637 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16638 if (IndexExpr.isInvalid())
16639 return ExprError();
16640 }
16641
16642 SmallVector<Expr *, 5> ExpandedExprs;
16643 bool FullySubstituted = true;
16644 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16645 Expr *Pattern = E->getPackIdExpression();
16646 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16647 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16648 Unexpanded);
16649 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16650
16651 // Determine whether the set of unexpanded parameter packs can and should
16652 // be expanded.
16653 bool ShouldExpand = true;
16654 bool RetainExpansion = false;
16655 UnsignedOrNone OrigNumExpansions = std::nullopt,
16656 NumExpansions = std::nullopt;
16657 if (getDerived().TryExpandParameterPacks(
16658 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16659 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16660 RetainExpansion, NumExpansions))
16661 return true;
16662 if (!ShouldExpand) {
16663 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16664 ExprResult Pack = getDerived().TransformExpr(Pattern);
16665 if (Pack.isInvalid())
16666 return ExprError();
16667 return getDerived().RebuildPackIndexingExpr(
16668 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16669 {}, /*FullySubstituted=*/false);
16670 }
16671 for (unsigned I = 0; I != *NumExpansions; ++I) {
16672 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16673 ExprResult Out = getDerived().TransformExpr(Pattern);
16674 if (Out.isInvalid())
16675 return true;
16676 if (Out.get()->containsUnexpandedParameterPack()) {
16677 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16678 OrigNumExpansions);
16679 if (Out.isInvalid())
16680 return true;
16681 FullySubstituted = false;
16682 }
16683 ExpandedExprs.push_back(Elt: Out.get());
16684 }
16685 // If we're supposed to retain a pack expansion, do so by temporarily
16686 // forgetting the partially-substituted parameter pack.
16687 if (RetainExpansion) {
16688 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16689
16690 ExprResult Out = getDerived().TransformExpr(Pattern);
16691 if (Out.isInvalid())
16692 return true;
16693
16694 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16695 OrigNumExpansions);
16696 if (Out.isInvalid())
16697 return true;
16698 FullySubstituted = false;
16699 ExpandedExprs.push_back(Elt: Out.get());
16700 }
16701 } else if (!E->expandsToEmptyPack()) {
16702 if (getDerived().TransformExprs(E->getExpressions().data(),
16703 E->getExpressions().size(), false,
16704 ExpandedExprs))
16705 return ExprError();
16706 }
16707
16708 return getDerived().RebuildPackIndexingExpr(
16709 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16710 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16711}
16712
16713template <typename Derived>
16714ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16715 SubstNonTypeTemplateParmPackExpr *E) {
16716 if (!getSema().ArgPackSubstIndex)
16717 // We aren't expanding the parameter pack, so just return ourselves.
16718 return E;
16719
16720 TemplateArgument Pack = E->getArgumentPack();
16721 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
16722 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16723 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
16724 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
16725 SemaRef.getPackIndex(Pack), E->getFinal());
16726}
16727
16728template <typename Derived>
16729ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16730 SubstNonTypeTemplateParmExpr *E) {
16731 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
16732
16733 // Insert a constant-evaluated context for the transform.
16734 // Otherwise, when a normalized constraint places the replacement inside
16735 // an unevaluated operand (e.g. decltype), entities it refers to are not
16736 // odr-used, and the constant evaluation performed by CheckTemplateArgument
16737 // below can spuriously fail for otherwise valid replacements,
16738 // e.g. when a call materializes a function parameter of class type whose
16739 // special members were never instantiated.
16740 EnterExpressionEvaluationContext ConstantEvaluated(
16741 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
16742 Sema::ReuseLambdaContextDecl,
16743 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
16744
16745 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
16746 if (Replacement.isInvalid())
16747 return true;
16748
16749 Decl *AssociatedDecl =
16750 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
16751 if (!AssociatedDecl)
16752 return true;
16753
16754 QualType ParamType = TransformType(E->getParameterType());
16755 if (ParamType.isNull())
16756 return true;
16757
16758 if (Replacement.get() == OrigReplacement &&
16759 AssociatedDecl == E->getAssociatedDecl() &&
16760 ParamType == E->getParameterType())
16761 return E;
16762
16763 if (Replacement.get() != OrigReplacement ||
16764 ParamType != E->getParameterType()) {
16765 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
16766 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
16767 // When transforming the replacement expression previously, all Sema
16768 // specific annotations, such as implicit casts, are discarded. Calling the
16769 // corresponding sema action is necessary to recover those. Otherwise,
16770 // equivalency of the result would be lost.
16771 TemplateArgument SugaredConverted, CanonicalConverted;
16772 Replacement = SemaRef.CheckTemplateArgument(
16773 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
16774 CanonicalConverted,
16775 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
16776 if (Replacement.isInvalid())
16777 return true;
16778 } else {
16779 // Otherwise, the same expression would have been produced.
16780 Replacement = E->getReplacement();
16781 }
16782
16783 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16784 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
16785 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
16786 E->getPackIndex(), E->getFinal());
16787}
16788
16789template<typename Derived>
16790ExprResult
16791TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16792 // Default behavior is to do nothing with this transformation.
16793 return E;
16794}
16795
16796template<typename Derived>
16797ExprResult
16798TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16799 MaterializeTemporaryExpr *E) {
16800 return getDerived().TransformExpr(E->getSubExpr());
16801}
16802
16803template<typename Derived>
16804ExprResult
16805TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16806 UnresolvedLookupExpr *Callee = nullptr;
16807 if (Expr *OldCallee = E->getCallee()) {
16808 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16809 if (CalleeResult.isInvalid())
16810 return ExprError();
16811 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16812 }
16813
16814 Expr *Pattern = E->getPattern();
16815
16816 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16817 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16818 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16819
16820 // Determine whether the set of unexpanded parameter packs can and should
16821 // be expanded.
16822 bool Expand = true;
16823 bool RetainExpansion = false;
16824 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16825 NumExpansions = OrigNumExpansions;
16826 if (getDerived().TryExpandParameterPacks(
16827 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16828 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
16829 NumExpansions))
16830 return true;
16831
16832 if (!Expand) {
16833 // Do not expand any packs here, just transform and rebuild a fold
16834 // expression.
16835 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16836
16837 ExprResult LHS =
16838 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16839 if (LHS.isInvalid())
16840 return true;
16841
16842 ExprResult RHS =
16843 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16844 if (RHS.isInvalid())
16845 return true;
16846
16847 if (!getDerived().AlwaysRebuild() &&
16848 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16849 return E;
16850
16851 return getDerived().RebuildCXXFoldExpr(
16852 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16853 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16854 }
16855
16856 // Formally a fold expression expands to nested parenthesized expressions.
16857 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16858 // them.
16859 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16860 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16861 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16862 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16863 << E->getSourceRange();
16864 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16865 return ExprError();
16866 }
16867
16868 // The transform has determined that we should perform an elementwise
16869 // expansion of the pattern. Do so.
16870 ExprResult Result = getDerived().TransformExpr(E->getInit());
16871 if (Result.isInvalid())
16872 return true;
16873 bool LeftFold = E->isLeftFold();
16874
16875 // If we're retaining an expansion for a right fold, it is the innermost
16876 // component and takes the init (if any).
16877 if (!LeftFold && RetainExpansion) {
16878 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16879
16880 ExprResult Out = getDerived().TransformExpr(Pattern);
16881 if (Out.isInvalid())
16882 return true;
16883
16884 Result = getDerived().RebuildCXXFoldExpr(
16885 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16886 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16887 if (Result.isInvalid())
16888 return true;
16889 }
16890
16891 bool WarnedOnComparison = false;
16892 for (unsigned I = 0; I != *NumExpansions; ++I) {
16893 Sema::ArgPackSubstIndexRAII SubstIndex(
16894 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16895 ExprResult Out = getDerived().TransformExpr(Pattern);
16896 if (Out.isInvalid())
16897 return true;
16898
16899 if (Out.get()->containsUnexpandedParameterPack()) {
16900 // We still have a pack; retain a pack expansion for this slice.
16901 Result = getDerived().RebuildCXXFoldExpr(
16902 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16903 E->getOperator(), E->getEllipsisLoc(),
16904 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16905 OrigNumExpansions);
16906 } else if (Result.isUsable()) {
16907 // We've got down to a single element; build a binary operator.
16908 Expr *LHS = LeftFold ? Result.get() : Out.get();
16909 Expr *RHS = LeftFold ? Out.get() : Result.get();
16910 if (Callee) {
16911 UnresolvedSet<16> Functions;
16912 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16913 Result = getDerived().RebuildCXXOperatorCallExpr(
16914 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16915 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16916 Functions, LHS, RHS);
16917 } else {
16918 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16919 E->getOperator(), LHS, RHS,
16920 /*ForFoldExpresion=*/true);
16921 if (!WarnedOnComparison && Result.isUsable()) {
16922 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16923 BO && BO->isComparisonOp()) {
16924 WarnedOnComparison = true;
16925 SemaRef.Diag(Loc: BO->getBeginLoc(),
16926 DiagID: diag::warn_comparison_in_fold_expression)
16927 << BO->getOpcodeStr();
16928 }
16929 }
16930 }
16931 } else
16932 Result = Out;
16933
16934 if (Result.isInvalid())
16935 return true;
16936 }
16937
16938 // If we're retaining an expansion for a left fold, it is the outermost
16939 // component and takes the complete expansion so far as its init (if any).
16940 if (LeftFold && RetainExpansion) {
16941 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16942
16943 ExprResult Out = getDerived().TransformExpr(Pattern);
16944 if (Out.isInvalid())
16945 return true;
16946
16947 Result = getDerived().RebuildCXXFoldExpr(
16948 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16949 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16950 if (Result.isInvalid())
16951 return true;
16952 }
16953
16954 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16955 PE->setIsProducedByFoldExpansion();
16956
16957 // If we had no init and an empty pack, and we're not retaining an expansion,
16958 // then produce a fallback value or error.
16959 if (Result.isUnset())
16960 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16961 E->getOperator());
16962 return Result;
16963}
16964
16965template <typename Derived>
16966ExprResult
16967TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16968 SmallVector<Expr *, 4> TransformedInits;
16969 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16970
16971 QualType T = getDerived().TransformType(E->getType());
16972
16973 bool ArgChanged = false;
16974
16975 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16976 TransformedInits, &ArgChanged))
16977 return ExprError();
16978
16979 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16980 return E;
16981
16982 return getDerived().RebuildCXXParenListInitExpr(
16983 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16984 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16985}
16986
16987template<typename Derived>
16988ExprResult
16989TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16990 CXXStdInitializerListExpr *E) {
16991 return getDerived().TransformExpr(E->getSubExpr());
16992}
16993
16994template<typename Derived>
16995ExprResult
16996TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16997 return SemaRef.MaybeBindToTemporary(E);
16998}
16999
17000template<typename Derived>
17001ExprResult
17002TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17003 return E;
17004}
17005
17006template<typename Derived>
17007ExprResult
17008TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17009 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17010 if (SubExpr.isInvalid())
17011 return ExprError();
17012
17013 if (!getDerived().AlwaysRebuild() &&
17014 SubExpr.get() == E->getSubExpr())
17015 return E;
17016
17017 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17018}
17019
17020template<typename Derived>
17021ExprResult
17022TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17023 // Transform each of the elements.
17024 SmallVector<Expr *, 8> Elements;
17025 bool ArgChanged = false;
17026 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17027 /*IsCall=*/false, Elements, &ArgChanged))
17028 return ExprError();
17029
17030 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17031 return SemaRef.MaybeBindToTemporary(E);
17032
17033 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17034 Elements.data(),
17035 Elements.size());
17036}
17037
17038template<typename Derived>
17039ExprResult
17040TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17041 ObjCDictionaryLiteral *E) {
17042 // Transform each of the elements.
17043 SmallVector<ObjCDictionaryElement, 8> Elements;
17044 bool ArgChanged = false;
17045 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17046 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17047
17048 if (OrigElement.isPackExpansion()) {
17049 // This key/value element is a pack expansion.
17050 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17051 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17052 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17053 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17054
17055 // Determine whether the set of unexpanded parameter packs can
17056 // and should be expanded.
17057 bool Expand = true;
17058 bool RetainExpansion = false;
17059 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17060 UnsignedOrNone NumExpansions = OrigNumExpansions;
17061 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17062 OrigElement.Value->getEndLoc());
17063 if (getDerived().TryExpandParameterPacks(
17064 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17065 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17066 NumExpansions))
17067 return ExprError();
17068
17069 if (!Expand) {
17070 // The transform has determined that we should perform a simple
17071 // transformation on the pack expansion, producing another pack
17072 // expansion.
17073 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17074 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17075 if (Key.isInvalid())
17076 return ExprError();
17077
17078 if (Key.get() != OrigElement.Key)
17079 ArgChanged = true;
17080
17081 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17082 if (Value.isInvalid())
17083 return ExprError();
17084
17085 if (Value.get() != OrigElement.Value)
17086 ArgChanged = true;
17087
17088 ObjCDictionaryElement Expansion = {
17089 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17090 };
17091 Elements.push_back(Elt: Expansion);
17092 continue;
17093 }
17094
17095 // Record right away that the argument was changed. This needs
17096 // to happen even if the array expands to nothing.
17097 ArgChanged = true;
17098
17099 // The transform has determined that we should perform an elementwise
17100 // expansion of the pattern. Do so.
17101 for (unsigned I = 0; I != *NumExpansions; ++I) {
17102 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17103 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17104 if (Key.isInvalid())
17105 return ExprError();
17106
17107 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17108 if (Value.isInvalid())
17109 return ExprError();
17110
17111 ObjCDictionaryElement Element = {
17112 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17113 };
17114
17115 // If any unexpanded parameter packs remain, we still have a
17116 // pack expansion.
17117 // FIXME: Can this really happen?
17118 if (Key.get()->containsUnexpandedParameterPack() ||
17119 Value.get()->containsUnexpandedParameterPack())
17120 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17121
17122 Elements.push_back(Elt: Element);
17123 }
17124
17125 // FIXME: Retain a pack expansion if RetainExpansion is true.
17126
17127 // We've finished with this pack expansion.
17128 continue;
17129 }
17130
17131 // Transform and check key.
17132 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17133 if (Key.isInvalid())
17134 return ExprError();
17135
17136 if (Key.get() != OrigElement.Key)
17137 ArgChanged = true;
17138
17139 // Transform and check value.
17140 ExprResult Value
17141 = getDerived().TransformExpr(OrigElement.Value);
17142 if (Value.isInvalid())
17143 return ExprError();
17144
17145 if (Value.get() != OrigElement.Value)
17146 ArgChanged = true;
17147
17148 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17149 .NumExpansions: std::nullopt};
17150 Elements.push_back(Elt: Element);
17151 }
17152
17153 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17154 return SemaRef.MaybeBindToTemporary(E);
17155
17156 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17157 Elements);
17158}
17159
17160template<typename Derived>
17161ExprResult
17162TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17163 TypeSourceInfo *EncodedTypeInfo
17164 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17165 if (!EncodedTypeInfo)
17166 return ExprError();
17167
17168 if (!getDerived().AlwaysRebuild() &&
17169 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17170 return E;
17171
17172 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17173 EncodedTypeInfo,
17174 E->getRParenLoc());
17175}
17176
17177template<typename Derived>
17178ExprResult TreeTransform<Derived>::
17179TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17180 // This is a kind of implicit conversion, and it needs to get dropped
17181 // and recomputed for the same general reasons that ImplicitCastExprs
17182 // do, as well a more specific one: this expression is only valid when
17183 // it appears *immediately* as an argument expression.
17184 return getDerived().TransformExpr(E->getSubExpr());
17185}
17186
17187template<typename Derived>
17188ExprResult TreeTransform<Derived>::
17189TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17190 TypeSourceInfo *TSInfo
17191 = getDerived().TransformType(E->getTypeInfoAsWritten());
17192 if (!TSInfo)
17193 return ExprError();
17194
17195 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17196 if (Result.isInvalid())
17197 return ExprError();
17198
17199 if (!getDerived().AlwaysRebuild() &&
17200 TSInfo == E->getTypeInfoAsWritten() &&
17201 Result.get() == E->getSubExpr())
17202 return E;
17203
17204 return SemaRef.ObjC().BuildObjCBridgedCast(
17205 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17206 SubExpr: Result.get());
17207}
17208
17209template <typename Derived>
17210ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17211 ObjCAvailabilityCheckExpr *E) {
17212 return E;
17213}
17214
17215template<typename Derived>
17216ExprResult
17217TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17218 // Transform arguments.
17219 bool ArgChanged = false;
17220 SmallVector<Expr*, 8> Args;
17221 Args.reserve(N: E->getNumArgs());
17222 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17223 &ArgChanged))
17224 return ExprError();
17225
17226 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17227 // Class message: transform the receiver type.
17228 TypeSourceInfo *ReceiverTypeInfo
17229 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17230 if (!ReceiverTypeInfo)
17231 return ExprError();
17232
17233 // If nothing changed, just retain the existing message send.
17234 if (!getDerived().AlwaysRebuild() &&
17235 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17236 return SemaRef.MaybeBindToTemporary(E);
17237
17238 // Build a new class message send.
17239 SmallVector<SourceLocation, 16> SelLocs;
17240 E->getSelectorLocs(SelLocs);
17241 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17242 E->getSelector(),
17243 SelLocs,
17244 E->getMethodDecl(),
17245 E->getLeftLoc(),
17246 Args,
17247 E->getRightLoc());
17248 }
17249 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17250 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17251 if (!E->getMethodDecl())
17252 return ExprError();
17253
17254 // Build a new class message send to 'super'.
17255 SmallVector<SourceLocation, 16> SelLocs;
17256 E->getSelectorLocs(SelLocs);
17257 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17258 E->getSelector(),
17259 SelLocs,
17260 E->getReceiverType(),
17261 E->getMethodDecl(),
17262 E->getLeftLoc(),
17263 Args,
17264 E->getRightLoc());
17265 }
17266
17267 // Instance message: transform the receiver
17268 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17269 "Only class and instance messages may be instantiated");
17270 ExprResult Receiver
17271 = getDerived().TransformExpr(E->getInstanceReceiver());
17272 if (Receiver.isInvalid())
17273 return ExprError();
17274
17275 // If nothing changed, just retain the existing message send.
17276 if (!getDerived().AlwaysRebuild() &&
17277 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17278 return SemaRef.MaybeBindToTemporary(E);
17279
17280 // Build a new instance message send.
17281 SmallVector<SourceLocation, 16> SelLocs;
17282 E->getSelectorLocs(SelLocs);
17283 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17284 E->getSelector(),
17285 SelLocs,
17286 E->getMethodDecl(),
17287 E->getLeftLoc(),
17288 Args,
17289 E->getRightLoc());
17290}
17291
17292template<typename Derived>
17293ExprResult
17294TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17295 return E;
17296}
17297
17298template<typename Derived>
17299ExprResult
17300TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17301 return E;
17302}
17303
17304template<typename Derived>
17305ExprResult
17306TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17307 // Transform the base expression.
17308 ExprResult Base = getDerived().TransformExpr(E->getBase());
17309 if (Base.isInvalid())
17310 return ExprError();
17311
17312 // We don't need to transform the ivar; it will never change.
17313
17314 // If nothing changed, just retain the existing expression.
17315 if (!getDerived().AlwaysRebuild() &&
17316 Base.get() == E->getBase())
17317 return E;
17318
17319 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17320 E->getLocation(),
17321 E->isArrow(), E->isFreeIvar());
17322}
17323
17324template<typename Derived>
17325ExprResult
17326TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17327 // 'super' and types never change. Property never changes. Just
17328 // retain the existing expression.
17329 if (!E->isObjectReceiver())
17330 return E;
17331
17332 // Transform the base expression.
17333 ExprResult Base = getDerived().TransformExpr(E->getBase());
17334 if (Base.isInvalid())
17335 return ExprError();
17336
17337 // We don't need to transform the property; it will never change.
17338
17339 // If nothing changed, just retain the existing expression.
17340 if (!getDerived().AlwaysRebuild() &&
17341 Base.get() == E->getBase())
17342 return E;
17343
17344 if (E->isExplicitProperty())
17345 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17346 E->getExplicitProperty(),
17347 E->getLocation());
17348
17349 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17350 SemaRef.Context.PseudoObjectTy,
17351 E->getImplicitPropertyGetter(),
17352 E->getImplicitPropertySetter(),
17353 E->getLocation());
17354}
17355
17356template<typename Derived>
17357ExprResult
17358TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17359 // Transform the base expression.
17360 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17361 if (Base.isInvalid())
17362 return ExprError();
17363
17364 // Transform the key expression.
17365 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17366 if (Key.isInvalid())
17367 return ExprError();
17368
17369 // If nothing changed, just retain the existing expression.
17370 if (!getDerived().AlwaysRebuild() &&
17371 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17372 return E;
17373
17374 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17375 Base.get(), Key.get(),
17376 E->getAtIndexMethodDecl(),
17377 E->setAtIndexMethodDecl());
17378}
17379
17380template<typename Derived>
17381ExprResult
17382TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17383 // Transform the base expression.
17384 ExprResult Base = getDerived().TransformExpr(E->getBase());
17385 if (Base.isInvalid())
17386 return ExprError();
17387
17388 // If nothing changed, just retain the existing expression.
17389 if (!getDerived().AlwaysRebuild() &&
17390 Base.get() == E->getBase())
17391 return E;
17392
17393 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17394 E->getOpLoc(),
17395 E->isArrow());
17396}
17397
17398template<typename Derived>
17399ExprResult
17400TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17401 bool ArgumentChanged = false;
17402 SmallVector<Expr*, 8> SubExprs;
17403 SubExprs.reserve(N: E->getNumSubExprs());
17404 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17405 SubExprs, &ArgumentChanged))
17406 return ExprError();
17407
17408 if (!getDerived().AlwaysRebuild() &&
17409 !ArgumentChanged)
17410 return E;
17411
17412 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17413 SubExprs,
17414 E->getRParenLoc());
17415}
17416
17417template<typename Derived>
17418ExprResult
17419TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17420 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17421 if (SrcExpr.isInvalid())
17422 return ExprError();
17423
17424 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17425 if (!Type)
17426 return ExprError();
17427
17428 if (!getDerived().AlwaysRebuild() &&
17429 Type == E->getTypeSourceInfo() &&
17430 SrcExpr.get() == E->getSrcExpr())
17431 return E;
17432
17433 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17434 SrcExpr.get(), Type,
17435 E->getRParenLoc());
17436}
17437
17438template<typename Derived>
17439ExprResult
17440TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17441 BlockDecl *oldBlock = E->getBlockDecl();
17442
17443 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17444 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17445
17446 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17447 blockScope->TheDecl->setBlockMissingReturnType(
17448 oldBlock->blockMissingReturnType());
17449
17450 SmallVector<ParmVarDecl*, 4> params;
17451 SmallVector<QualType, 4> paramTypes;
17452
17453 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17454
17455 // Parameter substitution.
17456 Sema::ExtParameterInfoBuilder extParamInfos;
17457 if (getDerived().TransformFunctionTypeParams(
17458 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17459 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17460 extParamInfos)) {
17461 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17462 return ExprError();
17463 }
17464
17465 QualType exprResultType =
17466 getDerived().TransformType(exprFunctionType->getReturnType());
17467
17468 auto epi = exprFunctionType->getExtProtoInfo();
17469 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17470
17471 QualType functionType =
17472 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17473 blockScope->FunctionType = functionType;
17474
17475 // Set the parameters on the block decl.
17476 if (!params.empty())
17477 blockScope->TheDecl->setParams(params);
17478
17479 if (!oldBlock->blockMissingReturnType()) {
17480 blockScope->HasImplicitReturnType = false;
17481 blockScope->ReturnType = exprResultType;
17482 }
17483
17484 // Transform the body
17485 StmtResult body = getDerived().TransformStmt(E->getBody());
17486 if (body.isInvalid()) {
17487 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17488 return ExprError();
17489 }
17490
17491#ifndef NDEBUG
17492 // In builds with assertions, make sure that we captured everything we
17493 // captured before.
17494 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17495 for (const auto &I : oldBlock->captures()) {
17496 VarDecl *oldCapture = I.getVariable();
17497
17498 // Ignore parameter packs.
17499 if (oldCapture->isParameterPack())
17500 continue;
17501
17502 VarDecl *newCapture =
17503 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17504 oldCapture));
17505 assert(blockScope->CaptureMap.count(newCapture));
17506 }
17507
17508 // The this pointer may not be captured by the instantiated block, even when
17509 // it's captured by the original block, if the expression causing the
17510 // capture is in the discarded branch of a constexpr if statement.
17511 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17512 "this pointer isn't captured in the old block");
17513 }
17514#endif
17515
17516 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17517 /*Scope=*/CurScope: nullptr);
17518}
17519
17520template<typename Derived>
17521ExprResult
17522TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17523 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17524 if (SrcExpr.isInvalid())
17525 return ExprError();
17526
17527 QualType Type = getDerived().TransformType(E->getType());
17528
17529 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17530 RParenLoc: E->getRParenLoc());
17531}
17532
17533template<typename Derived>
17534ExprResult
17535TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17536 bool ArgumentChanged = false;
17537 SmallVector<Expr*, 8> SubExprs;
17538 SubExprs.reserve(N: E->getNumSubExprs());
17539 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17540 SubExprs, &ArgumentChanged))
17541 return ExprError();
17542
17543 if (!getDerived().AlwaysRebuild() &&
17544 !ArgumentChanged)
17545 return E;
17546
17547 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17548 E->getOp(), E->getRParenLoc());
17549}
17550
17551//===----------------------------------------------------------------------===//
17552// Type reconstruction
17553//===----------------------------------------------------------------------===//
17554
17555template<typename Derived>
17556QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17557 SourceLocation Star) {
17558 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17559 Entity: getDerived().getBaseEntity());
17560}
17561
17562template<typename Derived>
17563QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17564 SourceLocation Star) {
17565 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17566 Entity: getDerived().getBaseEntity());
17567}
17568
17569template<typename Derived>
17570QualType
17571TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17572 bool WrittenAsLValue,
17573 SourceLocation Sigil) {
17574 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17575 Loc: Sigil, Entity: getDerived().getBaseEntity());
17576}
17577
17578template <typename Derived>
17579QualType TreeTransform<Derived>::RebuildMemberPointerType(
17580 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17581 SourceLocation Sigil) {
17582 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17583 Entity: getDerived().getBaseEntity());
17584}
17585
17586template<typename Derived>
17587QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17588 const ObjCTypeParamDecl *Decl,
17589 SourceLocation ProtocolLAngleLoc,
17590 ArrayRef<ObjCProtocolDecl *> Protocols,
17591 ArrayRef<SourceLocation> ProtocolLocs,
17592 SourceLocation ProtocolRAngleLoc) {
17593 return SemaRef.ObjC().BuildObjCTypeParamType(
17594 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17595 /*FailOnError=*/FailOnError: true);
17596}
17597
17598template<typename Derived>
17599QualType TreeTransform<Derived>::RebuildObjCObjectType(
17600 QualType BaseType,
17601 SourceLocation Loc,
17602 SourceLocation TypeArgsLAngleLoc,
17603 ArrayRef<TypeSourceInfo *> TypeArgs,
17604 SourceLocation TypeArgsRAngleLoc,
17605 SourceLocation ProtocolLAngleLoc,
17606 ArrayRef<ObjCProtocolDecl *> Protocols,
17607 ArrayRef<SourceLocation> ProtocolLocs,
17608 SourceLocation ProtocolRAngleLoc) {
17609 return SemaRef.ObjC().BuildObjCObjectType(
17610 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17611 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17612 /*FailOnError=*/FailOnError: true,
17613 /*Rebuilding=*/Rebuilding: true);
17614}
17615
17616template<typename Derived>
17617QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17618 QualType PointeeType,
17619 SourceLocation Star) {
17620 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17621}
17622
17623template <typename Derived>
17624QualType TreeTransform<Derived>::RebuildArrayType(
17625 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17626 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17627 if (SizeExpr || !Size)
17628 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17629 Quals: IndexTypeQuals, Brackets: BracketsRange,
17630 Entity: getDerived().getBaseEntity());
17631
17632 QualType Types[] = {
17633 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17634 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17635 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17636 };
17637 QualType SizeType;
17638 for (const auto &T : Types)
17639 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17640 SizeType = T;
17641 break;
17642 }
17643
17644 // Note that we can return a VariableArrayType here in the case where
17645 // the element type was a dependent VariableArrayType.
17646 IntegerLiteral *ArraySize
17647 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17648 /*FIXME*/l: BracketsRange.getBegin());
17649 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17650 Quals: IndexTypeQuals, Brackets: BracketsRange,
17651 Entity: getDerived().getBaseEntity());
17652}
17653
17654template <typename Derived>
17655QualType TreeTransform<Derived>::RebuildConstantArrayType(
17656 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17657 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17658 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17659 IndexTypeQuals, BracketsRange);
17660}
17661
17662template <typename Derived>
17663QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17664 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17665 SourceRange BracketsRange) {
17666 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17667 IndexTypeQuals, BracketsRange);
17668}
17669
17670template <typename Derived>
17671QualType TreeTransform<Derived>::RebuildVariableArrayType(
17672 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17673 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17674 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17675 SizeExpr,
17676 IndexTypeQuals, BracketsRange);
17677}
17678
17679template <typename Derived>
17680QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17681 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17682 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17683 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17684 SizeExpr,
17685 IndexTypeQuals, BracketsRange);
17686}
17687
17688template <typename Derived>
17689QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17690 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17691 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17692 AttrLoc: AttributeLoc);
17693}
17694
17695template <typename Derived>
17696QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17697 unsigned NumElements,
17698 VectorKind VecKind) {
17699 // FIXME: semantic checking!
17700 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17701}
17702
17703template <typename Derived>
17704QualType TreeTransform<Derived>::RebuildDependentVectorType(
17705 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17706 VectorKind VecKind) {
17707 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17708}
17709
17710template<typename Derived>
17711QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17712 unsigned NumElements,
17713 SourceLocation AttributeLoc) {
17714 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17715 NumElements, true);
17716 IntegerLiteral *VectorSize
17717 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17718 l: AttributeLoc);
17719 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17720}
17721
17722template<typename Derived>
17723QualType
17724TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17725 Expr *SizeExpr,
17726 SourceLocation AttributeLoc) {
17727 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17728}
17729
17730template <typename Derived>
17731QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17732 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17733 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17734 NumColumns);
17735}
17736
17737template <typename Derived>
17738QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17739 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17740 SourceLocation AttributeLoc) {
17741 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17742 AttrLoc: AttributeLoc);
17743}
17744
17745template <typename Derived>
17746QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17747 QualType T, MutableArrayRef<QualType> ParamTypes,
17748 const FunctionProtoType::ExtProtoInfo &EPI) {
17749 return SemaRef.BuildFunctionType(T, ParamTypes,
17750 Loc: getDerived().getBaseLocation(),
17751 Entity: getDerived().getBaseEntity(),
17752 EPI);
17753}
17754
17755template<typename Derived>
17756QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17757 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17758}
17759
17760template <typename Derived>
17761QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
17762 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
17763 SourceLocation NameLoc, Decl *D) {
17764 assert(D && "no decl found");
17765 if (D->isInvalidDecl()) return QualType();
17766
17767 // FIXME: Doesn't account for ObjCInterfaceDecl!
17768 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17769 // A valid resolved using typename pack expansion decl can have multiple
17770 // UsingDecls, but they must each have exactly one type, and it must be
17771 // the same type in every case. But we must have at least one expansion!
17772 if (UPD->expansions().empty()) {
17773 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
17774 << UPD->isCXXClassMember() << UPD;
17775 return QualType();
17776 }
17777
17778 // We might still have some unresolved types. Try to pick a resolved type
17779 // if we can. The final instantiation will check that the remaining
17780 // unresolved types instantiate to the type we pick.
17781 QualType FallbackT;
17782 QualType T;
17783 for (auto *E : UPD->expansions()) {
17784 QualType ThisT =
17785 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
17786 if (ThisT.isNull())
17787 continue;
17788 if (ThisT->getAs<UnresolvedUsingType>())
17789 FallbackT = ThisT;
17790 else if (T.isNull())
17791 T = ThisT;
17792 else
17793 assert(getSema().Context.hasSameType(ThisT, T) &&
17794 "mismatched resolved types in using pack expansion");
17795 }
17796 return T.isNull() ? FallbackT : T;
17797 }
17798 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17799 assert(Using->hasTypename() &&
17800 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17801
17802 // A valid resolved using typename decl points to exactly one type decl.
17803 assert(++Using->shadow_begin() == Using->shadow_end());
17804
17805 UsingShadowDecl *Shadow = *Using->shadow_begin();
17806 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
17807 return QualType();
17808 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
17809 }
17810 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17811 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17812 return SemaRef.Context.getUnresolvedUsingType(
17813 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
17814}
17815
17816template <typename Derived>
17817QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17818 TypeOfKind Kind) {
17819 return SemaRef.BuildTypeofExprType(E, Kind);
17820}
17821
17822template<typename Derived>
17823QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17824 TypeOfKind Kind) {
17825 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17826}
17827
17828template <typename Derived>
17829QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17830 return SemaRef.BuildDecltypeType(E);
17831}
17832
17833template <typename Derived>
17834QualType TreeTransform<Derived>::RebuildPackIndexingType(
17835 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17836 SourceLocation EllipsisLoc, bool FullySubstituted,
17837 ArrayRef<QualType> Expansions) {
17838 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17839 FullySubstituted, Expansions);
17840}
17841
17842template<typename Derived>
17843QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17844 UnaryTransformType::UTTKind UKind,
17845 SourceLocation Loc) {
17846 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17847}
17848
17849template <typename Derived>
17850QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17851 ElaboratedTypeKeyword Keyword, TemplateName Template,
17852 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
17853 return SemaRef.CheckTemplateIdType(
17854 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
17855 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
17856}
17857
17858template<typename Derived>
17859QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17860 SourceLocation KWLoc) {
17861 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17862}
17863
17864template<typename Derived>
17865QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17866 SourceLocation KWLoc,
17867 bool isReadPipe) {
17868 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17869 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17870}
17871
17872template <typename Derived>
17873QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17874 unsigned NumBits,
17875 SourceLocation Loc) {
17876 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17877 NumBits, true);
17878 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17879 type: SemaRef.Context.IntTy, l: Loc);
17880 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17881}
17882
17883template <typename Derived>
17884QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17885 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17886 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17887}
17888
17889template <typename Derived>
17890TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17891 bool TemplateKW,
17892 TemplateName Name) {
17893 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17894 Template: Name);
17895}
17896
17897template <typename Derived>
17898TemplateName TreeTransform<Derived>::RebuildTemplateName(
17899 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
17900 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
17901 UnqualifiedId TemplateName;
17902 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17903 Sema::TemplateTy Template;
17904 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17905 TemplateName, ParsedType::make(P: ObjectType),
17906 /*EnteringContext=*/false, Template,
17907 AllowInjectedClassName);
17908 return Template.get();
17909}
17910
17911template<typename Derived>
17912TemplateName
17913TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17914 SourceLocation TemplateKWLoc,
17915 OverloadedOperatorKind Operator,
17916 SourceLocation NameLoc,
17917 QualType ObjectType,
17918 bool AllowInjectedClassName) {
17919 UnqualifiedId Name;
17920 // FIXME: Bogus location information.
17921 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17922 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17923 Sema::TemplateTy Template;
17924 getSema().ActOnTemplateName(
17925 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17926 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17927 return Template.get();
17928}
17929
17930template <typename Derived>
17931ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17932 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17933 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17934 Expr *Second) {
17935 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17936
17937 if (First->getObjectKind() == OK_ObjCProperty) {
17938 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17939 if (BinaryOperator::isAssignmentOp(Opc))
17940 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17941 Opcode: Opc, LHS: First, RHS: Second);
17942 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17943 if (Result.isInvalid())
17944 return ExprError();
17945 First = Result.get();
17946 }
17947
17948 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17949 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17950 if (Result.isInvalid())
17951 return ExprError();
17952 Second = Result.get();
17953 }
17954
17955 // Determine whether this should be a builtin operation.
17956 if (Op == OO_Subscript) {
17957 if (!First->getType()->isOverloadableType() &&
17958 !Second->getType()->isOverloadableType())
17959 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17960 OpLoc);
17961 } else if (Op == OO_Arrow) {
17962 // It is possible that the type refers to a RecoveryExpr created earlier
17963 // in the tree transformation.
17964 if (First->getType()->isDependentType())
17965 return ExprError();
17966 // -> is never a builtin operation.
17967 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17968 } else if (Second == nullptr || isPostIncDec) {
17969 if (!First->getType()->isOverloadableType() ||
17970 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17971 // The argument is not of overloadable type, or this is an expression
17972 // of the form &Class::member, so try to create a built-in unary
17973 // operation.
17974 UnaryOperatorKind Opc
17975 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17976
17977 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17978 }
17979 } else {
17980 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17981 !First->getType()->isOverloadableType() &&
17982 !Second->getType()->isOverloadableType()) {
17983 // Neither of the arguments is type-dependent or has an overloadable
17984 // type, so try to create a built-in binary operation.
17985 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17986 ExprResult Result
17987 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17988 if (Result.isInvalid())
17989 return ExprError();
17990
17991 return Result;
17992 }
17993 }
17994
17995 // Create the overloaded operator invocation for unary operators.
17996 if (!Second || isPostIncDec) {
17997 UnaryOperatorKind Opc
17998 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17999 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18000 RequiresADL);
18001 }
18002
18003 // Create the overloaded operator invocation for binary operators.
18004 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18005 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18006 LHS: First, RHS: Second, RequiresADL);
18007 if (Result.isInvalid())
18008 return ExprError();
18009
18010 return Result;
18011}
18012
18013template<typename Derived>
18014ExprResult
18015TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18016 SourceLocation OperatorLoc,
18017 bool isArrow,
18018 CXXScopeSpec &SS,
18019 TypeSourceInfo *ScopeType,
18020 SourceLocation CCLoc,
18021 SourceLocation TildeLoc,
18022 PseudoDestructorTypeStorage Destroyed) {
18023 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18024 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18025 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18026 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18027 !cast<PointerType>(Val&: CanonicalBaseType)
18028 ->getPointeeType()
18029 ->getAsCanonical<RecordType>())) {
18030 // This pseudo-destructor expression is still a pseudo-destructor.
18031 return SemaRef.BuildPseudoDestructorExpr(
18032 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18033 CCLoc, TildeLoc, DestroyedType: Destroyed);
18034 }
18035
18036 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18037 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18038 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18039 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18040 NameInfo.setNamedTypeInfo(DestroyedType);
18041
18042 // The scope type is now known to be a valid nested name specifier
18043 // component. Tack it on to the nested name specifier.
18044 if (ScopeType) {
18045 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18046 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18047 diag::err_expected_class_or_namespace)
18048 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18049 return ExprError();
18050 }
18051 SS.clear();
18052 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18053 }
18054
18055 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18056 return getSema().BuildMemberReferenceExpr(
18057 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18058 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18059 /*TemplateArgs*/ nullptr,
18060 /*S*/ nullptr);
18061}
18062
18063template<typename Derived>
18064StmtResult
18065TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18066 SourceLocation Loc = S->getBeginLoc();
18067 CapturedDecl *CD = S->getCapturedDecl();
18068 unsigned NumParams = CD->getNumParams();
18069 unsigned ContextParamPos = CD->getContextParamPosition();
18070 SmallVector<Sema::CapturedParamNameType, 4> Params;
18071 for (unsigned I = 0; I < NumParams; ++I) {
18072 if (I != ContextParamPos) {
18073 Params.push_back(
18074 Elt: std::make_pair(
18075 CD->getParam(i: I)->getName(),
18076 getDerived().TransformType(CD->getParam(i: I)->getType())));
18077 } else {
18078 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18079 }
18080 }
18081 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18082 S->getCapturedRegionKind(), Params);
18083 StmtResult Body;
18084 {
18085 Sema::CompoundScopeRAII CompoundScope(getSema());
18086 Body = getDerived().TransformStmt(S->getCapturedStmt());
18087 }
18088
18089 if (Body.isInvalid()) {
18090 getSema().ActOnCapturedRegionError();
18091 return StmtError();
18092 }
18093
18094 return getSema().ActOnCapturedRegionEnd(Body.get());
18095}
18096
18097template <typename Derived>
18098StmtResult
18099TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18100 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18101 // function definition or instantiation of a function template specialization
18102 // and will therefore never appear in a dependent context.
18103 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18104 "context");
18105}
18106
18107template <typename Derived>
18108ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18109 // We can transform the base expression and allow argument resolution to fill
18110 // in the rest.
18111 return getDerived().TransformExpr(E->getArgLValue());
18112}
18113
18114} // end namespace clang
18115
18116#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18117