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 ExprResult TransformLambdaConstraint(Expr *AC) { return AC; }
841
842 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
843
844 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
845 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
846
847 TemplateParameterList *TransformTemplateParameterList(
848 TemplateParameterList *TPL) {
849 return TPL;
850 }
851
852 ExprResult TransformAddressOfOperand(Expr *E);
853
854 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
855 bool IsAddressOfOperand,
856 TypeSourceInfo **RecoveryTSI);
857
858 ExprResult TransformParenDependentScopeDeclRefExpr(
859 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
860 TypeSourceInfo **RecoveryTSI);
861
862 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
863 bool IsAddressOfOperand);
864
865 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
866
867 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
868
869// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
870// amount of stack usage with clang.
871#define STMT(Node, Parent) \
872 LLVM_ATTRIBUTE_NOINLINE \
873 StmtResult Transform##Node(Node *S);
874#define VALUESTMT(Node, Parent) \
875 LLVM_ATTRIBUTE_NOINLINE \
876 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
877#define EXPR(Node, Parent) \
878 LLVM_ATTRIBUTE_NOINLINE \
879 ExprResult Transform##Node(Node *E);
880#define ABSTRACT_STMT(Stmt)
881#include "clang/AST/StmtNodes.inc"
882
883#define GEN_CLANG_CLAUSE_CLASS
884#define CLAUSE_CLASS(Enum, Str, Class) \
885 LLVM_ATTRIBUTE_NOINLINE \
886 OMPClause *Transform##Class(Class *S);
887#include "llvm/Frontend/OpenMP/OMP.inc"
888
889 /// Build a new qualified type given its unqualified type and type location.
890 ///
891 /// By default, this routine adds type qualifiers only to types that can
892 /// have qualifiers, and silently suppresses those qualifiers that are not
893 /// permitted. Subclasses may override this routine to provide different
894 /// behavior.
895 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
896
897 /// Build a new pointer type given its pointee type.
898 ///
899 /// By default, performs semantic analysis when building the pointer type.
900 /// Subclasses may override this routine to provide different behavior.
901 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
902
903 /// Build a new block pointer type given its pointee type.
904 ///
905 /// By default, performs semantic analysis when building the block pointer
906 /// type. Subclasses may override this routine to provide different behavior.
907 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
908
909 /// Build a new reference type given the type it references.
910 ///
911 /// By default, performs semantic analysis when building the
912 /// reference type. Subclasses may override this routine to provide
913 /// different behavior.
914 ///
915 /// \param LValue whether the type was written with an lvalue sigil
916 /// or an rvalue sigil.
917 QualType RebuildReferenceType(QualType ReferentType,
918 bool LValue,
919 SourceLocation Sigil);
920
921 /// Build a new member pointer type given the pointee type and the
922 /// qualifier it refers into.
923 ///
924 /// By default, performs semantic analysis when building the member pointer
925 /// type. Subclasses may override this routine to provide different behavior.
926 QualType RebuildMemberPointerType(QualType PointeeType,
927 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
928 SourceLocation Sigil);
929
930 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
931 SourceLocation ProtocolLAngleLoc,
932 ArrayRef<ObjCProtocolDecl *> Protocols,
933 ArrayRef<SourceLocation> ProtocolLocs,
934 SourceLocation ProtocolRAngleLoc);
935
936 /// Build an Objective-C object type.
937 ///
938 /// By default, performs semantic analysis when building the object type.
939 /// Subclasses may override this routine to provide different behavior.
940 QualType RebuildObjCObjectType(QualType BaseType,
941 SourceLocation Loc,
942 SourceLocation TypeArgsLAngleLoc,
943 ArrayRef<TypeSourceInfo *> TypeArgs,
944 SourceLocation TypeArgsRAngleLoc,
945 SourceLocation ProtocolLAngleLoc,
946 ArrayRef<ObjCProtocolDecl *> Protocols,
947 ArrayRef<SourceLocation> ProtocolLocs,
948 SourceLocation ProtocolRAngleLoc);
949
950 /// Build a new Objective-C object pointer type given the pointee type.
951 ///
952 /// By default, directly builds the pointer type, with no additional semantic
953 /// analysis.
954 QualType RebuildObjCObjectPointerType(QualType PointeeType,
955 SourceLocation Star);
956
957 /// Build a new array type given the element type, size
958 /// modifier, size of the array (if known), size expression, and index type
959 /// qualifiers.
960 ///
961 /// By default, performs semantic analysis when building the array type.
962 /// Subclasses may override this routine to provide different behavior.
963 /// Also by default, all of the other Rebuild*Array
964 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
965 const llvm::APInt *Size, Expr *SizeExpr,
966 unsigned IndexTypeQuals, SourceRange BracketsRange);
967
968 /// Build a new constant array type given the element type, size
969 /// modifier, (known) size of the array, and index type qualifiers.
970 ///
971 /// By default, performs semantic analysis when building the array type.
972 /// Subclasses may override this routine to provide different behavior.
973 QualType RebuildConstantArrayType(QualType ElementType,
974 ArraySizeModifier SizeMod,
975 const llvm::APInt &Size, Expr *SizeExpr,
976 unsigned IndexTypeQuals,
977 SourceRange BracketsRange);
978
979 /// Build a new incomplete array type given the element type, size
980 /// modifier, and index type qualifiers.
981 ///
982 /// By default, performs semantic analysis when building the array type.
983 /// Subclasses may override this routine to provide different behavior.
984 QualType RebuildIncompleteArrayType(QualType ElementType,
985 ArraySizeModifier SizeMod,
986 unsigned IndexTypeQuals,
987 SourceRange BracketsRange);
988
989 /// Build a new variable-length array type given the element type,
990 /// size modifier, size expression, and index type qualifiers.
991 ///
992 /// By default, performs semantic analysis when building the array type.
993 /// Subclasses may override this routine to provide different behavior.
994 QualType RebuildVariableArrayType(QualType ElementType,
995 ArraySizeModifier SizeMod, Expr *SizeExpr,
996 unsigned IndexTypeQuals,
997 SourceRange BracketsRange);
998
999 /// Build a new dependent-sized array type given the element type,
1000 /// size modifier, size expression, and index type qualifiers.
1001 ///
1002 /// By default, performs semantic analysis when building the array type.
1003 /// Subclasses may override this routine to provide different behavior.
1004 QualType RebuildDependentSizedArrayType(QualType ElementType,
1005 ArraySizeModifier SizeMod,
1006 Expr *SizeExpr,
1007 unsigned IndexTypeQuals,
1008 SourceRange BracketsRange);
1009
1010 /// Build a new vector type given the element type and
1011 /// number of elements.
1012 ///
1013 /// By default, performs semantic analysis when building the vector type.
1014 /// Subclasses may override this routine to provide different behavior.
1015 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
1016 VectorKind VecKind);
1017
1018 /// Build a new potentially dependently-sized extended vector type
1019 /// given the element type and number of elements.
1020 ///
1021 /// By default, performs semantic analysis when building the vector type.
1022 /// Subclasses may override this routine to provide different behavior.
1023 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
1024 SourceLocation AttributeLoc, VectorKind);
1025
1026 /// Build a new extended vector type given the element type and
1027 /// number of elements.
1028 ///
1029 /// By default, performs semantic analysis when building the vector type.
1030 /// Subclasses may override this routine to provide different behavior.
1031 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
1032 SourceLocation AttributeLoc);
1033
1034 /// Build a new potentially dependently-sized extended vector type
1035 /// given the element type and number of elements.
1036 ///
1037 /// By default, performs semantic analysis when building the vector type.
1038 /// Subclasses may override this routine to provide different behavior.
1039 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
1040 Expr *SizeExpr,
1041 SourceLocation AttributeLoc);
1042
1043 /// Build a new matrix type given the element type and dimensions.
1044 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
1045 unsigned NumColumns);
1046
1047 /// Build a new matrix type given the type and dependently-defined
1048 /// dimensions.
1049 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
1050 Expr *ColumnExpr,
1051 SourceLocation AttributeLoc);
1052
1053 /// Build a new DependentAddressSpaceType or return the pointee
1054 /// type variable with the correct address space (retrieved from
1055 /// AddrSpaceExpr) applied to it. The former will be returned in cases
1056 /// where the address space remains dependent.
1057 ///
1058 /// By default, performs semantic analysis when building the type with address
1059 /// space applied. Subclasses may override this routine to provide different
1060 /// behavior.
1061 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1062 Expr *AddrSpaceExpr,
1063 SourceLocation AttributeLoc);
1064
1065 /// Build a new function type.
1066 ///
1067 /// By default, performs semantic analysis when building the function type.
1068 /// Subclasses may override this routine to provide different behavior.
1069 QualType RebuildFunctionProtoType(QualType T,
1070 MutableArrayRef<QualType> ParamTypes,
1071 const FunctionProtoType::ExtProtoInfo &EPI);
1072
1073 /// Build a new unprototyped function type.
1074 QualType RebuildFunctionNoProtoType(QualType ResultType);
1075
1076 /// Rebuild an unresolved typename type, given the decl that
1077 /// the UnresolvedUsingTypenameDecl was transformed to.
1078 QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
1079 NestedNameSpecifier Qualifier,
1080 SourceLocation NameLoc, Decl *D);
1081
1082 /// Build a new type found via an alias.
1083 QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
1084 NestedNameSpecifier Qualifier, UsingShadowDecl *D,
1085 QualType UnderlyingType) {
1086 return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
1087 }
1088
1089 /// Build a new typedef type.
1090 QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
1091 NestedNameSpecifier Qualifier,
1092 TypedefNameDecl *Typedef) {
1093 return SemaRef.Context.getTypedefType(Keyword, Qualifier, Decl: Typedef);
1094 }
1095
1096 /// Build a new MacroDefined type.
1097 QualType RebuildMacroQualifiedType(QualType T,
1098 const IdentifierInfo *MacroII) {
1099 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1100 }
1101
1102 /// Build a new class/struct/union/enum type.
1103 QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
1104 NestedNameSpecifier Qualifier, TagDecl *Tag) {
1105 return SemaRef.Context.getTagType(Keyword, Qualifier, TD: Tag,
1106 /*OwnsTag=*/OwnsTag: false);
1107 }
1108 QualType RebuildCanonicalTagType(TagDecl *Tag) {
1109 return SemaRef.Context.getCanonicalTagType(TD: Tag);
1110 }
1111
1112 /// Build a new typeof(expr) type.
1113 ///
1114 /// By default, performs semantic analysis when building the typeof type.
1115 /// Subclasses may override this routine to provide different behavior.
1116 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1117 TypeOfKind Kind);
1118
1119 /// Build a new typeof(type) type.
1120 ///
1121 /// By default, builds a new TypeOfType with the given underlying type.
1122 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1123
1124 /// Build a new unary transform type.
1125 QualType RebuildUnaryTransformType(QualType BaseType,
1126 UnaryTransformType::UTTKind UKind,
1127 SourceLocation Loc);
1128
1129 /// Build a new C++11 decltype type.
1130 ///
1131 /// By default, performs semantic analysis when building the decltype type.
1132 /// Subclasses may override this routine to provide different behavior.
1133 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1134
1135 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1136 SourceLocation Loc,
1137 SourceLocation EllipsisLoc,
1138 bool FullySubstituted,
1139 ArrayRef<QualType> Expansions = {});
1140
1141 /// Build a new C++11 auto type.
1142 ///
1143 /// By default, builds a new AutoType with the given deduced type.
1144 QualType RebuildAutoType(DeducedKind DK, QualType DeducedAsType,
1145 AutoTypeKeyword Keyword,
1146 ConceptDecl *TypeConstraintConcept,
1147 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1148 return SemaRef.Context.getAutoType(
1149 DK, DeducedAsType, Keyword, TypeConstraintConcept, TypeConstraintArgs);
1150 }
1151
1152 /// By default, builds a new DeducedTemplateSpecializationType with the given
1153 /// deduced type.
1154 QualType RebuildDeducedTemplateSpecializationType(
1155 DeducedKind DK, QualType DeducedAsType, ElaboratedTypeKeyword Keyword,
1156 TemplateName Template) {
1157 return SemaRef.Context.getDeducedTemplateSpecializationType(
1158 DK, DeducedAsType, Keyword, Template);
1159 }
1160
1161 /// Build a new template specialization type.
1162 ///
1163 /// By default, performs semantic analysis when building the template
1164 /// specialization type. Subclasses may override this routine to provide
1165 /// different behavior.
1166 QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
1167 TemplateName Template,
1168 SourceLocation TemplateLoc,
1169 TemplateArgumentListInfo &Args);
1170
1171 /// Build a new parenthesized type.
1172 ///
1173 /// By default, builds a new ParenType type from the inner type.
1174 /// Subclasses may override this routine to provide different behavior.
1175 QualType RebuildParenType(QualType InnerType) {
1176 return SemaRef.BuildParenType(T: InnerType);
1177 }
1178
1179 /// Build a new typename type that refers to an identifier.
1180 ///
1181 /// By default, performs semantic analysis when building the typename type
1182 /// (or elaborated type). Subclasses may override this routine to provide
1183 /// different behavior.
1184 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1185 SourceLocation KeywordLoc,
1186 NestedNameSpecifierLoc QualifierLoc,
1187 const IdentifierInfo *Id,
1188 SourceLocation IdLoc,
1189 bool DeducedTSTContext) {
1190 CXXScopeSpec SS;
1191 SS.Adopt(Other: QualifierLoc);
1192
1193 if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
1194 // If the name is still dependent, just build a new dependent name type.
1195 if (!SemaRef.computeDeclContext(SS))
1196 return SemaRef.Context.getDependentNameType(Keyword,
1197 NNS: QualifierLoc.getNestedNameSpecifier(),
1198 Name: Id);
1199 }
1200
1201 if (Keyword == ElaboratedTypeKeyword::None ||
1202 Keyword == ElaboratedTypeKeyword::Typename) {
1203 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1204 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1205 }
1206
1207 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1208
1209 // We had a dependent elaborated-type-specifier that has been transformed
1210 // into a non-dependent elaborated-type-specifier. Find the tag we're
1211 // referring to.
1212 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1213 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1214 if (!DC)
1215 return QualType();
1216
1217 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1218 return QualType();
1219
1220 TagDecl *Tag = nullptr;
1221 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1222 switch (Result.getResultKind()) {
1223 case LookupResultKind::NotFound:
1224 case LookupResultKind::NotFoundInCurrentInstantiation:
1225 break;
1226
1227 case LookupResultKind::Found:
1228 Tag = Result.getAsSingle<TagDecl>();
1229 break;
1230
1231 case LookupResultKind::FoundOverloaded:
1232 case LookupResultKind::FoundUnresolvedValue:
1233 llvm_unreachable("Tag lookup cannot find non-tags");
1234
1235 case LookupResultKind::Ambiguous:
1236 // Let the LookupResult structure handle ambiguities.
1237 return QualType();
1238 }
1239
1240 if (!Tag) {
1241 // Check where the name exists but isn't a tag type and use that to emit
1242 // better diagnostics.
1243 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1244 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1245 switch (Result.getResultKind()) {
1246 case LookupResultKind::Found:
1247 case LookupResultKind::FoundOverloaded:
1248 case LookupResultKind::FoundUnresolvedValue: {
1249 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1250 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1251 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1252 << SomeDecl << NTK << Kind;
1253 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1254 break;
1255 }
1256 default:
1257 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1258 << Kind << Id << DC << QualifierLoc.getSourceRange();
1259 break;
1260 }
1261 return QualType();
1262 }
1263 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1264 NewTagLoc: IdLoc, Name: Id)) {
1265 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1266 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1267 return QualType();
1268 }
1269 return getDerived().RebuildTagType(
1270 Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
1271 }
1272
1273 /// Build a new pack expansion type.
1274 ///
1275 /// By default, builds a new PackExpansionType type from the given pattern.
1276 /// Subclasses may override this routine to provide different behavior.
1277 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1278 SourceLocation EllipsisLoc,
1279 UnsignedOrNone NumExpansions) {
1280 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1281 NumExpansions);
1282 }
1283
1284 /// Build a new atomic type given its value type.
1285 ///
1286 /// By default, performs semantic analysis when building the atomic type.
1287 /// Subclasses may override this routine to provide different behavior.
1288 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1289
1290 /// Build a new pipe type given its value type.
1291 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1292 bool isReadPipe);
1293
1294 /// Build a bit-precise int given its value type.
1295 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1296 SourceLocation Loc);
1297
1298 /// Build a dependent bit-precise int given its value type.
1299 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1300 SourceLocation Loc);
1301
1302 /// Build a new template name given a nested name specifier, a flag
1303 /// indicating whether the "template" keyword was provided, and the template
1304 /// that the template name refers to.
1305 ///
1306 /// By default, builds the new template name directly. Subclasses may override
1307 /// this routine to provide different behavior.
1308 TemplateName RebuildTemplateName(CXXScopeSpec &SS, bool TemplateKW,
1309 TemplateName Name);
1310
1311 /// Build a new template name given a nested name specifier and the
1312 /// name that is referred to as a template.
1313 ///
1314 /// By default, performs semantic analysis to determine whether the name can
1315 /// be resolved to a specific template, then builds the appropriate kind of
1316 /// template name. Subclasses may override this routine to provide different
1317 /// behavior.
1318 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1319 SourceLocation TemplateKWLoc,
1320 const IdentifierInfo &Name,
1321 SourceLocation NameLoc, QualType ObjectType,
1322 bool AllowInjectedClassName);
1323
1324 /// Build a new template name given a nested name specifier and the
1325 /// overloaded operator name that is referred to as a template.
1326 ///
1327 /// By default, performs semantic analysis to determine whether the name can
1328 /// be resolved to a specific template, then builds the appropriate kind of
1329 /// template name. Subclasses may override this routine to provide different
1330 /// behavior.
1331 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1332 SourceLocation TemplateKWLoc,
1333 OverloadedOperatorKind Operator,
1334 SourceLocation NameLoc, QualType ObjectType,
1335 bool AllowInjectedClassName);
1336
1337 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1338 SourceLocation TemplateKWLoc,
1339 IdentifierOrOverloadedOperator IO,
1340 SourceLocation NameLoc, QualType ObjectType,
1341 bool AllowInjectedClassName);
1342
1343 /// Build a new template name given a template template parameter pack
1344 /// and the
1345 ///
1346 /// By default, performs semantic analysis to determine whether the name can
1347 /// be resolved to a specific template, then builds the appropriate kind of
1348 /// template name. Subclasses may override this routine to provide different
1349 /// behavior.
1350 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1351 Decl *AssociatedDecl, unsigned Index,
1352 bool Final) {
1353 return getSema().Context.getSubstTemplateTemplateParmPack(
1354 ArgPack, AssociatedDecl, Index, Final);
1355 }
1356
1357 /// Build a new compound statement.
1358 ///
1359 /// By default, performs semantic analysis to build the new statement.
1360 /// Subclasses may override this routine to provide different behavior.
1361 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1362 MultiStmtArg Statements,
1363 SourceLocation RBraceLoc,
1364 bool IsStmtExpr) {
1365 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1366 IsStmtExpr);
1367 }
1368
1369 /// Build a new case statement.
1370 ///
1371 /// By default, performs semantic analysis to build the new statement.
1372 /// Subclasses may override this routine to provide different behavior.
1373 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1374 Expr *LHS,
1375 SourceLocation EllipsisLoc,
1376 Expr *RHS,
1377 SourceLocation ColonLoc) {
1378 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1379 ColonLoc);
1380 }
1381
1382 /// Attach the body to a new case statement.
1383 ///
1384 /// By default, performs semantic analysis to build the new statement.
1385 /// Subclasses may override this routine to provide different behavior.
1386 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1387 getSema().ActOnCaseStmtBody(S, Body);
1388 return S;
1389 }
1390
1391 /// Build a new default statement.
1392 ///
1393 /// By default, performs semantic analysis to build the new statement.
1394 /// Subclasses may override this routine to provide different behavior.
1395 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1396 SourceLocation ColonLoc,
1397 Stmt *SubStmt) {
1398 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1399 /*CurScope=*/nullptr);
1400 }
1401
1402 /// Build a new label statement.
1403 ///
1404 /// By default, performs semantic analysis to build the new statement.
1405 /// Subclasses may override this routine to provide different behavior.
1406 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1407 SourceLocation ColonLoc, Stmt *SubStmt) {
1408 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1409 }
1410
1411 /// Build a new attributed statement.
1412 ///
1413 /// By default, performs semantic analysis to build the new statement.
1414 /// Subclasses may override this routine to provide different behavior.
1415 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1416 ArrayRef<const Attr *> Attrs,
1417 Stmt *SubStmt) {
1418 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1419 return StmtError();
1420 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1421 }
1422
1423 /// Build a new "if" statement.
1424 ///
1425 /// By default, performs semantic analysis to build the new statement.
1426 /// Subclasses may override this routine to provide different behavior.
1427 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1428 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1429 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1430 SourceLocation ElseLoc, Stmt *Else) {
1431 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1432 Then, ElseLoc, Else);
1433 }
1434
1435 /// Start building a new switch statement.
1436 ///
1437 /// By default, performs semantic analysis to build the new statement.
1438 /// Subclasses may override this routine to provide different behavior.
1439 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1440 SourceLocation LParenLoc, Stmt *Init,
1441 Sema::ConditionResult Cond,
1442 SourceLocation RParenLoc) {
1443 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1444 RParenLoc);
1445 }
1446
1447 /// Attach the body to the switch statement.
1448 ///
1449 /// By default, performs semantic analysis to build the new statement.
1450 /// Subclasses may override this routine to provide different behavior.
1451 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1452 Stmt *Switch, Stmt *Body) {
1453 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1454 }
1455
1456 /// Build a new while statement.
1457 ///
1458 /// By default, performs semantic analysis to build the new statement.
1459 /// Subclasses may override this routine to provide different behavior.
1460 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1461 Sema::ConditionResult Cond,
1462 SourceLocation RParenLoc, Stmt *Body) {
1463 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1464 }
1465
1466 /// Build a new do-while statement.
1467 ///
1468 /// By default, performs semantic analysis to build the new statement.
1469 /// Subclasses may override this routine to provide different behavior.
1470 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1471 SourceLocation WhileLoc, SourceLocation LParenLoc,
1472 Expr *Cond, SourceLocation RParenLoc) {
1473 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1474 Cond, RParenLoc);
1475 }
1476
1477 /// Build a new for statement.
1478 ///
1479 /// By default, performs semantic analysis to build the new statement.
1480 /// Subclasses may override this routine to provide different behavior.
1481 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1482 Stmt *Init, Sema::ConditionResult Cond,
1483 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1484 Stmt *Body) {
1485 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1486 Inc, RParenLoc, Body);
1487 }
1488
1489 /// Build a new goto statement.
1490 ///
1491 /// By default, performs semantic analysis to build the new statement.
1492 /// Subclasses may override this routine to provide different behavior.
1493 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1494 LabelDecl *Label) {
1495 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1496 }
1497
1498 /// Build a new indirect goto statement.
1499 ///
1500 /// By default, performs semantic analysis to build the new statement.
1501 /// Subclasses may override this routine to provide different behavior.
1502 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1503 SourceLocation StarLoc,
1504 Expr *Target) {
1505 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1506 }
1507
1508 /// Build a new return statement.
1509 ///
1510 /// By default, performs semantic analysis to build the new statement.
1511 /// Subclasses may override this routine to provide different behavior.
1512 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1513 return getSema().BuildReturnStmt(ReturnLoc, Result);
1514 }
1515
1516 /// Build a new declaration statement.
1517 ///
1518 /// By default, performs semantic analysis to build the new statement.
1519 /// Subclasses may override this routine to provide different behavior.
1520 StmtResult RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1521 SourceLocation StartLoc, SourceLocation EndLoc) {
1522 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1523 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1524 }
1525
1526 /// Build a new inline asm statement.
1527 ///
1528 /// By default, performs semantic analysis to build the new statement.
1529 /// Subclasses may override this routine to provide different behavior.
1530 StmtResult RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1531 bool IsVolatile, unsigned NumOutputs,
1532 unsigned NumInputs, IdentifierInfo **Names,
1533 MultiExprArg Constraints, MultiExprArg Exprs,
1534 Expr *AsmString, MultiExprArg Clobbers,
1535 unsigned NumLabels,
1536 SourceLocation RParenLoc) {
1537 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1538 NumInputs, Names, Constraints, Exprs,
1539 AsmString, Clobbers, NumLabels, RParenLoc);
1540 }
1541
1542 /// Build a new MS style inline asm statement.
1543 ///
1544 /// By default, performs semantic analysis to build the new statement.
1545 /// Subclasses may override this routine to provide different behavior.
1546 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1547 ArrayRef<Token> AsmToks,
1548 StringRef AsmString,
1549 unsigned NumOutputs, unsigned NumInputs,
1550 ArrayRef<StringRef> Constraints,
1551 ArrayRef<StringRef> Clobbers,
1552 ArrayRef<Expr*> Exprs,
1553 SourceLocation EndLoc) {
1554 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1555 NumOutputs, NumInputs,
1556 Constraints, Clobbers, Exprs, EndLoc);
1557 }
1558
1559 /// Build a new co_return statement.
1560 ///
1561 /// By default, performs semantic analysis to build the new statement.
1562 /// Subclasses may override this routine to provide different behavior.
1563 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1564 bool IsImplicit) {
1565 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1566 }
1567
1568 /// Build a new co_await expression.
1569 ///
1570 /// By default, performs semantic analysis to build the new expression.
1571 /// Subclasses may override this routine to provide different behavior.
1572 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1573 UnresolvedLookupExpr *OpCoawaitLookup,
1574 bool IsImplicit) {
1575 // This function rebuilds a coawait-expr given its operator.
1576 // For an explicit coawait-expr, the rebuild involves the full set
1577 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1578 // including calling await_transform().
1579 // For an implicit coawait-expr, we need to rebuild the "operator
1580 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1581 // This mirrors how the implicit CoawaitExpr is originally created
1582 // in Sema::ActOnCoroutineBodyStart().
1583 if (IsImplicit) {
1584 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1585 CoawaitLoc, Operand, OpCoawaitLookup);
1586 if (Suspend.isInvalid())
1587 return ExprError();
1588 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1589 Suspend.get(), true);
1590 }
1591
1592 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1593 OpCoawaitLookup);
1594 }
1595
1596 /// Build a new co_await expression.
1597 ///
1598 /// By default, performs semantic analysis to build the new expression.
1599 /// Subclasses may override this routine to provide different behavior.
1600 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1601 Expr *Result,
1602 UnresolvedLookupExpr *Lookup) {
1603 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1604 }
1605
1606 /// Build a new co_yield expression.
1607 ///
1608 /// By default, performs semantic analysis to build the new expression.
1609 /// Subclasses may override this routine to provide different behavior.
1610 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1611 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1612 }
1613
1614 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1615 return getSema().BuildCoroutineBodyStmt(Args);
1616 }
1617
1618 /// Build a new Objective-C \@try statement.
1619 ///
1620 /// By default, performs semantic analysis to build the new statement.
1621 /// Subclasses may override this routine to provide different behavior.
1622 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1623 Stmt *TryBody,
1624 MultiStmtArg CatchStmts,
1625 Stmt *Finally) {
1626 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1627 Finally);
1628 }
1629
1630 /// Rebuild an Objective-C exception declaration.
1631 ///
1632 /// By default, performs semantic analysis to build the new declaration.
1633 /// Subclasses may override this routine to provide different behavior.
1634 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1635 TypeSourceInfo *TInfo, QualType T) {
1636 return getSema().ObjC().BuildObjCExceptionDecl(
1637 TInfo, T, ExceptionDecl->getInnerLocStart(),
1638 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1639 }
1640
1641 /// Build a new Objective-C \@catch statement.
1642 ///
1643 /// By default, performs semantic analysis to build the new statement.
1644 /// Subclasses may override this routine to provide different behavior.
1645 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1646 SourceLocation RParenLoc,
1647 VarDecl *Var,
1648 Stmt *Body) {
1649 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1650 }
1651
1652 /// Build a new Objective-C \@finally statement.
1653 ///
1654 /// By default, performs semantic analysis to build the new statement.
1655 /// Subclasses may override this routine to provide different behavior.
1656 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1657 Stmt *Body) {
1658 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1659 }
1660
1661 /// Build a new Objective-C \@throw statement.
1662 ///
1663 /// By default, performs semantic analysis to build the new statement.
1664 /// Subclasses may override this routine to provide different behavior.
1665 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1666 Expr *Operand) {
1667 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1668 }
1669
1670 /// Build a new OpenMP Canonical loop.
1671 ///
1672 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1673 /// OMPCanonicalLoop.
1674 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1675 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1676 }
1677
1678 /// Build a new OpenMP executable directive.
1679 ///
1680 /// By default, performs semantic analysis to build the new statement.
1681 /// Subclasses may override this routine to provide different behavior.
1682 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1683 DeclarationNameInfo DirName,
1684 OpenMPDirectiveKind CancelRegion,
1685 ArrayRef<OMPClause *> Clauses,
1686 Stmt *AStmt, SourceLocation StartLoc,
1687 SourceLocation EndLoc) {
1688
1689 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1690 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1691 }
1692
1693 /// Build a new OpenMP informational directive.
1694 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1695 DeclarationNameInfo DirName,
1696 ArrayRef<OMPClause *> Clauses,
1697 Stmt *AStmt,
1698 SourceLocation StartLoc,
1699 SourceLocation EndLoc) {
1700
1701 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1702 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1703 }
1704
1705 /// Build a new OpenMP 'if' clause.
1706 ///
1707 /// By default, performs semantic analysis to build the new OpenMP clause.
1708 /// Subclasses may override this routine to provide different behavior.
1709 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1710 Expr *Condition, SourceLocation StartLoc,
1711 SourceLocation LParenLoc,
1712 SourceLocation NameModifierLoc,
1713 SourceLocation ColonLoc,
1714 SourceLocation EndLoc) {
1715 return getSema().OpenMP().ActOnOpenMPIfClause(
1716 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1717 EndLoc);
1718 }
1719
1720 /// Build a new OpenMP 'final' clause.
1721 ///
1722 /// By default, performs semantic analysis to build the new OpenMP clause.
1723 /// Subclasses may override this routine to provide different behavior.
1724 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1725 SourceLocation LParenLoc,
1726 SourceLocation EndLoc) {
1727 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1728 LParenLoc, EndLoc);
1729 }
1730
1731 /// Build a new OpenMP 'num_threads' clause.
1732 ///
1733 /// By default, performs semantic analysis to build the new OpenMP clause.
1734 /// Subclasses may override this routine to provide different behavior.
1735 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1736 Expr *NumThreads,
1737 SourceLocation StartLoc,
1738 SourceLocation LParenLoc,
1739 SourceLocation ModifierLoc,
1740 SourceLocation EndLoc) {
1741 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1742 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1743 }
1744
1745 /// Build a new OpenMP 'safelen' clause.
1746 ///
1747 /// By default, performs semantic analysis to build the new OpenMP clause.
1748 /// Subclasses may override this routine to provide different behavior.
1749 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1750 SourceLocation LParenLoc,
1751 SourceLocation EndLoc) {
1752 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1753 EndLoc);
1754 }
1755
1756 /// Build a new OpenMP 'simdlen' clause.
1757 ///
1758 /// By default, performs semantic analysis to build the new OpenMP clause.
1759 /// Subclasses may override this routine to provide different behavior.
1760 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1761 SourceLocation LParenLoc,
1762 SourceLocation EndLoc) {
1763 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1764 EndLoc);
1765 }
1766
1767 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1768 SourceLocation StartLoc,
1769 SourceLocation LParenLoc,
1770 SourceLocation EndLoc) {
1771 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1772 EndLoc);
1773 }
1774
1775 OMPClause *RebuildOMPCountsClause(ArrayRef<Expr *> Counts,
1776 SourceLocation StartLoc,
1777 SourceLocation LParenLoc,
1778 SourceLocation EndLoc,
1779 std::optional<unsigned> FillIdx,
1780 SourceLocation FillLoc) {
1781 unsigned FillCount = FillIdx ? 1 : 0;
1782 return getSema().OpenMP().ActOnOpenMPCountsClause(
1783 Counts, StartLoc, LParenLoc, EndLoc, FillIdx, FillLoc, FillCount);
1784 }
1785
1786 /// Build a new OpenMP 'permutation' clause.
1787 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1788 SourceLocation StartLoc,
1789 SourceLocation LParenLoc,
1790 SourceLocation EndLoc) {
1791 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1792 LParenLoc, EndLoc);
1793 }
1794
1795 /// Build a new OpenMP 'full' clause.
1796 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1797 SourceLocation EndLoc) {
1798 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1799 }
1800
1801 /// Build a new OpenMP 'partial' clause.
1802 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1803 SourceLocation LParenLoc,
1804 SourceLocation EndLoc) {
1805 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1806 LParenLoc, EndLoc);
1807 }
1808
1809 OMPClause *
1810 RebuildOMPLoopRangeClause(Expr *First, Expr *Count, SourceLocation StartLoc,
1811 SourceLocation LParenLoc, SourceLocation FirstLoc,
1812 SourceLocation CountLoc, SourceLocation EndLoc) {
1813 return getSema().OpenMP().ActOnOpenMPLoopRangeClause(
1814 First, Count, StartLoc, LParenLoc, FirstLoc, CountLoc, EndLoc);
1815 }
1816
1817 /// Build a new OpenMP 'allocator' clause.
1818 ///
1819 /// By default, performs semantic analysis to build the new OpenMP clause.
1820 /// Subclasses may override this routine to provide different behavior.
1821 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1822 SourceLocation LParenLoc,
1823 SourceLocation EndLoc) {
1824 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1825 EndLoc);
1826 }
1827
1828 /// Build a new OpenMP 'collapse' clause.
1829 ///
1830 /// By default, performs semantic analysis to build the new OpenMP clause.
1831 /// Subclasses may override this routine to provide different behavior.
1832 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1833 SourceLocation LParenLoc,
1834 SourceLocation EndLoc) {
1835 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1836 LParenLoc, EndLoc);
1837 }
1838
1839 /// Build a new OpenMP 'default' clause.
1840 ///
1841 /// By default, performs semantic analysis to build the new OpenMP clause.
1842 /// Subclasses may override this routine to provide different behavior.
1843 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1844 OpenMPDefaultClauseVariableCategory VCKind,
1845 SourceLocation VCLoc,
1846 SourceLocation StartLoc,
1847 SourceLocation LParenLoc,
1848 SourceLocation EndLoc) {
1849 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1850 Kind, KindKwLoc, VCKind, VCLoc, StartLoc, LParenLoc, EndLoc);
1851 }
1852
1853 /// Build a new OpenMP 'proc_bind' clause.
1854 ///
1855 /// By default, performs semantic analysis to build the new OpenMP clause.
1856 /// Subclasses may override this routine to provide different behavior.
1857 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1858 SourceLocation KindKwLoc,
1859 SourceLocation StartLoc,
1860 SourceLocation LParenLoc,
1861 SourceLocation EndLoc) {
1862 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1863 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1864 }
1865 OMPClause *RebuildOMPTransparentClause(Expr *ImpexTypeArg,
1866 SourceLocation StartLoc,
1867 SourceLocation LParenLoc,
1868 SourceLocation EndLoc) {
1869 return getSema().OpenMP().ActOnOpenMPTransparentClause(
1870 ImpexTypeArg, StartLoc, LParenLoc, EndLoc);
1871 }
1872
1873 /// Build a new OpenMP 'schedule' clause.
1874 ///
1875 /// By default, performs semantic analysis to build the new OpenMP clause.
1876 /// Subclasses may override this routine to provide different behavior.
1877 OMPClause *RebuildOMPScheduleClause(
1878 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1879 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1880 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1881 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1882 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1883 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1884 CommaLoc, EndLoc);
1885 }
1886
1887 /// Build a new OpenMP 'ordered' clause.
1888 ///
1889 /// By default, performs semantic analysis to build the new OpenMP clause.
1890 /// Subclasses may override this routine to provide different behavior.
1891 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1892 SourceLocation EndLoc,
1893 SourceLocation LParenLoc, Expr *Num) {
1894 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1895 LParenLoc, Num);
1896 }
1897
1898 /// Build a new OpenMP 'nowait' clause.
1899 ///
1900 /// By default, performs semantic analysis to build the new OpenMP clause.
1901 /// Subclasses may override this routine to provide different behavior.
1902 OMPClause *RebuildOMPNowaitClause(Expr *Condition, SourceLocation StartLoc,
1903 SourceLocation LParenLoc,
1904 SourceLocation EndLoc) {
1905 return getSema().OpenMP().ActOnOpenMPNowaitClause(StartLoc, EndLoc,
1906 LParenLoc, Condition);
1907 }
1908
1909 /// Build a new OpenMP 'private' clause.
1910 ///
1911 /// By default, performs semantic analysis to build the new OpenMP clause.
1912 /// Subclasses may override this routine to provide different behavior.
1913 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1914 SourceLocation StartLoc,
1915 SourceLocation LParenLoc,
1916 SourceLocation EndLoc) {
1917 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1918 LParenLoc, EndLoc);
1919 }
1920
1921 /// Build a new OpenMP 'firstprivate' clause.
1922 ///
1923 /// By default, performs semantic analysis to build the new OpenMP clause.
1924 /// Subclasses may override this routine to provide different behavior.
1925 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1926 SourceLocation StartLoc,
1927 SourceLocation LParenLoc,
1928 SourceLocation EndLoc) {
1929 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1930 LParenLoc, EndLoc);
1931 }
1932
1933 /// Build a new OpenMP 'lastprivate' clause.
1934 ///
1935 /// By default, performs semantic analysis to build the new OpenMP clause.
1936 /// Subclasses may override this routine to provide different behavior.
1937 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1938 OpenMPLastprivateModifier LPKind,
1939 SourceLocation LPKindLoc,
1940 SourceLocation ColonLoc,
1941 SourceLocation StartLoc,
1942 SourceLocation LParenLoc,
1943 SourceLocation EndLoc) {
1944 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1945 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1946 }
1947
1948 /// Build a new OpenMP 'shared' clause.
1949 ///
1950 /// By default, performs semantic analysis to build the new OpenMP clause.
1951 /// Subclasses may override this routine to provide different behavior.
1952 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1953 SourceLocation StartLoc,
1954 SourceLocation LParenLoc,
1955 SourceLocation EndLoc) {
1956 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1957 LParenLoc, EndLoc);
1958 }
1959
1960 /// Build a new OpenMP 'reduction' clause.
1961 ///
1962 /// By default, performs semantic analysis to build the new statement.
1963 /// Subclasses may override this routine to provide different behavior.
1964 OMPClause *RebuildOMPReductionClause(
1965 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1966 OpenMPOriginalSharingModifier OriginalSharingModifier,
1967 SourceLocation StartLoc, SourceLocation LParenLoc,
1968 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1969 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1970 const DeclarationNameInfo &ReductionId,
1971 ArrayRef<Expr *> UnresolvedReductions) {
1972 return getSema().OpenMP().ActOnOpenMPReductionClause(
1973 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1974 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1975 UnresolvedReductions);
1976 }
1977
1978 /// Build a new OpenMP 'task_reduction' clause.
1979 ///
1980 /// By default, performs semantic analysis to build the new statement.
1981 /// Subclasses may override this routine to provide different behavior.
1982 OMPClause *RebuildOMPTaskReductionClause(
1983 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1984 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1985 CXXScopeSpec &ReductionIdScopeSpec,
1986 const DeclarationNameInfo &ReductionId,
1987 ArrayRef<Expr *> UnresolvedReductions) {
1988 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1989 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1990 ReductionId, UnresolvedReductions);
1991 }
1992
1993 /// Build a new OpenMP 'in_reduction' clause.
1994 ///
1995 /// By default, performs semantic analysis to build the new statement.
1996 /// Subclasses may override this routine to provide different behavior.
1997 OMPClause *
1998 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1999 SourceLocation LParenLoc, SourceLocation ColonLoc,
2000 SourceLocation EndLoc,
2001 CXXScopeSpec &ReductionIdScopeSpec,
2002 const DeclarationNameInfo &ReductionId,
2003 ArrayRef<Expr *> UnresolvedReductions) {
2004 return getSema().OpenMP().ActOnOpenMPInReductionClause(
2005 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
2006 ReductionId, UnresolvedReductions);
2007 }
2008
2009 /// Build a new OpenMP 'linear' clause.
2010 ///
2011 /// By default, performs semantic analysis to build the new OpenMP clause.
2012 /// Subclasses may override this routine to provide different behavior.
2013 OMPClause *RebuildOMPLinearClause(
2014 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
2015 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
2016 SourceLocation ModifierLoc, SourceLocation ColonLoc,
2017 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
2018 return getSema().OpenMP().ActOnOpenMPLinearClause(
2019 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
2020 StepModifierLoc, EndLoc);
2021 }
2022
2023 /// Build a new OpenMP 'aligned' clause.
2024 ///
2025 /// By default, performs semantic analysis to build the new OpenMP clause.
2026 /// Subclasses may override this routine to provide different behavior.
2027 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
2028 SourceLocation StartLoc,
2029 SourceLocation LParenLoc,
2030 SourceLocation ColonLoc,
2031 SourceLocation EndLoc) {
2032 return getSema().OpenMP().ActOnOpenMPAlignedClause(
2033 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
2034 }
2035
2036 /// Build a new OpenMP 'copyin' clause.
2037 ///
2038 /// By default, performs semantic analysis to build the new OpenMP clause.
2039 /// Subclasses may override this routine to provide different behavior.
2040 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
2041 SourceLocation StartLoc,
2042 SourceLocation LParenLoc,
2043 SourceLocation EndLoc) {
2044 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
2045 LParenLoc, EndLoc);
2046 }
2047
2048 /// Build a new OpenMP 'copyprivate' clause.
2049 ///
2050 /// By default, performs semantic analysis to build the new OpenMP clause.
2051 /// Subclasses may override this routine to provide different behavior.
2052 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
2053 SourceLocation StartLoc,
2054 SourceLocation LParenLoc,
2055 SourceLocation EndLoc) {
2056 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2057 LParenLoc, EndLoc);
2058 }
2059
2060 /// Build a new OpenMP 'flush' pseudo clause.
2061 ///
2062 /// By default, performs semantic analysis to build the new OpenMP clause.
2063 /// Subclasses may override this routine to provide different behavior.
2064 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2065 SourceLocation StartLoc,
2066 SourceLocation LParenLoc,
2067 SourceLocation EndLoc) {
2068 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2069 LParenLoc, EndLoc);
2070 }
2071
2072 /// Build a new OpenMP 'depobj' pseudo clause.
2073 ///
2074 /// By default, performs semantic analysis to build the new OpenMP clause.
2075 /// Subclasses may override this routine to provide different behavior.
2076 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2077 SourceLocation LParenLoc,
2078 SourceLocation EndLoc) {
2079 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2080 LParenLoc, EndLoc);
2081 }
2082
2083 /// Build a new OpenMP 'depend' pseudo clause.
2084 ///
2085 /// By default, performs semantic analysis to build the new OpenMP clause.
2086 /// Subclasses may override this routine to provide different behavior.
2087 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2088 Expr *DepModifier, ArrayRef<Expr *> VarList,
2089 SourceLocation StartLoc,
2090 SourceLocation LParenLoc,
2091 SourceLocation EndLoc) {
2092 return getSema().OpenMP().ActOnOpenMPDependClause(
2093 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2094 }
2095
2096 /// Build a new OpenMP 'device' clause.
2097 ///
2098 /// By default, performs semantic analysis to build the new statement.
2099 /// Subclasses may override this routine to provide different behavior.
2100 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2101 Expr *Device, SourceLocation StartLoc,
2102 SourceLocation LParenLoc,
2103 SourceLocation ModifierLoc,
2104 SourceLocation EndLoc) {
2105 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2106 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2107 }
2108
2109 /// Build a new OpenMP 'map' clause.
2110 ///
2111 /// By default, performs semantic analysis to build the new OpenMP clause.
2112 /// Subclasses may override this routine to provide different behavior.
2113 OMPClause *RebuildOMPMapClause(
2114 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2115 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2116 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2117 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2118 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2119 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2120 return getSema().OpenMP().ActOnOpenMPMapClause(
2121 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2122 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2123 ColonLoc, VarList, Locs,
2124 /*NoDiagnose=*/false, UnresolvedMappers);
2125 }
2126
2127 /// Build a new OpenMP 'allocate' clause.
2128 ///
2129 /// By default, performs semantic analysis to build the new OpenMP clause.
2130 /// Subclasses may override this routine to provide different behavior.
2131 OMPClause *
2132 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2133 OpenMPAllocateClauseModifier FirstModifier,
2134 SourceLocation FirstModifierLoc,
2135 OpenMPAllocateClauseModifier SecondModifier,
2136 SourceLocation SecondModifierLoc,
2137 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2138 SourceLocation LParenLoc, SourceLocation ColonLoc,
2139 SourceLocation EndLoc) {
2140 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2141 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2142 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2143 }
2144
2145 /// Build a new OpenMP 'num_teams' clause.
2146 ///
2147 /// By default, performs semantic analysis to build the new statement.
2148 /// Subclasses may override this routine to provide different behavior.
2149 OMPClause *RebuildOMPNumTeamsClause(
2150 ArrayRef<Expr *> VarList, OpenMPNumTeamsClauseModifier Modifier,
2151 Expr *ModifierExpr, SourceLocation ModifierLoc,
2152 OpenMPNumTeamsClauseModifier ModifierExtra, Expr *ModifierExtraExpr,
2153 SourceLocation ModifierExtraLoc, SourceLocation StartLoc,
2154 SourceLocation LParenLoc, SourceLocation EndLoc) {
2155 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(
2156 VarList, Modifier, ModifierExpr, ModifierLoc, ModifierExtra,
2157 ModifierExtraExpr, ModifierExtraLoc, StartLoc, LParenLoc, EndLoc);
2158 }
2159
2160 /// Build a new OpenMP 'thread_limit' clause.
2161 ///
2162 /// By default, performs semantic analysis to build the new statement.
2163 /// Subclasses may override this routine to provide different behavior.
2164 OMPClause *RebuildOMPThreadLimitClause(
2165 ArrayRef<Expr *> VarList, OpenMPThreadLimitClauseModifier Modifier,
2166 Expr *ModifierExpr, SourceLocation ModifierLoc, SourceLocation StartLoc,
2167 SourceLocation LParenLoc, SourceLocation EndLoc) {
2168 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(
2169 VarList, Modifier, ModifierExpr, ModifierLoc, StartLoc, LParenLoc,
2170 EndLoc);
2171 }
2172
2173 /// Build a new OpenMP 'priority' clause.
2174 ///
2175 /// By default, performs semantic analysis to build the new statement.
2176 /// Subclasses may override this routine to provide different behavior.
2177 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2178 SourceLocation LParenLoc,
2179 SourceLocation EndLoc) {
2180 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2181 LParenLoc, EndLoc);
2182 }
2183
2184 /// Build a new OpenMP 'grainsize' clause.
2185 ///
2186 /// By default, performs semantic analysis to build the new statement.
2187 /// Subclasses may override this routine to provide different behavior.
2188 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2189 Expr *Device, SourceLocation StartLoc,
2190 SourceLocation LParenLoc,
2191 SourceLocation ModifierLoc,
2192 SourceLocation EndLoc) {
2193 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2194 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2195 }
2196
2197 /// Build a new OpenMP 'num_tasks' clause.
2198 ///
2199 /// By default, performs semantic analysis to build the new statement.
2200 /// Subclasses may override this routine to provide different behavior.
2201 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2202 Expr *NumTasks, SourceLocation StartLoc,
2203 SourceLocation LParenLoc,
2204 SourceLocation ModifierLoc,
2205 SourceLocation EndLoc) {
2206 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2207 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2208 }
2209
2210 /// Build a new OpenMP 'hint' clause.
2211 ///
2212 /// By default, performs semantic analysis to build the new statement.
2213 /// Subclasses may override this routine to provide different behavior.
2214 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2215 SourceLocation LParenLoc,
2216 SourceLocation EndLoc) {
2217 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2218 EndLoc);
2219 }
2220
2221 /// Build a new OpenMP 'detach' clause.
2222 ///
2223 /// By default, performs semantic analysis to build the new statement.
2224 /// Subclasses may override this routine to provide different behavior.
2225 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2226 SourceLocation LParenLoc,
2227 SourceLocation EndLoc) {
2228 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2229 EndLoc);
2230 }
2231
2232 /// Build a new OpenMP 'dist_schedule' clause.
2233 ///
2234 /// By default, performs semantic analysis to build the new OpenMP clause.
2235 /// Subclasses may override this routine to provide different behavior.
2236 OMPClause *
2237 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2238 Expr *ChunkSize, SourceLocation StartLoc,
2239 SourceLocation LParenLoc, SourceLocation KindLoc,
2240 SourceLocation CommaLoc, SourceLocation EndLoc) {
2241 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2242 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2243 }
2244
2245 /// Build a new OpenMP 'to' clause.
2246 ///
2247 /// By default, performs semantic analysis to build the new statement.
2248 /// Subclasses may override this routine to provide different behavior.
2249 OMPClause *
2250 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2251 ArrayRef<SourceLocation> MotionModifiersLoc,
2252 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2253 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2254 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2255 ArrayRef<Expr *> UnresolvedMappers) {
2256 return getSema().OpenMP().ActOnOpenMPToClause(
2257 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2258 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2259 UnresolvedMappers);
2260 }
2261
2262 /// Build a new OpenMP 'from' clause.
2263 ///
2264 /// By default, performs semantic analysis to build the new statement.
2265 /// Subclasses may override this routine to provide different behavior.
2266 OMPClause *
2267 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2268 ArrayRef<SourceLocation> MotionModifiersLoc,
2269 Expr *IteratorModifier, CXXScopeSpec &MapperIdScopeSpec,
2270 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2271 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2272 ArrayRef<Expr *> UnresolvedMappers) {
2273 return getSema().OpenMP().ActOnOpenMPFromClause(
2274 MotionModifiers, MotionModifiersLoc, IteratorModifier,
2275 MapperIdScopeSpec, MapperId, ColonLoc, VarList, Locs,
2276 UnresolvedMappers);
2277 }
2278
2279 /// Build a new OpenMP 'use_device_ptr' clause.
2280 ///
2281 /// By default, performs semantic analysis to build the new OpenMP clause.
2282 /// Subclasses may override this routine to provide different behavior.
2283 OMPClause *RebuildOMPUseDevicePtrClause(
2284 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2285 OpenMPUseDevicePtrFallbackModifier FallbackModifier,
2286 SourceLocation FallbackModifierLoc) {
2287 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(
2288 VarList, Locs, FallbackModifier, FallbackModifierLoc);
2289 }
2290
2291 /// Build a new OpenMP 'use_device_addr' clause.
2292 ///
2293 /// By default, performs semantic analysis to build the new OpenMP clause.
2294 /// Subclasses may override this routine to provide different behavior.
2295 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2296 const OMPVarListLocTy &Locs) {
2297 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2298 }
2299
2300 /// Build a new OpenMP 'is_device_ptr' clause.
2301 ///
2302 /// By default, performs semantic analysis to build the new OpenMP clause.
2303 /// Subclasses may override this routine to provide different behavior.
2304 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2305 const OMPVarListLocTy &Locs) {
2306 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2307 }
2308
2309 /// Build a new OpenMP 'has_device_addr' clause.
2310 ///
2311 /// By default, performs semantic analysis to build the new OpenMP clause.
2312 /// Subclasses may override this routine to provide different behavior.
2313 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2314 const OMPVarListLocTy &Locs) {
2315 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2316 }
2317
2318 /// Build a new OpenMP 'defaultmap' clause.
2319 ///
2320 /// By default, performs semantic analysis to build the new OpenMP clause.
2321 /// Subclasses may override this routine to provide different behavior.
2322 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2323 OpenMPDefaultmapClauseKind Kind,
2324 SourceLocation StartLoc,
2325 SourceLocation LParenLoc,
2326 SourceLocation MLoc,
2327 SourceLocation KindLoc,
2328 SourceLocation EndLoc) {
2329 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2330 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2331 }
2332
2333 /// Build a new OpenMP 'nontemporal' clause.
2334 ///
2335 /// By default, performs semantic analysis to build the new OpenMP clause.
2336 /// Subclasses may override this routine to provide different behavior.
2337 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2338 SourceLocation StartLoc,
2339 SourceLocation LParenLoc,
2340 SourceLocation EndLoc) {
2341 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2342 LParenLoc, EndLoc);
2343 }
2344
2345 /// Build a new OpenMP 'inclusive' clause.
2346 ///
2347 /// By default, performs semantic analysis to build the new OpenMP clause.
2348 /// Subclasses may override this routine to provide different behavior.
2349 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2350 SourceLocation StartLoc,
2351 SourceLocation LParenLoc,
2352 SourceLocation EndLoc) {
2353 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2354 LParenLoc, EndLoc);
2355 }
2356
2357 /// Build a new OpenMP 'exclusive' clause.
2358 ///
2359 /// By default, performs semantic analysis to build the new OpenMP clause.
2360 /// Subclasses may override this routine to provide different behavior.
2361 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2362 SourceLocation StartLoc,
2363 SourceLocation LParenLoc,
2364 SourceLocation EndLoc) {
2365 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2366 LParenLoc, EndLoc);
2367 }
2368
2369 /// Build a new OpenMP 'uses_allocators' clause.
2370 ///
2371 /// By default, performs semantic analysis to build the new OpenMP clause.
2372 /// Subclasses may override this routine to provide different behavior.
2373 OMPClause *RebuildOMPUsesAllocatorsClause(
2374 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2375 SourceLocation LParenLoc, SourceLocation EndLoc) {
2376 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2377 StartLoc, LParenLoc, EndLoc, Data);
2378 }
2379
2380 /// Build a new OpenMP 'affinity' clause.
2381 ///
2382 /// By default, performs semantic analysis to build the new OpenMP clause.
2383 /// Subclasses may override this routine to provide different behavior.
2384 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2385 SourceLocation LParenLoc,
2386 SourceLocation ColonLoc,
2387 SourceLocation EndLoc, Expr *Modifier,
2388 ArrayRef<Expr *> Locators) {
2389 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2390 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2391 }
2392
2393 /// Build a new OpenMP 'order' clause.
2394 ///
2395 /// By default, performs semantic analysis to build the new OpenMP clause.
2396 /// Subclasses may override this routine to provide different behavior.
2397 OMPClause *RebuildOMPOrderClause(
2398 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2399 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2400 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2401 return getSema().OpenMP().ActOnOpenMPOrderClause(
2402 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2403 }
2404
2405 /// Build a new OpenMP 'init' clause.
2406 ///
2407 /// By default, performs semantic analysis to build the new OpenMP clause.
2408 /// Subclasses may override this routine to provide different behavior.
2409 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2410 SourceLocation StartLoc,
2411 SourceLocation LParenLoc,
2412 SourceLocation VarLoc,
2413 SourceLocation EndLoc) {
2414 return getSema().OpenMP().ActOnOpenMPInitClause(
2415 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2416 }
2417
2418 /// Build a new OpenMP 'use' clause.
2419 ///
2420 /// By default, performs semantic analysis to build the new OpenMP clause.
2421 /// Subclasses may override this routine to provide different behavior.
2422 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2423 SourceLocation LParenLoc,
2424 SourceLocation VarLoc, SourceLocation EndLoc) {
2425 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2426 LParenLoc, VarLoc, EndLoc);
2427 }
2428
2429 /// Build a new OpenMP 'destroy' clause.
2430 ///
2431 /// By default, performs semantic analysis to build the new OpenMP clause.
2432 /// Subclasses may override this routine to provide different behavior.
2433 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2434 SourceLocation LParenLoc,
2435 SourceLocation VarLoc,
2436 SourceLocation EndLoc) {
2437 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2438 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2439 }
2440
2441 /// Build a new OpenMP 'novariants' clause.
2442 ///
2443 /// By default, performs semantic analysis to build the new OpenMP clause.
2444 /// Subclasses may override this routine to provide different behavior.
2445 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2446 SourceLocation StartLoc,
2447 SourceLocation LParenLoc,
2448 SourceLocation EndLoc) {
2449 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2450 LParenLoc, EndLoc);
2451 }
2452
2453 /// Build a new OpenMP 'nocontext' clause.
2454 ///
2455 /// By default, performs semantic analysis to build the new OpenMP clause.
2456 /// Subclasses may override this routine to provide different behavior.
2457 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2458 SourceLocation LParenLoc,
2459 SourceLocation EndLoc) {
2460 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2461 LParenLoc, EndLoc);
2462 }
2463
2464 /// Build a new OpenMP 'filter' clause.
2465 ///
2466 /// By default, performs semantic analysis to build the new OpenMP clause.
2467 /// Subclasses may override this routine to provide different behavior.
2468 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2469 SourceLocation LParenLoc,
2470 SourceLocation EndLoc) {
2471 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2472 LParenLoc, EndLoc);
2473 }
2474
2475 /// Build a new OpenMP 'bind' clause.
2476 ///
2477 /// By default, performs semantic analysis to build the new OpenMP clause.
2478 /// Subclasses may override this routine to provide different behavior.
2479 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2480 SourceLocation KindLoc,
2481 SourceLocation StartLoc,
2482 SourceLocation LParenLoc,
2483 SourceLocation EndLoc) {
2484 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2485 LParenLoc, EndLoc);
2486 }
2487
2488 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2489 ///
2490 /// By default, performs semantic analysis to build the new OpenMP clause.
2491 /// Subclasses may override this routine to provide different behavior.
2492 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2493 SourceLocation LParenLoc,
2494 SourceLocation EndLoc) {
2495 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2496 LParenLoc, EndLoc);
2497 }
2498
2499 /// Build a new OpenMP 'dyn_groupprivate' clause.
2500 ///
2501 /// By default, performs semantic analysis to build the new OpenMP clause.
2502 /// Subclasses may override this routine to provide different behavior.
2503 OMPClause *RebuildOMPDynGroupprivateClause(
2504 OpenMPDynGroupprivateClauseModifier M1,
2505 OpenMPDynGroupprivateClauseFallbackModifier M2, Expr *Size,
2506 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc,
2507 SourceLocation M2Loc, SourceLocation EndLoc) {
2508 return getSema().OpenMP().ActOnOpenMPDynGroupprivateClause(
2509 M1, M2, Size, StartLoc, LParenLoc, M1Loc, M2Loc, EndLoc);
2510 }
2511
2512 /// Build a new OpenMP 'ompx_attribute' clause.
2513 ///
2514 /// By default, performs semantic analysis to build the new OpenMP clause.
2515 /// Subclasses may override this routine to provide different behavior.
2516 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2517 SourceLocation StartLoc,
2518 SourceLocation LParenLoc,
2519 SourceLocation EndLoc) {
2520 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2521 LParenLoc, EndLoc);
2522 }
2523
2524 /// Build a new OpenMP 'ompx_bare' clause.
2525 ///
2526 /// By default, performs semantic analysis to build the new OpenMP clause.
2527 /// Subclasses may override this routine to provide different behavior.
2528 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2529 SourceLocation EndLoc) {
2530 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2531 }
2532
2533 /// Build a new OpenMP 'align' clause.
2534 ///
2535 /// By default, performs semantic analysis to build the new OpenMP clause.
2536 /// Subclasses may override this routine to provide different behavior.
2537 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2538 SourceLocation LParenLoc,
2539 SourceLocation EndLoc) {
2540 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2541 EndLoc);
2542 }
2543
2544 /// Build a new OpenMP 'at' clause.
2545 ///
2546 /// By default, performs semantic analysis to build the new OpenMP clause.
2547 /// Subclasses may override this routine to provide different behavior.
2548 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2549 SourceLocation StartLoc,
2550 SourceLocation LParenLoc,
2551 SourceLocation EndLoc) {
2552 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2553 LParenLoc, EndLoc);
2554 }
2555
2556 /// Build a new OpenMP 'severity' clause.
2557 ///
2558 /// By default, performs semantic analysis to build the new OpenMP clause.
2559 /// Subclasses may override this routine to provide different behavior.
2560 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2561 SourceLocation KwLoc,
2562 SourceLocation StartLoc,
2563 SourceLocation LParenLoc,
2564 SourceLocation EndLoc) {
2565 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2566 LParenLoc, EndLoc);
2567 }
2568
2569 /// Build a new OpenMP 'message' clause.
2570 ///
2571 /// By default, performs semantic analysis to build the new OpenMP clause.
2572 /// Subclasses may override this routine to provide different behavior.
2573 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2574 SourceLocation LParenLoc,
2575 SourceLocation EndLoc) {
2576 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2577 EndLoc);
2578 }
2579
2580 /// Build a new OpenMP 'doacross' clause.
2581 ///
2582 /// By default, performs semantic analysis to build the new OpenMP clause.
2583 /// Subclasses may override this routine to provide different behavior.
2584 OMPClause *
2585 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2586 SourceLocation DepLoc, SourceLocation ColonLoc,
2587 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2588 SourceLocation LParenLoc, SourceLocation EndLoc) {
2589 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2590 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2591 }
2592
2593 /// Build a new OpenMP 'holds' clause.
2594 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2595 SourceLocation LParenLoc,
2596 SourceLocation EndLoc) {
2597 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2598 EndLoc);
2599 }
2600
2601 /// Rebuild the operand to an Objective-C \@synchronized statement.
2602 ///
2603 /// By default, performs semantic analysis to build the new statement.
2604 /// Subclasses may override this routine to provide different behavior.
2605 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2606 Expr *object) {
2607 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2608 }
2609
2610 /// Build a new Objective-C \@synchronized statement.
2611 ///
2612 /// By default, performs semantic analysis to build the new statement.
2613 /// Subclasses may override this routine to provide different behavior.
2614 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2615 Expr *Object, Stmt *Body) {
2616 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2617 }
2618
2619 /// Build a new Objective-C \@autoreleasepool statement.
2620 ///
2621 /// By default, performs semantic analysis to build the new statement.
2622 /// Subclasses may override this routine to provide different behavior.
2623 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2624 Stmt *Body) {
2625 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2626 }
2627
2628 /// Build a new Objective-C fast enumeration statement.
2629 ///
2630 /// By default, performs semantic analysis to build the new statement.
2631 /// Subclasses may override this routine to provide different behavior.
2632 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2633 Stmt *Element,
2634 Expr *Collection,
2635 SourceLocation RParenLoc,
2636 Stmt *Body) {
2637 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2638 ForLoc, Element, Collection, RParenLoc);
2639 if (ForEachStmt.isInvalid())
2640 return StmtError();
2641
2642 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2643 Body);
2644 }
2645
2646 /// Build a new C++ exception declaration.
2647 ///
2648 /// By default, performs semantic analysis to build the new decaration.
2649 /// Subclasses may override this routine to provide different behavior.
2650 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2651 TypeSourceInfo *Declarator,
2652 SourceLocation StartLoc,
2653 SourceLocation IdLoc,
2654 IdentifierInfo *Id) {
2655 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2656 StartLoc, IdLoc, Id);
2657 if (Var)
2658 getSema().CurContext->addDecl(Var);
2659 return Var;
2660 }
2661
2662 /// Build a new C++ catch statement.
2663 ///
2664 /// By default, performs semantic analysis to build the new statement.
2665 /// Subclasses may override this routine to provide different behavior.
2666 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2667 VarDecl *ExceptionDecl,
2668 Stmt *Handler) {
2669 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2670 Handler));
2671 }
2672
2673 /// Build a new C++ try statement.
2674 ///
2675 /// By default, performs semantic analysis to build the new statement.
2676 /// Subclasses may override this routine to provide different behavior.
2677 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2678 ArrayRef<Stmt *> Handlers) {
2679 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2680 }
2681
2682 /// Build a new C++0x range-based for statement.
2683 ///
2684 /// By default, performs semantic analysis to build the new statement.
2685 /// Subclasses may override this routine to provide different behavior.
2686 StmtResult RebuildCXXForRangeStmt(
2687 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2688 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2689 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2690 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2691 // If we've just learned that the range is actually an Objective-C
2692 // collection, treat this as an Objective-C fast enumeration loop.
2693 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2694 if (RangeStmt->isSingleDecl()) {
2695 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2696 if (RangeVar->isInvalidDecl())
2697 return StmtError();
2698
2699 Expr *RangeExpr = RangeVar->getInit();
2700 if (!RangeExpr->isTypeDependent() &&
2701 RangeExpr->getType()->isObjCObjectPointerType()) {
2702 // FIXME: Support init-statements in Objective-C++20 ranged for
2703 // statement.
2704 if (Init) {
2705 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2706 DiagID: diag::err_objc_for_range_init_stmt)
2707 << Init->getSourceRange();
2708 }
2709 return getSema().ObjC().ActOnObjCForCollectionStmt(
2710 ForLoc, LoopVar, RangeExpr, RParenLoc);
2711 }
2712 }
2713 }
2714 }
2715
2716 return getSema().BuildCXXForRangeStmt(
2717 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2718 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2719 }
2720
2721 /// Build a new C++0x range-based for statement.
2722 ///
2723 /// By default, performs semantic analysis to build the new statement.
2724 /// Subclasses may override this routine to provide different behavior.
2725 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2726 bool IsIfExists,
2727 NestedNameSpecifierLoc QualifierLoc,
2728 DeclarationNameInfo NameInfo,
2729 Stmt *Nested) {
2730 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2731 QualifierLoc, NameInfo, Nested);
2732 }
2733
2734 /// Attach body to a C++0x range-based for statement.
2735 ///
2736 /// By default, performs semantic analysis to finish the new statement.
2737 /// Subclasses may override this routine to provide different behavior.
2738 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2739 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2740 }
2741
2742 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2743 Stmt *TryBlock, Stmt *Handler) {
2744 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2745 }
2746
2747 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2748 Stmt *Block) {
2749 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2750 }
2751
2752 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2753 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2754 }
2755
2756 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2757 SourceLocation LParen,
2758 SourceLocation RParen,
2759 TypeSourceInfo *TSI) {
2760 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2761 TSI);
2762 }
2763
2764 /// Build a new predefined expression.
2765 ///
2766 /// By default, performs semantic analysis to build the new expression.
2767 /// Subclasses may override this routine to provide different behavior.
2768 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2769 return getSema().BuildPredefinedExpr(Loc, IK);
2770 }
2771
2772 /// Build a new expression that references a declaration.
2773 ///
2774 /// By default, performs semantic analysis to build the new expression.
2775 /// Subclasses may override this routine to provide different behavior.
2776 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2777 LookupResult &R,
2778 bool RequiresADL) {
2779 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2780 }
2781
2782
2783 /// Build a new expression that references a declaration.
2784 ///
2785 /// By default, performs semantic analysis to build the new expression.
2786 /// Subclasses may override this routine to provide different behavior.
2787 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2788 ValueDecl *VD,
2789 const DeclarationNameInfo &NameInfo,
2790 NamedDecl *Found,
2791 TemplateArgumentListInfo *TemplateArgs) {
2792 CXXScopeSpec SS;
2793 SS.Adopt(Other: QualifierLoc);
2794 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2795 TemplateArgs);
2796 }
2797
2798 /// Build a new expression in parentheses.
2799 ///
2800 /// By default, performs semantic analysis to build the new expression.
2801 /// Subclasses may override this routine to provide different behavior.
2802 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2803 SourceLocation RParen) {
2804 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2805 }
2806
2807 /// Build a new pseudo-destructor expression.
2808 ///
2809 /// By default, performs semantic analysis to build the new expression.
2810 /// Subclasses may override this routine to provide different behavior.
2811 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2812 SourceLocation OperatorLoc,
2813 bool isArrow,
2814 CXXScopeSpec &SS,
2815 TypeSourceInfo *ScopeType,
2816 SourceLocation CCLoc,
2817 SourceLocation TildeLoc,
2818 PseudoDestructorTypeStorage Destroyed);
2819
2820 /// Build a new unary operator expression.
2821 ///
2822 /// By default, performs semantic analysis to build the new expression.
2823 /// Subclasses may override this routine to provide different behavior.
2824 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2825 UnaryOperatorKind Opc,
2826 Expr *SubExpr) {
2827 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2828 }
2829
2830 /// Build a new builtin offsetof expression.
2831 ///
2832 /// By default, performs semantic analysis to build the new expression.
2833 /// Subclasses may override this routine to provide different behavior.
2834 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2835 TypeSourceInfo *Type, const Designation &Desig,
2836 SourceLocation RParenLoc) {
2837 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Desig, RParenLoc);
2838 }
2839
2840 /// Build a new sizeof, alignof or vec_step expression with a
2841 /// type argument.
2842 ///
2843 /// By default, performs semantic analysis to build the new expression.
2844 /// Subclasses may override this routine to provide different behavior.
2845 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2846 SourceLocation OpLoc,
2847 UnaryExprOrTypeTrait ExprKind,
2848 SourceRange R) {
2849 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2850 }
2851
2852 /// Build a new sizeof, alignof or vec step expression with an
2853 /// expression argument.
2854 ///
2855 /// By default, performs semantic analysis to build the new expression.
2856 /// Subclasses may override this routine to provide different behavior.
2857 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2858 UnaryExprOrTypeTrait ExprKind,
2859 SourceRange R) {
2860 ExprResult Result
2861 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2862 if (Result.isInvalid())
2863 return ExprError();
2864
2865 return Result;
2866 }
2867
2868 /// Build a new array subscript expression.
2869 ///
2870 /// By default, performs semantic analysis to build the new expression.
2871 /// Subclasses may override this routine to provide different behavior.
2872 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2873 SourceLocation LBracketLoc,
2874 Expr *RHS,
2875 SourceLocation RBracketLoc) {
2876 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2877 LBracketLoc, RHS,
2878 RBracketLoc);
2879 }
2880
2881 /// Build a new matrix single subscript expression.
2882 ///
2883 /// By default, performs semantic analysis to build the new expression.
2884 /// Subclasses may override this routine to provide different behavior.
2885 ExprResult RebuildMatrixSingleSubscriptExpr(Expr *Base, Expr *RowIdx,
2886 SourceLocation RBracketLoc) {
2887 return getSema().CreateBuiltinMatrixSingleSubscriptExpr(Base, RowIdx,
2888 RBracketLoc);
2889 }
2890
2891 /// Build a new matrix subscript expression.
2892 ///
2893 /// By default, performs semantic analysis to build the new expression.
2894 /// Subclasses may override this routine to provide different behavior.
2895 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2896 Expr *ColumnIdx,
2897 SourceLocation RBracketLoc) {
2898 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2899 RBracketLoc);
2900 }
2901
2902 /// Build a new array section expression.
2903 ///
2904 /// By default, performs semantic analysis to build the new expression.
2905 /// Subclasses may override this routine to provide different behavior.
2906 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2907 SourceLocation LBracketLoc,
2908 Expr *LowerBound,
2909 SourceLocation ColonLocFirst,
2910 SourceLocation ColonLocSecond,
2911 Expr *Length, Expr *Stride,
2912 SourceLocation RBracketLoc) {
2913 if (IsOMPArraySection)
2914 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2915 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2916 Stride, RBracketLoc);
2917
2918 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2919 "Stride/second colon not allowed for OpenACC");
2920
2921 return getSema().OpenACC().ActOnArraySectionExpr(
2922 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2923 }
2924
2925 /// Build a new array shaping expression.
2926 ///
2927 /// By default, performs semantic analysis to build the new expression.
2928 /// Subclasses may override this routine to provide different behavior.
2929 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2930 SourceLocation RParenLoc,
2931 ArrayRef<Expr *> Dims,
2932 ArrayRef<SourceRange> BracketsRanges) {
2933 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2934 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2935 }
2936
2937 /// Build a new iterator expression.
2938 ///
2939 /// By default, performs semantic analysis to build the new expression.
2940 /// Subclasses may override this routine to provide different behavior.
2941 ExprResult
2942 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2943 SourceLocation RLoc,
2944 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2945 return getSema().OpenMP().ActOnOMPIteratorExpr(
2946 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2947 }
2948
2949 /// Build a new call expression.
2950 ///
2951 /// By default, performs semantic analysis to build the new expression.
2952 /// Subclasses may override this routine to provide different behavior.
2953 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2954 MultiExprArg Args,
2955 SourceLocation RParenLoc,
2956 Expr *ExecConfig = nullptr) {
2957 return getSema().ActOnCallExpr(
2958 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2959 }
2960
2961 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2962 MultiExprArg Args,
2963 SourceLocation RParenLoc) {
2964 return getSema().ActOnArraySubscriptExpr(
2965 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2966 }
2967
2968 /// Build a new member access expression.
2969 ///
2970 /// By default, performs semantic analysis to build the new expression.
2971 /// Subclasses may override this routine to provide different behavior.
2972 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2973 bool isArrow,
2974 NestedNameSpecifierLoc QualifierLoc,
2975 SourceLocation TemplateKWLoc,
2976 const DeclarationNameInfo &MemberNameInfo,
2977 ValueDecl *Member,
2978 NamedDecl *FoundDecl,
2979 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2980 NamedDecl *FirstQualifierInScope) {
2981 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2982 isArrow);
2983 if (!Member->getDeclName()) {
2984 // We have a reference to an unnamed field. This is always the
2985 // base of an anonymous struct/union member access, i.e. the
2986 // field is always of record type.
2987 assert(Member->getType()->isRecordType() &&
2988 "unnamed member not of record type?");
2989
2990 BaseResult =
2991 getSema().PerformObjectMemberConversion(BaseResult.get(),
2992 QualifierLoc.getNestedNameSpecifier(),
2993 FoundDecl, Member);
2994 if (BaseResult.isInvalid())
2995 return ExprError();
2996 Base = BaseResult.get();
2997
2998 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2999 // from the AST, so we need to re-insert them if needed (since
3000 // `BuildFieldRefereneExpr()` doesn't do this).
3001 if (!isArrow && Base->isPRValue()) {
3002 BaseResult = getSema().TemporaryMaterializationConversion(Base);
3003 if (BaseResult.isInvalid())
3004 return ExprError();
3005 Base = BaseResult.get();
3006 }
3007
3008 CXXScopeSpec EmptySS;
3009 return getSema().BuildFieldReferenceExpr(
3010 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
3011 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
3012 MemberNameInfo);
3013 }
3014
3015 CXXScopeSpec SS;
3016 SS.Adopt(Other: QualifierLoc);
3017
3018 Base = BaseResult.get();
3019 if (Base->containsErrors())
3020 return ExprError();
3021
3022 QualType BaseType = Base->getType();
3023
3024 if (isArrow && !BaseType->isPointerType())
3025 return ExprError();
3026
3027 // FIXME: this involves duplicating earlier analysis in a lot of
3028 // cases; we should avoid this when possible.
3029 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
3030 R.addDecl(D: FoundDecl);
3031 R.resolveKind();
3032
3033 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
3034 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
3035 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
3036 ->getType()
3037 ->getPointeeType()
3038 ->getAsCXXRecordDecl()) {
3039 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
3040 // In unevaluated contexts, an expression supposed to be a member access
3041 // might reference a member in an unrelated class.
3042 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
3043 return getSema().BuildDeclRefExpr(Member, Member->getType(),
3044 VK_LValue, Member->getLocation());
3045 }
3046 }
3047
3048 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
3049 SS, TemplateKWLoc,
3050 FirstQualifierInScope,
3051 R, ExplicitTemplateArgs,
3052 /*S*/nullptr);
3053 }
3054
3055 /// Build a new binary operator expression.
3056 ///
3057 /// By default, performs semantic analysis to build the new expression.
3058 /// Subclasses may override this routine to provide different behavior.
3059 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
3060 Expr *LHS, Expr *RHS,
3061 bool ForFoldExpression = false) {
3062 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
3063 ForFoldExpression);
3064 }
3065
3066 /// Build a new rewritten operator expression.
3067 ///
3068 /// By default, performs semantic analysis to build the new expression.
3069 /// Subclasses may override this routine to provide different behavior.
3070 ExprResult RebuildCXXRewrittenBinaryOperator(
3071 SourceLocation OpLoc, BinaryOperatorKind Opcode,
3072 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
3073 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
3074 RHS, /*RequiresADL*/false);
3075 }
3076
3077 /// Build a new conditional operator expression.
3078 ///
3079 /// By default, performs semantic analysis to build the new expression.
3080 /// Subclasses may override this routine to provide different behavior.
3081 ExprResult RebuildConditionalOperator(Expr *Cond,
3082 SourceLocation QuestionLoc,
3083 Expr *LHS,
3084 SourceLocation ColonLoc,
3085 Expr *RHS) {
3086 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3087 LHS, RHS);
3088 }
3089
3090 /// Build a new C-style cast expression.
3091 ///
3092 /// By default, performs semantic analysis to build the new expression.
3093 /// Subclasses may override this routine to provide different behavior.
3094 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3095 TypeSourceInfo *TInfo,
3096 SourceLocation RParenLoc,
3097 Expr *SubExpr) {
3098 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3099 SubExpr);
3100 }
3101
3102 /// Build a new compound literal expression.
3103 ///
3104 /// By default, performs semantic analysis to build the new expression.
3105 /// Subclasses may override this routine to provide different behavior.
3106 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3107 TypeSourceInfo *TInfo,
3108 SourceLocation RParenLoc,
3109 Expr *Init) {
3110 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3111 Init);
3112 }
3113
3114 /// Build a new extended vector or matrix element access expression.
3115 ///
3116 /// By default, performs semantic analysis to build the new expression.
3117 /// Subclasses may override this routine to provide different behavior.
3118 ExprResult RebuildExtVectorOrMatrixElementExpr(Expr *Base,
3119 SourceLocation OpLoc,
3120 bool IsArrow,
3121 SourceLocation AccessorLoc,
3122 IdentifierInfo &Accessor) {
3123
3124 CXXScopeSpec SS;
3125 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3126 return getSema().BuildMemberReferenceExpr(
3127 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3128 /*FirstQualifierInScope*/ nullptr, NameInfo,
3129 /* TemplateArgs */ nullptr,
3130 /*S*/ nullptr);
3131 }
3132
3133 /// Build a new initializer list expression.
3134 ///
3135 /// By default, performs semantic analysis to build the new expression.
3136 /// Subclasses may override this routine to provide different behavior.
3137 ExprResult RebuildInitList(SourceLocation LBraceLoc, MultiExprArg Inits,
3138 SourceLocation RBraceLoc, bool IsExplicit) {
3139 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc, IsExplicit);
3140 }
3141
3142 /// Build a new designated initializer expression.
3143 ///
3144 /// By default, performs semantic analysis to build the new expression.
3145 /// Subclasses may override this routine to provide different behavior.
3146 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3147 MultiExprArg ArrayExprs,
3148 SourceLocation EqualOrColonLoc,
3149 bool GNUSyntax,
3150 Expr *Init) {
3151 ExprResult Result
3152 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3153 Init);
3154 if (Result.isInvalid())
3155 return ExprError();
3156
3157 return Result;
3158 }
3159
3160 /// Build a new value-initialized expression.
3161 ///
3162 /// By default, builds the implicit value initialization without performing
3163 /// any semantic analysis. Subclasses may override this routine to provide
3164 /// different behavior.
3165 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3166 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3167 }
3168
3169 /// Build a new \c va_arg expression.
3170 ///
3171 /// By default, performs semantic analysis to build the new expression.
3172 /// Subclasses may override this routine to provide different behavior.
3173 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3174 Expr *SubExpr, TypeSourceInfo *TInfo,
3175 SourceLocation RParenLoc) {
3176 return getSema().BuildVAArgExpr(BuiltinLoc,
3177 SubExpr, TInfo,
3178 RParenLoc);
3179 }
3180
3181 /// Build a new expression list in parentheses.
3182 ///
3183 /// By default, performs semantic analysis to build the new expression.
3184 /// Subclasses may override this routine to provide different behavior.
3185 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3186 MultiExprArg SubExprs,
3187 SourceLocation RParenLoc) {
3188 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3189 }
3190
3191 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3192 unsigned NumUserSpecifiedExprs,
3193 SourceLocation InitLoc,
3194 SourceLocation LParenLoc,
3195 SourceLocation RParenLoc) {
3196 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3197 InitLoc, LParenLoc, RParenLoc);
3198 }
3199
3200 /// Build a new address-of-label expression.
3201 ///
3202 /// By default, performs semantic analysis, using the name of the label
3203 /// rather than attempting to map the label statement itself.
3204 /// Subclasses may override this routine to provide different behavior.
3205 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3206 SourceLocation LabelLoc, LabelDecl *Label) {
3207 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3208 }
3209
3210 /// Build a new GNU statement expression.
3211 ///
3212 /// By default, performs semantic analysis to build the new expression.
3213 /// Subclasses may override this routine to provide different behavior.
3214 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3215 SourceLocation RParenLoc, unsigned TemplateDepth) {
3216 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3217 TemplateDepth);
3218 }
3219
3220 /// Build a new __builtin_choose_expr expression.
3221 ///
3222 /// By default, performs semantic analysis to build the new expression.
3223 /// Subclasses may override this routine to provide different behavior.
3224 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3225 Expr *Cond, Expr *LHS, Expr *RHS,
3226 SourceLocation RParenLoc) {
3227 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3228 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3229 RPLoc: RParenLoc);
3230 }
3231
3232 /// Build a new generic selection expression with an expression predicate.
3233 ///
3234 /// By default, performs semantic analysis to build the new expression.
3235 /// Subclasses may override this routine to provide different behavior.
3236 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3237 SourceLocation DefaultLoc,
3238 SourceLocation RParenLoc,
3239 Expr *ControllingExpr,
3240 ArrayRef<TypeSourceInfo *> Types,
3241 ArrayRef<Expr *> Exprs) {
3242 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3243 /*PredicateIsExpr=*/true,
3244 ControllingExpr, Types, Exprs);
3245 }
3246
3247 /// Build a new generic selection expression with a type predicate.
3248 ///
3249 /// By default, performs semantic analysis to build the new expression.
3250 /// Subclasses may override this routine to provide different behavior.
3251 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3252 SourceLocation DefaultLoc,
3253 SourceLocation RParenLoc,
3254 TypeSourceInfo *ControllingType,
3255 ArrayRef<TypeSourceInfo *> Types,
3256 ArrayRef<Expr *> Exprs) {
3257 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3258 /*PredicateIsExpr=*/false,
3259 ControllingType, Types, Exprs);
3260 }
3261
3262 /// Build a new overloaded operator call expression.
3263 ///
3264 /// By default, performs semantic analysis to build the new expression.
3265 /// The semantic analysis provides the behavior of template instantiation,
3266 /// copying with transformations that turn what looks like an overloaded
3267 /// operator call into a use of a builtin operator, performing
3268 /// argument-dependent lookup, etc. Subclasses may override this routine to
3269 /// provide different behavior.
3270 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3271 SourceLocation OpLoc,
3272 SourceLocation CalleeLoc,
3273 bool RequiresADL,
3274 const UnresolvedSetImpl &Functions,
3275 Expr *First, Expr *Second);
3276
3277 /// Build a new C++ "named" cast expression, such as static_cast or
3278 /// reinterpret_cast.
3279 ///
3280 /// By default, this routine dispatches to one of the more-specific routines
3281 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3282 /// Subclasses may override this routine to provide different behavior.
3283 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3284 Stmt::StmtClass Class,
3285 SourceLocation LAngleLoc,
3286 TypeSourceInfo *TInfo,
3287 SourceLocation RAngleLoc,
3288 SourceLocation LParenLoc,
3289 Expr *SubExpr,
3290 SourceLocation RParenLoc) {
3291 switch (Class) {
3292 case Stmt::CXXStaticCastExprClass:
3293 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3294 RAngleLoc, LParenLoc,
3295 SubExpr, RParenLoc);
3296
3297 case Stmt::CXXDynamicCastExprClass:
3298 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3299 RAngleLoc, LParenLoc,
3300 SubExpr, RParenLoc);
3301
3302 case Stmt::CXXReinterpretCastExprClass:
3303 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3304 RAngleLoc, LParenLoc,
3305 SubExpr,
3306 RParenLoc);
3307
3308 case Stmt::CXXConstCastExprClass:
3309 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3310 RAngleLoc, LParenLoc,
3311 SubExpr, RParenLoc);
3312
3313 case Stmt::CXXAddrspaceCastExprClass:
3314 return getDerived().RebuildCXXAddrspaceCastExpr(
3315 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3316
3317 default:
3318 llvm_unreachable("Invalid C++ named cast");
3319 }
3320 }
3321
3322 /// Build a new C++ static_cast expression.
3323 ///
3324 /// By default, performs semantic analysis to build the new expression.
3325 /// Subclasses may override this routine to provide different behavior.
3326 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3327 SourceLocation LAngleLoc,
3328 TypeSourceInfo *TInfo,
3329 SourceLocation RAngleLoc,
3330 SourceLocation LParenLoc,
3331 Expr *SubExpr,
3332 SourceLocation RParenLoc) {
3333 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3334 TInfo, SubExpr,
3335 SourceRange(LAngleLoc, RAngleLoc),
3336 SourceRange(LParenLoc, RParenLoc));
3337 }
3338
3339 /// Build a new C++ dynamic_cast expression.
3340 ///
3341 /// By default, performs semantic analysis to build the new expression.
3342 /// Subclasses may override this routine to provide different behavior.
3343 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3344 SourceLocation LAngleLoc,
3345 TypeSourceInfo *TInfo,
3346 SourceLocation RAngleLoc,
3347 SourceLocation LParenLoc,
3348 Expr *SubExpr,
3349 SourceLocation RParenLoc) {
3350 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3351 TInfo, SubExpr,
3352 SourceRange(LAngleLoc, RAngleLoc),
3353 SourceRange(LParenLoc, RParenLoc));
3354 }
3355
3356 /// Build a new C++ reinterpret_cast expression.
3357 ///
3358 /// By default, performs semantic analysis to build the new expression.
3359 /// Subclasses may override this routine to provide different behavior.
3360 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3361 SourceLocation LAngleLoc,
3362 TypeSourceInfo *TInfo,
3363 SourceLocation RAngleLoc,
3364 SourceLocation LParenLoc,
3365 Expr *SubExpr,
3366 SourceLocation RParenLoc) {
3367 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3368 TInfo, SubExpr,
3369 SourceRange(LAngleLoc, RAngleLoc),
3370 SourceRange(LParenLoc, RParenLoc));
3371 }
3372
3373 /// Build a new C++ const_cast expression.
3374 ///
3375 /// By default, performs semantic analysis to build the new expression.
3376 /// Subclasses may override this routine to provide different behavior.
3377 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3378 SourceLocation LAngleLoc,
3379 TypeSourceInfo *TInfo,
3380 SourceLocation RAngleLoc,
3381 SourceLocation LParenLoc,
3382 Expr *SubExpr,
3383 SourceLocation RParenLoc) {
3384 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3385 TInfo, SubExpr,
3386 SourceRange(LAngleLoc, RAngleLoc),
3387 SourceRange(LParenLoc, RParenLoc));
3388 }
3389
3390 ExprResult
3391 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3392 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3393 SourceLocation LParenLoc, Expr *SubExpr,
3394 SourceLocation RParenLoc) {
3395 return getSema().BuildCXXNamedCast(
3396 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3397 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3398 }
3399
3400 /// Build a new C++ functional-style cast expression.
3401 ///
3402 /// By default, performs semantic analysis to build the new expression.
3403 /// Subclasses may override this routine to provide different behavior.
3404 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3405 SourceLocation LParenLoc,
3406 Expr *Sub,
3407 SourceLocation RParenLoc,
3408 bool ListInitialization) {
3409 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3410 // CXXParenListInitExpr. Pass its expanded arguments so that the
3411 // CXXParenListInitExpr can be rebuilt.
3412 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3413 return getSema().BuildCXXTypeConstructExpr(
3414 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3415 RParenLoc, ListInitialization);
3416
3417 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3418 return getSema().BuildCXXTypeConstructExpr(
3419 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3420
3421 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3422 MultiExprArg(&Sub, 1), RParenLoc,
3423 ListInitialization);
3424 }
3425
3426 /// Build a new C++ __builtin_bit_cast expression.
3427 ///
3428 /// By default, performs semantic analysis to build the new expression.
3429 /// Subclasses may override this routine to provide different behavior.
3430 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3431 TypeSourceInfo *TSI, Expr *Sub,
3432 SourceLocation RParenLoc) {
3433 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3434 }
3435
3436 /// Build a new C++ typeid(type) expression.
3437 ///
3438 /// By default, performs semantic analysis to build the new expression.
3439 /// Subclasses may override this routine to provide different behavior.
3440 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3441 SourceLocation TypeidLoc,
3442 TypeSourceInfo *Operand,
3443 SourceLocation RParenLoc) {
3444 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3445 RParenLoc);
3446 }
3447
3448
3449 /// Build a new C++ typeid(expr) expression.
3450 ///
3451 /// By default, performs semantic analysis to build the new expression.
3452 /// Subclasses may override this routine to provide different behavior.
3453 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3454 SourceLocation TypeidLoc,
3455 Expr *Operand,
3456 SourceLocation RParenLoc) {
3457 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3458 RParenLoc);
3459 }
3460
3461 /// Build a new C++ __uuidof(type) expression.
3462 ///
3463 /// By default, performs semantic analysis to build the new expression.
3464 /// Subclasses may override this routine to provide different behavior.
3465 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3466 TypeSourceInfo *Operand,
3467 SourceLocation RParenLoc) {
3468 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3469 }
3470
3471 /// Build a new C++ __uuidof(expr) expression.
3472 ///
3473 /// By default, performs semantic analysis to build the new expression.
3474 /// Subclasses may override this routine to provide different behavior.
3475 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3476 Expr *Operand, SourceLocation RParenLoc) {
3477 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3478 }
3479
3480 /// Build a new C++ "this" expression.
3481 ///
3482 /// By default, performs semantic analysis to build a new "this" expression.
3483 /// Subclasses may override this routine to provide different behavior.
3484 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3485 QualType ThisType,
3486 bool isImplicit) {
3487 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3488 return ExprError();
3489 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3490 }
3491
3492 /// Build a new C++ throw expression.
3493 ///
3494 /// By default, performs semantic analysis to build the new expression.
3495 /// Subclasses may override this routine to provide different behavior.
3496 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3497 bool IsThrownVariableInScope) {
3498 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3499 }
3500
3501 /// Build a new C++ default-argument expression.
3502 ///
3503 /// By default, builds a new default-argument expression, which does not
3504 /// require any semantic analysis. Subclasses may override this routine to
3505 /// provide different behavior.
3506 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3507 Expr *RewrittenExpr) {
3508 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3509 RewrittenExpr, UsedContext: getSema().CurContext);
3510 }
3511
3512 /// Build a new C++11 default-initialization expression.
3513 ///
3514 /// By default, builds a new default field initialization expression, which
3515 /// does not require any semantic analysis. Subclasses may override this
3516 /// routine to provide different behavior.
3517 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3518 FieldDecl *Field) {
3519 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3520 }
3521
3522 /// Build a new C++ zero-initialization expression.
3523 ///
3524 /// By default, performs semantic analysis to build the new expression.
3525 /// Subclasses may override this routine to provide different behavior.
3526 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3527 SourceLocation LParenLoc,
3528 SourceLocation RParenLoc) {
3529 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3530 /*ListInitialization=*/false);
3531 }
3532
3533 /// Build a new C++ "new" expression.
3534 ///
3535 /// By default, performs semantic analysis to build the new expression.
3536 /// Subclasses may override this routine to provide different behavior.
3537 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3538 SourceLocation PlacementLParen,
3539 MultiExprArg PlacementArgs,
3540 SourceLocation PlacementRParen,
3541 SourceRange TypeIdParens, QualType AllocatedType,
3542 TypeSourceInfo *AllocatedTypeInfo,
3543 std::optional<Expr *> ArraySize,
3544 SourceRange DirectInitRange, Expr *Initializer) {
3545 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3546 PlacementLParen,
3547 PlacementArgs,
3548 PlacementRParen,
3549 TypeIdParens,
3550 AllocatedType,
3551 AllocatedTypeInfo,
3552 ArraySize,
3553 DirectInitRange,
3554 Initializer);
3555 }
3556
3557 /// Build a new C++ "delete" expression.
3558 ///
3559 /// By default, performs semantic analysis to build the new expression.
3560 /// Subclasses may override this routine to provide different behavior.
3561 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3562 bool IsGlobalDelete,
3563 bool IsArrayForm,
3564 Expr *Operand) {
3565 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3566 Operand);
3567 }
3568
3569 /// Build a new type trait expression.
3570 ///
3571 /// By default, performs semantic analysis to build the new expression.
3572 /// Subclasses may override this routine to provide different behavior.
3573 ExprResult RebuildTypeTrait(TypeTrait Trait,
3574 SourceLocation StartLoc,
3575 ArrayRef<TypeSourceInfo *> Args,
3576 SourceLocation RParenLoc) {
3577 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3578 }
3579
3580 /// Build a new array type trait expression.
3581 ///
3582 /// By default, performs semantic analysis to build the new expression.
3583 /// Subclasses may override this routine to provide different behavior.
3584 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3585 SourceLocation StartLoc,
3586 TypeSourceInfo *TSInfo,
3587 Expr *DimExpr,
3588 SourceLocation RParenLoc) {
3589 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3590 }
3591
3592 /// Build a new expression trait expression.
3593 ///
3594 /// By default, performs semantic analysis to build the new expression.
3595 /// Subclasses may override this routine to provide different behavior.
3596 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3597 SourceLocation StartLoc,
3598 Expr *Queried,
3599 SourceLocation RParenLoc) {
3600 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3601 }
3602
3603 /// Build a new (previously unresolved) declaration reference
3604 /// expression.
3605 ///
3606 /// By default, performs semantic analysis to build the new expression.
3607 /// Subclasses may override this routine to provide different behavior.
3608 ExprResult RebuildDependentScopeDeclRefExpr(
3609 NestedNameSpecifierLoc QualifierLoc,
3610 SourceLocation TemplateKWLoc,
3611 const DeclarationNameInfo &NameInfo,
3612 const TemplateArgumentListInfo *TemplateArgs,
3613 bool IsAddressOfOperand,
3614 TypeSourceInfo **RecoveryTSI) {
3615 CXXScopeSpec SS;
3616 SS.Adopt(Other: QualifierLoc);
3617
3618 if (TemplateArgs || TemplateKWLoc.isValid())
3619 return getSema().BuildQualifiedTemplateIdExpr(
3620 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3621
3622 return getSema().BuildQualifiedDeclarationNameExpr(
3623 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3624 }
3625
3626 /// Build a new template-id expression.
3627 ///
3628 /// By default, performs semantic analysis to build the new expression.
3629 /// Subclasses may override this routine to provide different behavior.
3630 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3631 SourceLocation TemplateKWLoc,
3632 LookupResult &R,
3633 bool RequiresADL,
3634 const TemplateArgumentListInfo *TemplateArgs) {
3635 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3636 TemplateArgs);
3637 }
3638
3639 /// Build a new object-construction expression.
3640 ///
3641 /// By default, performs semantic analysis to build the new expression.
3642 /// Subclasses may override this routine to provide different behavior.
3643 ExprResult RebuildCXXConstructExpr(
3644 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3645 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3646 bool ListInitialization, bool StdInitListInitialization,
3647 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3648 SourceRange ParenRange) {
3649 // Reconstruct the constructor we originally found, which might be
3650 // different if this is a call to an inherited constructor.
3651 CXXConstructorDecl *FoundCtor = Constructor;
3652 if (Constructor->isInheritingConstructor())
3653 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3654
3655 SmallVector<Expr *, 8> ConvertedArgs;
3656 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3657 ConvertedArgs))
3658 return ExprError();
3659
3660 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3661 IsElidable,
3662 ConvertedArgs,
3663 HadMultipleCandidates,
3664 ListInitialization,
3665 StdInitListInitialization,
3666 RequiresZeroInit, ConstructKind,
3667 ParenRange);
3668 }
3669
3670 /// Build a new implicit construction via inherited constructor
3671 /// expression.
3672 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3673 CXXConstructorDecl *Constructor,
3674 bool ConstructsVBase,
3675 bool InheritedFromVBase) {
3676 return new (getSema().Context) CXXInheritedCtorInitExpr(
3677 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3678 }
3679
3680 /// Build a new object-construction expression.
3681 ///
3682 /// By default, performs semantic analysis to build the new expression.
3683 /// Subclasses may override this routine to provide different behavior.
3684 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3685 SourceLocation LParenOrBraceLoc,
3686 MultiExprArg Args,
3687 SourceLocation RParenOrBraceLoc,
3688 bool ListInitialization) {
3689 return getSema().BuildCXXTypeConstructExpr(
3690 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3691 }
3692
3693 /// Build a new object-construction expression.
3694 ///
3695 /// By default, performs semantic analysis to build the new expression.
3696 /// Subclasses may override this routine to provide different behavior.
3697 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3698 SourceLocation LParenLoc,
3699 MultiExprArg Args,
3700 SourceLocation RParenLoc,
3701 bool ListInitialization) {
3702 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3703 RParenLoc, ListInitialization);
3704 }
3705
3706 /// Build a new member reference expression.
3707 ///
3708 /// By default, performs semantic analysis to build the new expression.
3709 /// Subclasses may override this routine to provide different behavior.
3710 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3711 QualType BaseType,
3712 bool IsArrow,
3713 SourceLocation OperatorLoc,
3714 NestedNameSpecifierLoc QualifierLoc,
3715 SourceLocation TemplateKWLoc,
3716 NamedDecl *FirstQualifierInScope,
3717 const DeclarationNameInfo &MemberNameInfo,
3718 const TemplateArgumentListInfo *TemplateArgs) {
3719 CXXScopeSpec SS;
3720 SS.Adopt(Other: QualifierLoc);
3721
3722 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3723 OpLoc: OperatorLoc, IsArrow,
3724 SS, TemplateKWLoc,
3725 FirstQualifierInScope,
3726 NameInfo: MemberNameInfo,
3727 TemplateArgs, /*S*/S: nullptr);
3728 }
3729
3730 /// Build a new member reference expression.
3731 ///
3732 /// By default, performs semantic analysis to build the new expression.
3733 /// Subclasses may override this routine to provide different behavior.
3734 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3735 SourceLocation OperatorLoc,
3736 bool IsArrow,
3737 NestedNameSpecifierLoc QualifierLoc,
3738 SourceLocation TemplateKWLoc,
3739 NamedDecl *FirstQualifierInScope,
3740 LookupResult &R,
3741 const TemplateArgumentListInfo *TemplateArgs) {
3742 CXXScopeSpec SS;
3743 SS.Adopt(Other: QualifierLoc);
3744
3745 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3746 OpLoc: OperatorLoc, IsArrow,
3747 SS, TemplateKWLoc,
3748 FirstQualifierInScope,
3749 R, TemplateArgs, /*S*/S: nullptr);
3750 }
3751
3752 /// Build a new noexcept expression.
3753 ///
3754 /// By default, performs semantic analysis to build the new expression.
3755 /// Subclasses may override this routine to provide different behavior.
3756 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3757 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3758 }
3759
3760 UnsignedOrNone
3761 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3762
3763 /// Build a new expression to compute the length of a parameter pack.
3764 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3765 SourceLocation PackLoc,
3766 SourceLocation RParenLoc,
3767 UnsignedOrNone Length,
3768 ArrayRef<TemplateArgument> PartialArgs) {
3769 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3770 RParenLoc, Length, PartialArgs);
3771 }
3772
3773 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3774 SourceLocation RSquareLoc,
3775 Expr *PackIdExpression, Expr *IndexExpr,
3776 ArrayRef<Expr *> ExpandedExprs,
3777 bool FullySubstituted = false) {
3778 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3779 IndexExpr, RSquareLoc, ExpandedExprs,
3780 FullySubstituted);
3781 }
3782
3783 /// Build a new expression representing a call to a source location
3784 /// builtin.
3785 ///
3786 /// By default, performs semantic analysis to build the new expression.
3787 /// Subclasses may override this routine to provide different behavior.
3788 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3789 SourceLocation BuiltinLoc,
3790 SourceLocation RPLoc,
3791 DeclContext *ParentContext) {
3792 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3793 ParentContext);
3794 }
3795
3796 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3797 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3798 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3799 TemplateArgumentListInfo *TALI) {
3800 CXXScopeSpec SS;
3801 SS.Adopt(Other: NNS);
3802 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3803 ConceptNameInfo,
3804 FoundDecl,
3805 NamedConcept, TALI);
3806 if (Result.isInvalid())
3807 return ExprError();
3808 return Result;
3809 }
3810
3811 /// \brief Build a new requires expression.
3812 ///
3813 /// By default, performs semantic analysis to build the new expression.
3814 /// Subclasses may override this routine to provide different behavior.
3815 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3816 RequiresExprBodyDecl *Body,
3817 SourceLocation LParenLoc,
3818 ArrayRef<ParmVarDecl *> LocalParameters,
3819 SourceLocation RParenLoc,
3820 ArrayRef<concepts::Requirement *> Requirements,
3821 SourceLocation ClosingBraceLoc) {
3822 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3823 LocalParameters, RParenLoc, Requirements,
3824 RBraceLoc: ClosingBraceLoc);
3825 }
3826
3827 concepts::TypeRequirement *
3828 RebuildTypeRequirement(
3829 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3830 return SemaRef.BuildTypeRequirement(SubstDiag);
3831 }
3832
3833 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3834 return SemaRef.BuildTypeRequirement(Type: T);
3835 }
3836
3837 concepts::ExprRequirement *
3838 RebuildExprRequirement(
3839 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3840 SourceLocation NoexceptLoc,
3841 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3842 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3843 ReturnTypeRequirement: std::move(Ret));
3844 }
3845
3846 concepts::ExprRequirement *
3847 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3848 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3849 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3850 ReturnTypeRequirement: std::move(Ret));
3851 }
3852
3853 concepts::NestedRequirement *
3854 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3855 const ASTConstraintSatisfaction &Satisfaction) {
3856 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3857 Satisfaction);
3858 }
3859
3860 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3861 return SemaRef.BuildNestedRequirement(E: Constraint);
3862 }
3863
3864 /// \brief Build a new Objective-C boxed expression.
3865 ///
3866 /// By default, performs semantic analysis to build the new expression.
3867 /// Subclasses may override this routine to provide different behavior.
3868 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3869 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3870 }
3871
3872 /// Build a new Objective-C array literal.
3873 ///
3874 /// By default, performs semantic analysis to build the new expression.
3875 /// Subclasses may override this routine to provide different behavior.
3876 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3877 Expr **Elements, unsigned NumElements) {
3878 return getSema().ObjC().BuildObjCArrayLiteral(
3879 Range, MultiExprArg(Elements, NumElements));
3880 }
3881
3882 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3883 Expr *Base, Expr *Key,
3884 ObjCMethodDecl *getterMethod,
3885 ObjCMethodDecl *setterMethod) {
3886 return getSema().ObjC().BuildObjCSubscriptExpression(
3887 RB, Base, Key, getterMethod, setterMethod);
3888 }
3889
3890 /// Build a new Objective-C dictionary literal.
3891 ///
3892 /// By default, performs semantic analysis to build the new expression.
3893 /// Subclasses may override this routine to provide different behavior.
3894 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3895 MutableArrayRef<ObjCDictionaryElement> Elements) {
3896 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3897 }
3898
3899 /// Build a new Objective-C \@encode expression.
3900 ///
3901 /// By default, performs semantic analysis to build the new expression.
3902 /// Subclasses may override this routine to provide different behavior.
3903 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3904 TypeSourceInfo *EncodeTypeInfo,
3905 SourceLocation RParenLoc) {
3906 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3907 RParenLoc);
3908 }
3909
3910 /// Build a new Objective-C class message.
3911 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3912 Selector Sel,
3913 ArrayRef<SourceLocation> SelectorLocs,
3914 ObjCMethodDecl *Method,
3915 SourceLocation LBracLoc,
3916 MultiExprArg Args,
3917 SourceLocation RBracLoc) {
3918 return SemaRef.ObjC().BuildClassMessage(
3919 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3920 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3921 RBracLoc, Args);
3922 }
3923
3924 /// Build a new Objective-C instance message.
3925 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3926 Selector Sel,
3927 ArrayRef<SourceLocation> SelectorLocs,
3928 ObjCMethodDecl *Method,
3929 SourceLocation LBracLoc,
3930 MultiExprArg Args,
3931 SourceLocation RBracLoc) {
3932 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3933 /*SuperLoc=*/SuperLoc: SourceLocation(),
3934 Sel, Method, LBracLoc,
3935 SelectorLocs, RBracLoc, Args);
3936 }
3937
3938 /// Build a new Objective-C instance/class message to 'super'.
3939 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3940 Selector Sel,
3941 ArrayRef<SourceLocation> SelectorLocs,
3942 QualType SuperType,
3943 ObjCMethodDecl *Method,
3944 SourceLocation LBracLoc,
3945 MultiExprArg Args,
3946 SourceLocation RBracLoc) {
3947 return Method->isInstanceMethod()
3948 ? SemaRef.ObjC().BuildInstanceMessage(
3949 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3950 SelectorLocs, RBracLoc, Args)
3951 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3952 Sel, Method, LBracLoc,
3953 SelectorLocs, RBracLoc, Args);
3954 }
3955
3956 /// Build a new Objective-C ivar reference expression.
3957 ///
3958 /// By default, performs semantic analysis to build the new expression.
3959 /// Subclasses may override this routine to provide different behavior.
3960 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3961 SourceLocation IvarLoc,
3962 bool IsArrow, bool IsFreeIvar) {
3963 CXXScopeSpec SS;
3964 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3965 ExprResult Result = getSema().BuildMemberReferenceExpr(
3966 BaseArg, BaseArg->getType(),
3967 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3968 /*FirstQualifierInScope=*/nullptr, NameInfo,
3969 /*TemplateArgs=*/nullptr,
3970 /*S=*/nullptr);
3971 if (IsFreeIvar && Result.isUsable())
3972 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3973 return Result;
3974 }
3975
3976 /// Build a new Objective-C property reference expression.
3977 ///
3978 /// By default, performs semantic analysis to build the new expression.
3979 /// Subclasses may override this routine to provide different behavior.
3980 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3981 ObjCPropertyDecl *Property,
3982 SourceLocation PropertyLoc) {
3983 CXXScopeSpec SS;
3984 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3985 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3986 /*FIXME:*/PropertyLoc,
3987 /*IsArrow=*/false,
3988 SS, SourceLocation(),
3989 /*FirstQualifierInScope=*/nullptr,
3990 NameInfo,
3991 /*TemplateArgs=*/nullptr,
3992 /*S=*/nullptr);
3993 }
3994
3995 /// Build a new Objective-C property reference expression.
3996 ///
3997 /// By default, performs semantic analysis to build the new expression.
3998 /// Subclasses may override this routine to provide different behavior.
3999 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
4000 ObjCMethodDecl *Getter,
4001 ObjCMethodDecl *Setter,
4002 SourceLocation PropertyLoc) {
4003 // Since these expressions can only be value-dependent, we do not
4004 // need to perform semantic analysis again.
4005 return Owned(
4006 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
4007 VK_LValue, OK_ObjCProperty,
4008 PropertyLoc, Base));
4009 }
4010
4011 /// Build a new Objective-C "isa" expression.
4012 ///
4013 /// By default, performs semantic analysis to build the new expression.
4014 /// Subclasses may override this routine to provide different behavior.
4015 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
4016 SourceLocation OpLoc, bool IsArrow) {
4017 CXXScopeSpec SS;
4018 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
4019 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
4020 OpLoc, IsArrow,
4021 SS, SourceLocation(),
4022 /*FirstQualifierInScope=*/nullptr,
4023 NameInfo,
4024 /*TemplateArgs=*/nullptr,
4025 /*S=*/nullptr);
4026 }
4027
4028 /// Build a new shuffle vector expression.
4029 ///
4030 /// By default, performs semantic analysis to build the new expression.
4031 /// Subclasses may override this routine to provide different behavior.
4032 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
4033 MultiExprArg SubExprs,
4034 SourceLocation RParenLoc) {
4035 // Find the declaration for __builtin_shufflevector
4036 const IdentifierInfo &Name
4037 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
4038 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
4039 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
4040 assert(!Lookup.empty() && "No __builtin_shufflevector?");
4041
4042 // Build a reference to the __builtin_shufflevector builtin
4043 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
4044 Expr *Callee = new (SemaRef.Context)
4045 DeclRefExpr(SemaRef.Context, Builtin, false,
4046 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
4047 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
4048 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
4049 CK: CK_BuiltinFnToFnPtr).get();
4050
4051 // Build the CallExpr
4052 ExprResult TheCall = CallExpr::Create(
4053 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
4054 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
4055 FPFeatures: FPOptionsOverride());
4056
4057 // Type-check the __builtin_shufflevector expression.
4058 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
4059 }
4060
4061 /// Build a new convert vector expression.
4062 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
4063 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
4064 SourceLocation RParenLoc) {
4065 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
4066 }
4067
4068 /// Build a new template argument pack expansion.
4069 ///
4070 /// By default, performs semantic analysis to build a new pack expansion
4071 /// for a template argument. Subclasses may override this routine to provide
4072 /// different behavior.
4073 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
4074 SourceLocation EllipsisLoc,
4075 UnsignedOrNone NumExpansions) {
4076 switch (Pattern.getArgument().getKind()) {
4077 case TemplateArgument::Expression: {
4078 ExprResult Result
4079 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
4080 EllipsisLoc, NumExpansions);
4081 if (Result.isInvalid())
4082 return TemplateArgumentLoc();
4083
4084 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4085 /*IsCanonical=*/false),
4086 Result.get());
4087 }
4088
4089 case TemplateArgument::Template:
4090 return TemplateArgumentLoc(
4091 SemaRef.Context,
4092 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4093 NumExpansions),
4094 Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
4095 Pattern.getTemplateNameLoc(), EllipsisLoc);
4096
4097 case TemplateArgument::Null:
4098 case TemplateArgument::Integral:
4099 case TemplateArgument::Declaration:
4100 case TemplateArgument::StructuralValue:
4101 case TemplateArgument::Pack:
4102 case TemplateArgument::TemplateExpansion:
4103 case TemplateArgument::NullPtr:
4104 llvm_unreachable("Pack expansion pattern has no parameter packs");
4105
4106 case TemplateArgument::Type:
4107 if (TypeSourceInfo *Expansion
4108 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4109 EllipsisLoc,
4110 NumExpansions))
4111 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4112 Expansion);
4113 break;
4114 }
4115
4116 return TemplateArgumentLoc();
4117 }
4118
4119 /// Build a new expression pack expansion.
4120 ///
4121 /// By default, performs semantic analysis to build a new pack expansion
4122 /// for an expression. Subclasses may override this routine to provide
4123 /// different behavior.
4124 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4125 UnsignedOrNone NumExpansions) {
4126 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4127 }
4128
4129 /// Build a new C++1z fold-expression.
4130 ///
4131 /// By default, performs semantic analysis in order to build a new fold
4132 /// expression.
4133 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4134 SourceLocation LParenLoc, Expr *LHS,
4135 BinaryOperatorKind Operator,
4136 SourceLocation EllipsisLoc, Expr *RHS,
4137 SourceLocation RParenLoc,
4138 UnsignedOrNone NumExpansions) {
4139 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4140 EllipsisLoc, RHS, RParenLoc,
4141 NumExpansions);
4142 }
4143
4144 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4145 LambdaScopeInfo *LSI) {
4146 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4147 if (Expr *Init = PVD->getInit())
4148 LSI->ContainsUnexpandedParameterPack |=
4149 Init->containsUnexpandedParameterPack();
4150 else if (PVD->hasUninstantiatedDefaultArg())
4151 LSI->ContainsUnexpandedParameterPack |=
4152 PVD->getUninstantiatedDefaultArg()
4153 ->containsUnexpandedParameterPack();
4154 }
4155 return getSema().BuildLambdaExpr(StartLoc, EndLoc);
4156 }
4157
4158 /// Build an empty C++1z fold-expression with the given operator.
4159 ///
4160 /// By default, produces the fallback value for the fold-expression, or
4161 /// produce an error if there is no fallback value.
4162 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4163 BinaryOperatorKind Operator) {
4164 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4165 }
4166
4167 /// Build a new atomic operation expression.
4168 ///
4169 /// By default, performs semantic analysis to build the new expression.
4170 /// Subclasses may override this routine to provide different behavior.
4171 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4172 AtomicExpr::AtomicOp Op,
4173 SourceLocation RParenLoc) {
4174 // Use this for all of the locations, since we don't know the difference
4175 // between the call and the expr at this point.
4176 SourceRange Range{BuiltinLoc, RParenLoc};
4177 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4178 Sema::AtomicArgumentOrder::AST);
4179 }
4180
4181 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4182 ArrayRef<Expr *> SubExprs, QualType Type) {
4183 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4184 }
4185
4186 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4187 SourceLocation BeginLoc,
4188 SourceLocation DirLoc,
4189 SourceLocation EndLoc,
4190 ArrayRef<OpenACCClause *> Clauses,
4191 StmtResult StrBlock) {
4192 return getSema().OpenACC().ActOnEndStmtDirective(
4193 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4194 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4195 }
4196
4197 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4198 SourceLocation DirLoc,
4199 SourceLocation EndLoc,
4200 ArrayRef<OpenACCClause *> Clauses,
4201 StmtResult Loop) {
4202 return getSema().OpenACC().ActOnEndStmtDirective(
4203 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4204 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4205 Clauses, Loop);
4206 }
4207
4208 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4209 SourceLocation BeginLoc,
4210 SourceLocation DirLoc,
4211 SourceLocation EndLoc,
4212 ArrayRef<OpenACCClause *> Clauses,
4213 StmtResult Loop) {
4214 return getSema().OpenACC().ActOnEndStmtDirective(
4215 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4216 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4217 }
4218
4219 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4220 SourceLocation DirLoc,
4221 SourceLocation EndLoc,
4222 ArrayRef<OpenACCClause *> Clauses,
4223 StmtResult StrBlock) {
4224 return getSema().OpenACC().ActOnEndStmtDirective(
4225 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4226 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4227 Clauses, StrBlock);
4228 }
4229
4230 StmtResult
4231 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4232 SourceLocation DirLoc, SourceLocation EndLoc,
4233 ArrayRef<OpenACCClause *> Clauses) {
4234 return getSema().OpenACC().ActOnEndStmtDirective(
4235 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4236 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4237 Clauses, {});
4238 }
4239
4240 StmtResult
4241 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4242 SourceLocation DirLoc, SourceLocation EndLoc,
4243 ArrayRef<OpenACCClause *> Clauses) {
4244 return getSema().OpenACC().ActOnEndStmtDirective(
4245 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4246 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4247 Clauses, {});
4248 }
4249
4250 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4251 SourceLocation DirLoc,
4252 SourceLocation EndLoc,
4253 ArrayRef<OpenACCClause *> Clauses,
4254 StmtResult StrBlock) {
4255 return getSema().OpenACC().ActOnEndStmtDirective(
4256 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4257 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4258 Clauses, StrBlock);
4259 }
4260
4261 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4262 SourceLocation DirLoc,
4263 SourceLocation EndLoc,
4264 ArrayRef<OpenACCClause *> Clauses) {
4265 return getSema().OpenACC().ActOnEndStmtDirective(
4266 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4267 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4268 Clauses, {});
4269 }
4270
4271 StmtResult
4272 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4273 SourceLocation DirLoc, SourceLocation EndLoc,
4274 ArrayRef<OpenACCClause *> Clauses) {
4275 return getSema().OpenACC().ActOnEndStmtDirective(
4276 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4277 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4278 Clauses, {});
4279 }
4280
4281 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4282 SourceLocation DirLoc,
4283 SourceLocation EndLoc,
4284 ArrayRef<OpenACCClause *> Clauses) {
4285 return getSema().OpenACC().ActOnEndStmtDirective(
4286 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4287 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4288 Clauses, {});
4289 }
4290
4291 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4292 SourceLocation DirLoc,
4293 SourceLocation EndLoc,
4294 ArrayRef<OpenACCClause *> Clauses) {
4295 return getSema().OpenACC().ActOnEndStmtDirective(
4296 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4297 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4298 Clauses, {});
4299 }
4300
4301 StmtResult RebuildOpenACCWaitConstruct(
4302 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4303 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4304 SourceLocation RParenLoc, SourceLocation EndLoc,
4305 ArrayRef<OpenACCClause *> Clauses) {
4306 llvm::SmallVector<Expr *> Exprs;
4307 Exprs.push_back(Elt: DevNumExpr);
4308 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4309 return getSema().OpenACC().ActOnEndStmtDirective(
4310 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4311 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4312 }
4313
4314 StmtResult RebuildOpenACCCacheConstruct(
4315 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4316 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4317 SourceLocation RParenLoc, SourceLocation EndLoc) {
4318 return getSema().OpenACC().ActOnEndStmtDirective(
4319 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4320 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4321 }
4322
4323 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4324 SourceLocation DirLoc,
4325 OpenACCAtomicKind AtKind,
4326 SourceLocation EndLoc,
4327 ArrayRef<OpenACCClause *> Clauses,
4328 StmtResult AssociatedStmt) {
4329 return getSema().OpenACC().ActOnEndStmtDirective(
4330 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4331 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4332 AssociatedStmt);
4333 }
4334
4335 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4336 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4337 }
4338
4339 ExprResult
4340 RebuildSubstNonTypeTemplateParmExpr(Decl *AssociatedDecl, unsigned Index,
4341 QualType ParamType, SourceLocation Loc,
4342 TemplateArgument Arg,
4343 UnsignedOrNone PackIndex, bool Final) {
4344 return getSema().BuildSubstNonTypeTemplateParmExpr(
4345 AssociatedDecl, Index, ParamType, Loc, Arg, PackIndex, Final);
4346 }
4347
4348 OMPClause *RebuildOpenMPTransparentClause(Expr *ImpexType,
4349 SourceLocation StartLoc,
4350 SourceLocation LParenLoc,
4351 SourceLocation EndLoc) {
4352 return getSema().OpenMP().ActOnOpenMPTransparentClause(ImpexType, StartLoc,
4353 LParenLoc, EndLoc);
4354 }
4355
4356private:
4357 QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
4358 QualType ObjectType,
4359 NamedDecl *FirstQualifierInScope);
4360
4361 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4362 QualType ObjectType,
4363 NamedDecl *FirstQualifierInScope) {
4364 if (getDerived().AlreadyTransformed(TSInfo->getType()))
4365 return TSInfo;
4366
4367 TypeLocBuilder TLB;
4368 QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
4369 ObjectType, FirstQualifierInScope);
4370 if (T.isNull())
4371 return nullptr;
4372 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T);
4373 }
4374
4375 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4376 DependentNameTypeLoc TL,
4377 bool DeducibleTSTContext,
4378 QualType ObjectType = QualType(),
4379 NamedDecl *UnqualLookup = nullptr);
4380
4381 llvm::SmallVector<OpenACCClause *>
4382 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4383 ArrayRef<const OpenACCClause *> OldClauses);
4384
4385 OpenACCClause *
4386 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4387 OpenACCDirectiveKind DirKind,
4388 const OpenACCClause *OldClause);
4389};
4390
4391template <typename Derived>
4392StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4393 if (!S)
4394 return S;
4395
4396 switch (S->getStmtClass()) {
4397 case Stmt::NoStmtClass: break;
4398
4399 // Transform individual statement nodes
4400 // Pass SDK into statements that can produce a value
4401#define STMT(Node, Parent) \
4402 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4403#define VALUESTMT(Node, Parent) \
4404 case Stmt::Node##Class: \
4405 return getDerived().Transform##Node(cast<Node>(S), SDK);
4406#define ABSTRACT_STMT(Node)
4407#define EXPR(Node, Parent)
4408#include "clang/AST/StmtNodes.inc"
4409
4410 // Transform expressions by calling TransformExpr.
4411#define STMT(Node, Parent)
4412#define ABSTRACT_STMT(Stmt)
4413#define EXPR(Node, Parent) case Stmt::Node##Class:
4414#include "clang/AST/StmtNodes.inc"
4415 {
4416 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4417
4418 if (SDK == StmtDiscardKind::StmtExprResult)
4419 E = getSema().ActOnStmtExprResult(E);
4420 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4421 }
4422 }
4423
4424 return S;
4425}
4426
4427template<typename Derived>
4428OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4429 if (!S)
4430 return S;
4431
4432 switch (S->getClauseKind()) {
4433 default: break;
4434 // Transform individual clause nodes
4435#define GEN_CLANG_CLAUSE_CLASS
4436#define CLAUSE_CLASS(Enum, Str, Class) \
4437 case Enum: \
4438 return getDerived().Transform##Class(cast<Class>(S));
4439#include "llvm/Frontend/OpenMP/OMP.inc"
4440 }
4441
4442 return S;
4443}
4444
4445
4446template<typename Derived>
4447ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4448 if (!E)
4449 return E;
4450
4451 switch (E->getStmtClass()) {
4452 case Stmt::NoStmtClass: break;
4453#define STMT(Node, Parent) case Stmt::Node##Class: break;
4454#define ABSTRACT_STMT(Stmt)
4455#define EXPR(Node, Parent) \
4456 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4457#include "clang/AST/StmtNodes.inc"
4458 }
4459
4460 return E;
4461}
4462
4463template<typename Derived>
4464ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4465 bool NotCopyInit) {
4466 // Initializers are instantiated like expressions, except that various outer
4467 // layers are stripped.
4468 if (!Init)
4469 return Init;
4470
4471 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4472 Init = FE->getSubExpr();
4473
4474 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4475 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4476 Init = OVE->getSourceExpr();
4477 }
4478
4479 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4480 Init = MTE->getSubExpr();
4481
4482 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4483 Init = Binder->getSubExpr();
4484
4485 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4486 Init = ICE->getSubExprAsWritten();
4487
4488 if (CXXStdInitializerListExpr *ILE =
4489 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4490 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4491
4492 // If this is copy-initialization, we only need to reconstruct
4493 // InitListExprs. Other forms of copy-initialization will be a no-op if
4494 // the initializer is already the right type.
4495 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4496 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4497 return getDerived().TransformExpr(Init);
4498
4499 // Revert value-initialization back to empty parens.
4500 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4501 SourceRange Parens = VIE->getSourceRange();
4502 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4503 Parens.getEnd());
4504 }
4505
4506 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4507 if (isa<ImplicitValueInitExpr>(Val: Init))
4508 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4509 SourceLocation());
4510
4511 // Revert initialization by constructor back to a parenthesized or braced list
4512 // of expressions. Any other form of initializer can just be reused directly.
4513 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4514 return getDerived().TransformExpr(Init);
4515
4516 // If the initialization implicitly converted an initializer list to a
4517 // std::initializer_list object, unwrap the std::initializer_list too.
4518 if (Construct && Construct->isStdInitListInitialization())
4519 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4520
4521 // Enter a list-init context if this was list initialization.
4522 EnterExpressionEvaluationContext Context(
4523 getSema(), EnterExpressionEvaluationContext::InitList,
4524 Construct->isListInitialization());
4525
4526 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4527 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4528 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4529 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4530 SmallVector<Expr*, 8> NewArgs;
4531 bool ArgChanged = false;
4532 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4533 /*IsCall*/true, NewArgs, &ArgChanged))
4534 return ExprError();
4535
4536 // If this was list initialization, revert to syntactic list form.
4537 if (Construct->isListInitialization())
4538 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4539 Construct->getEndLoc(),
4540 /*IsExplicit=*/true);
4541
4542 // Build a ParenListExpr to represent anything else.
4543 SourceRange Parens = Construct->getParenOrBraceRange();
4544 if (Parens.isInvalid()) {
4545 // This was a variable declaration's initialization for which no initializer
4546 // was specified.
4547 assert(NewArgs.empty() &&
4548 "no parens or braces but have direct init with arguments?");
4549 return ExprEmpty();
4550 }
4551 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4552 Parens.getEnd());
4553}
4554
4555template<typename Derived>
4556bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4557 unsigned NumInputs,
4558 bool IsCall,
4559 SmallVectorImpl<Expr *> &Outputs,
4560 bool *ArgChanged) {
4561 for (unsigned I = 0; I != NumInputs; ++I) {
4562 // If requested, drop call arguments that need to be dropped.
4563 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4564 if (ArgChanged)
4565 *ArgChanged = true;
4566
4567 break;
4568 }
4569
4570 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4571 Expr *Pattern = Expansion->getPattern();
4572
4573 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4574 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4575 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4576
4577 // Determine whether the set of unexpanded parameter packs can and should
4578 // be expanded.
4579 bool Expand = true;
4580 bool RetainExpansion = false;
4581 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4582 UnsignedOrNone NumExpansions = OrigNumExpansions;
4583 if (getDerived().TryExpandParameterPacks(
4584 Expansion->getEllipsisLoc(), Pattern->getSourceRange(),
4585 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
4586 RetainExpansion, NumExpansions))
4587 return true;
4588
4589 if (!Expand) {
4590 // The transform has determined that we should perform a simple
4591 // transformation on the pack expansion, producing another pack
4592 // expansion.
4593 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4594 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4595 if (OutPattern.isInvalid())
4596 return true;
4597
4598 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4599 Expansion->getEllipsisLoc(),
4600 NumExpansions);
4601 if (Out.isInvalid())
4602 return true;
4603
4604 if (ArgChanged)
4605 *ArgChanged = true;
4606 Outputs.push_back(Elt: Out.get());
4607 continue;
4608 }
4609
4610 // Record right away that the argument was changed. This needs
4611 // to happen even if the array expands to nothing.
4612 if (ArgChanged) *ArgChanged = true;
4613
4614 // The transform has determined that we should perform an elementwise
4615 // expansion of the pattern. Do so.
4616 for (unsigned I = 0; I != *NumExpansions; ++I) {
4617 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4618 ExprResult Out = getDerived().TransformExpr(Pattern);
4619 if (Out.isInvalid())
4620 return true;
4621
4622 if (Out.get()->containsUnexpandedParameterPack()) {
4623 Out = getDerived().RebuildPackExpansion(
4624 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4625 if (Out.isInvalid())
4626 return true;
4627 }
4628
4629 Outputs.push_back(Elt: Out.get());
4630 }
4631
4632 // If we're supposed to retain a pack expansion, do so by temporarily
4633 // forgetting the partially-substituted parameter pack.
4634 if (RetainExpansion) {
4635 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4636
4637 ExprResult Out = getDerived().TransformExpr(Pattern);
4638 if (Out.isInvalid())
4639 return true;
4640
4641 Out = getDerived().RebuildPackExpansion(
4642 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4643 if (Out.isInvalid())
4644 return true;
4645
4646 Outputs.push_back(Elt: Out.get());
4647 }
4648
4649 continue;
4650 }
4651
4652 ExprResult Result =
4653 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4654 : getDerived().TransformExpr(Inputs[I]);
4655 if (Result.isInvalid())
4656 return true;
4657
4658 if (Result.get() != Inputs[I] && ArgChanged)
4659 *ArgChanged = true;
4660
4661 Outputs.push_back(Elt: Result.get());
4662 }
4663
4664 return false;
4665}
4666
4667template <typename Derived>
4668Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4669 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4670
4671 EnterExpressionEvaluationContext Eval(
4672 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4673 /*LambdaContextDecl=*/nullptr,
4674 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4675 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4676
4677 if (Var) {
4678 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4679 getDerived().TransformDefinition(Var->getLocation(), Var));
4680
4681 if (!ConditionVar)
4682 return Sema::ConditionError();
4683
4684 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4685 }
4686
4687 if (Expr) {
4688 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4689
4690 if (CondExpr.isInvalid())
4691 return Sema::ConditionError();
4692
4693 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4694 /*MissingOK=*/true);
4695 }
4696
4697 return Sema::ConditionResult();
4698}
4699
4700template <typename Derived>
4701NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4702 NestedNameSpecifierLoc NNS, QualType ObjectType,
4703 NamedDecl *FirstQualifierInScope) {
4704 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4705
4706 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4707 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4708 Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
4709 Qualifiers.push_back(Elt: Qualifier);
4710 };
4711 insertNNS(NNS);
4712
4713 CXXScopeSpec SS;
4714 while (!Qualifiers.empty()) {
4715 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4716 NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
4717
4718 switch (QNNS.getKind()) {
4719 case NestedNameSpecifier::Kind::Null:
4720 llvm_unreachable("unexpected null nested name specifier");
4721
4722 case NestedNameSpecifier::Kind::Namespace: {
4723 auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
4724 Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
4725 QNNS.getAsNamespaceAndPrefix().Namespace)));
4726 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4727 break;
4728 }
4729
4730 case NestedNameSpecifier::Kind::Global:
4731 // There is no meaningful transformation that one could perform on the
4732 // global scope.
4733 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4734 break;
4735
4736 case NestedNameSpecifier::Kind::MicrosoftSuper: {
4737 CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
4738 getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
4739 SS.MakeMicrosoftSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(),
4740 ColonColonLoc: Q.getEndLoc());
4741 break;
4742 }
4743
4744 case NestedNameSpecifier::Kind::Type: {
4745 assert(SS.isEmpty());
4746 TypeLoc TL = Q.castAsTypeLoc();
4747
4748 if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
4749 NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
4750 if (QualifierLoc) {
4751 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4752 QualifierLoc, ObjectType, FirstQualifierInScope);
4753 if (!QualifierLoc)
4754 return NestedNameSpecifierLoc();
4755 ObjectType = QualType();
4756 FirstQualifierInScope = nullptr;
4757 }
4758 SS.Adopt(Other: QualifierLoc);
4759 Sema::NestedNameSpecInfo IdInfo(
4760 const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
4761 DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
4762 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo,
4763 EnteringContext: false, SS,
4764 ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4765 return NestedNameSpecifierLoc();
4766 return SS.getWithLocInContext(Context&: SemaRef.Context);
4767 }
4768
4769 QualType T = TL.getType();
4770 TypeLocBuilder TLB;
4771 if (!getDerived().AlreadyTransformed(T)) {
4772 T = TransformTypeInObjectScope(TLB, TL, ObjectType,
4773 FirstQualifierInScope);
4774 if (T.isNull())
4775 return NestedNameSpecifierLoc();
4776 TL = TLB.getTypeLocInContext(Context&: SemaRef.Context, T);
4777 }
4778
4779 if (T->isDependentType() || T->isRecordType() ||
4780 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4781 if (T->isEnumeralType())
4782 SemaRef.Diag(Loc: TL.getBeginLoc(),
4783 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4784 SS.Make(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4785 break;
4786 }
4787 // If the nested-name-specifier is an invalid type def, don't emit an
4788 // error because a previous error should have already been emitted.
4789 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4790 if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
4791 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4792 << T << SS.getRange();
4793 }
4794 return NestedNameSpecifierLoc();
4795 }
4796 }
4797 }
4798
4799 // Don't rebuild the nested-name-specifier if we don't have to.
4800 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4801 !getDerived().AlwaysRebuild())
4802 return NNS;
4803
4804 // If we can re-use the source-location data from the original
4805 // nested-name-specifier, do so.
4806 if (SS.location_size() == NNS.getDataLength() &&
4807 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4808 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4809
4810 // Allocate new nested-name-specifier location information.
4811 return SS.getWithLocInContext(Context&: SemaRef.Context);
4812}
4813
4814template<typename Derived>
4815DeclarationNameInfo
4816TreeTransform<Derived>
4817::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4818 DeclarationName Name = NameInfo.getName();
4819 if (!Name)
4820 return DeclarationNameInfo();
4821
4822 switch (Name.getNameKind()) {
4823 case DeclarationName::Identifier:
4824 case DeclarationName::ObjCZeroArgSelector:
4825 case DeclarationName::ObjCOneArgSelector:
4826 case DeclarationName::ObjCMultiArgSelector:
4827 case DeclarationName::CXXOperatorName:
4828 case DeclarationName::CXXLiteralOperatorName:
4829 case DeclarationName::CXXUsingDirective:
4830 return NameInfo;
4831
4832 case DeclarationName::CXXDeductionGuideName: {
4833 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4834 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4835 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4836 if (!NewTemplate)
4837 return DeclarationNameInfo();
4838
4839 DeclarationNameInfo NewNameInfo(NameInfo);
4840 NewNameInfo.setName(
4841 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4842 return NewNameInfo;
4843 }
4844
4845 case DeclarationName::CXXConstructorName:
4846 case DeclarationName::CXXDestructorName:
4847 case DeclarationName::CXXConversionFunctionName: {
4848 TypeSourceInfo *NewTInfo;
4849 CanQualType NewCanTy;
4850 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4851 NewTInfo = getDerived().TransformType(OldTInfo);
4852 if (!NewTInfo)
4853 return DeclarationNameInfo();
4854 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4855 }
4856 else {
4857 NewTInfo = nullptr;
4858 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4859 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4860 if (NewT.isNull())
4861 return DeclarationNameInfo();
4862 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4863 }
4864
4865 DeclarationName NewName
4866 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4867 Ty: NewCanTy);
4868 DeclarationNameInfo NewNameInfo(NameInfo);
4869 NewNameInfo.setName(NewName);
4870 NewNameInfo.setNamedTypeInfo(NewTInfo);
4871 return NewNameInfo;
4872 }
4873 }
4874
4875 llvm_unreachable("Unknown name kind.");
4876}
4877
4878template <typename Derived>
4879TemplateName TreeTransform<Derived>::RebuildTemplateName(
4880 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4881 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4882 QualType ObjectType, bool AllowInjectedClassName) {
4883 if (const IdentifierInfo *II = IO.getIdentifier())
4884 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4885 ObjectType, AllowInjectedClassName);
4886 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4887 NameLoc, ObjectType,
4888 AllowInjectedClassName);
4889}
4890
4891template <typename Derived>
4892TemplateName TreeTransform<Derived>::TransformTemplateName(
4893 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
4894 TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
4895 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
4896 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4897 TemplateName UnderlyingName = QTN->getUnderlyingTemplate();
4898
4899 if (QualifierLoc) {
4900 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4901 QualifierLoc, ObjectType, FirstQualifierInScope);
4902 if (!QualifierLoc)
4903 return TemplateName();
4904 }
4905
4906 NestedNameSpecifierLoc UnderlyingQualifier;
4907 TemplateName NewUnderlyingName = getDerived().TransformTemplateName(
4908 UnderlyingQualifier, TemplateKWLoc, UnderlyingName, NameLoc, ObjectType,
4909 FirstQualifierInScope, AllowInjectedClassName);
4910 if (NewUnderlyingName.isNull())
4911 return TemplateName();
4912 assert(!UnderlyingQualifier && "unexpected qualifier");
4913
4914 if (!getDerived().AlwaysRebuild() &&
4915 QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
4916 NewUnderlyingName == UnderlyingName)
4917 return Name;
4918 CXXScopeSpec SS;
4919 SS.Adopt(Other: QualifierLoc);
4920 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4921 NewUnderlyingName);
4922 }
4923
4924 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4925 if (QualifierLoc) {
4926 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
4927 QualifierLoc, ObjectType, FirstQualifierInScope);
4928 if (!QualifierLoc)
4929 return TemplateName();
4930 // The qualifier-in-scope and object type only apply to the leftmost
4931 // entity.
4932 ObjectType = QualType();
4933 }
4934
4935 if (!getDerived().AlwaysRebuild() &&
4936 QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
4937 ObjectType.isNull())
4938 return Name;
4939
4940 CXXScopeSpec SS;
4941 SS.Adopt(Other: QualifierLoc);
4942 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
4943 NameLoc, ObjectType,
4944 AllowInjectedClassName);
4945 }
4946
4947 if (SubstTemplateTemplateParmStorage *S =
4948 Name.getAsSubstTemplateTemplateParm()) {
4949 assert(!QualifierLoc && "Unexpected qualified SubstTemplateTemplateParm");
4950
4951 NestedNameSpecifierLoc ReplacementQualifierLoc;
4952 TemplateName ReplacementName = S->getReplacement();
4953 if (NestedNameSpecifier Qualifier = ReplacementName.getQualifier()) {
4954 NestedNameSpecifierLocBuilder Builder;
4955 Builder.MakeTrivial(Context&: SemaRef.Context, Qualifier, R: NameLoc);
4956 ReplacementQualifierLoc = Builder.getWithLocInContext(Context&: SemaRef.Context);
4957 }
4958
4959 TemplateName NewName = getDerived().TransformTemplateName(
4960 ReplacementQualifierLoc, TemplateKWLoc, ReplacementName, NameLoc,
4961 ObjectType, FirstQualifierInScope, AllowInjectedClassName);
4962 if (NewName.isNull())
4963 return TemplateName();
4964 Decl *AssociatedDecl =
4965 getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
4966 if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
4967 AssociatedDecl == S->getAssociatedDecl())
4968 return Name;
4969 return SemaRef.Context.getSubstTemplateTemplateParm(
4970 replacement: NewName, AssociatedDecl, Index: S->getIndex(), PackIndex: S->getPackIndex(),
4971 Final: S->getFinal());
4972 }
4973
4974 assert(!Name.getAsDeducedTemplateName() &&
4975 "DeducedTemplateName should not escape partial ordering");
4976
4977 // FIXME: Preserve UsingTemplateName.
4978 if (auto *Template = Name.getAsTemplateDecl()) {
4979 assert(!QualifierLoc && "Unexpected qualifier");
4980 return TemplateName(cast_or_null<TemplateDecl>(
4981 getDerived().TransformDecl(NameLoc, Template)));
4982 }
4983
4984 if (SubstTemplateTemplateParmPackStorage *SubstPack
4985 = Name.getAsSubstTemplateTemplateParmPack()) {
4986 assert(!QualifierLoc &&
4987 "Unexpected qualified SubstTemplateTemplateParmPack");
4988 return getDerived().RebuildTemplateName(
4989 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4990 SubstPack->getIndex(), SubstPack->getFinal());
4991 }
4992
4993 // These should be getting filtered out before they reach the AST.
4994 llvm_unreachable("overloaded function decl survived to here");
4995}
4996
4997template <typename Derived>
4998TemplateArgument TreeTransform<Derived>::TransformNamedTemplateTemplateArgument(
4999 NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKeywordLoc,
5000 TemplateName Name, SourceLocation NameLoc) {
5001 TemplateName TN = getDerived().TransformTemplateName(
5002 QualifierLoc, TemplateKeywordLoc, Name, NameLoc);
5003 if (TN.isNull())
5004 return TemplateArgument();
5005 return TemplateArgument(TN);
5006}
5007
5008template<typename Derived>
5009void TreeTransform<Derived>::InventTemplateArgumentLoc(
5010 const TemplateArgument &Arg,
5011 TemplateArgumentLoc &Output) {
5012 Output = getSema().getTrivialTemplateArgumentLoc(
5013 Arg, QualType(), getDerived().getBaseLocation());
5014}
5015
5016template <typename Derived>
5017bool TreeTransform<Derived>::TransformTemplateArgument(
5018 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
5019 bool Uneval) {
5020 const TemplateArgument &Arg = Input.getArgument();
5021 switch (Arg.getKind()) {
5022 case TemplateArgument::Null:
5023 case TemplateArgument::Pack:
5024 llvm_unreachable("Unexpected TemplateArgument");
5025
5026 case TemplateArgument::Integral:
5027 case TemplateArgument::NullPtr:
5028 case TemplateArgument::Declaration:
5029 case TemplateArgument::StructuralValue: {
5030 // Transform a resolved template argument straight to a resolved template
5031 // argument. We get here when substituting into an already-substituted
5032 // template type argument during concept satisfaction checking.
5033 QualType T = Arg.getNonTypeTemplateArgumentType();
5034 QualType NewT = getDerived().TransformType(T);
5035 if (NewT.isNull())
5036 return true;
5037
5038 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
5039 ? Arg.getAsDecl()
5040 : nullptr;
5041 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
5042 getDerived().getBaseLocation(), D))
5043 : nullptr;
5044 if (D && !NewD)
5045 return true;
5046
5047 if (NewT == T && D == NewD)
5048 Output = Input;
5049 else if (Arg.getKind() == TemplateArgument::Integral)
5050 Output = TemplateArgumentLoc(
5051 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
5052 TemplateArgumentLocInfo());
5053 else if (Arg.getKind() == TemplateArgument::NullPtr)
5054 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
5055 TemplateArgumentLocInfo());
5056 else if (Arg.getKind() == TemplateArgument::Declaration)
5057 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
5058 TemplateArgumentLocInfo());
5059 else if (Arg.getKind() == TemplateArgument::StructuralValue)
5060 Output = TemplateArgumentLoc(
5061 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
5062 TemplateArgumentLocInfo());
5063 else
5064 llvm_unreachable("unexpected template argument kind");
5065
5066 return false;
5067 }
5068
5069 case TemplateArgument::Type: {
5070 TypeSourceInfo *TSI = Input.getTypeSourceInfo();
5071 if (!TSI)
5072 TSI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
5073
5074 TSI = getDerived().TransformType(TSI);
5075 if (!TSI)
5076 return true;
5077
5078 Output = TemplateArgumentLoc(TemplateArgument(TSI->getType()), TSI);
5079 return false;
5080 }
5081
5082 case TemplateArgument::Template: {
5083 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
5084
5085 TemplateArgument Out = getDerived().TransformNamedTemplateTemplateArgument(
5086 QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
5087 Input.getTemplateNameLoc());
5088 if (Out.isNull())
5089 return true;
5090 Output = TemplateArgumentLoc(SemaRef.Context, Out, Input.getTemplateKWLoc(),
5091 QualifierLoc, Input.getTemplateNameLoc());
5092 return false;
5093 }
5094
5095 case TemplateArgument::TemplateExpansion:
5096 llvm_unreachable("Caller should expand pack expansions");
5097
5098 case TemplateArgument::Expression: {
5099 // Template argument expressions are constant expressions.
5100 EnterExpressionEvaluationContext Unevaluated(
5101 getSema(),
5102 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
5103 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
5104 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
5105 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
5106
5107 Expr *InputExpr = Input.getSourceExpression();
5108 if (!InputExpr)
5109 InputExpr = Input.getArgument().getAsExpr();
5110
5111 ExprResult E = getDerived().TransformExpr(InputExpr);
5112 E = SemaRef.ActOnConstantExpression(Res: E);
5113 if (E.isInvalid())
5114 return true;
5115 Output = TemplateArgumentLoc(
5116 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
5117 return false;
5118 }
5119 }
5120
5121 // Work around bogus GCC warning
5122 return true;
5123}
5124
5125/// Iterator adaptor that invents template argument location information
5126/// for each of the template arguments in its underlying iterator.
5127template<typename Derived, typename InputIterator>
5128class TemplateArgumentLocInventIterator {
5129 TreeTransform<Derived> &Self;
5130 InputIterator Iter;
5131
5132public:
5133 typedef TemplateArgumentLoc value_type;
5134 typedef TemplateArgumentLoc reference;
5135 typedef typename std::iterator_traits<InputIterator>::difference_type
5136 difference_type;
5137 typedef std::input_iterator_tag iterator_category;
5138
5139 class pointer {
5140 TemplateArgumentLoc Arg;
5141
5142 public:
5143 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
5144
5145 const TemplateArgumentLoc *operator->() const { return &Arg; }
5146 };
5147
5148 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5149 InputIterator Iter)
5150 : Self(Self), Iter(Iter) { }
5151
5152 TemplateArgumentLocInventIterator &operator++() {
5153 ++Iter;
5154 return *this;
5155 }
5156
5157 TemplateArgumentLocInventIterator operator++(int) {
5158 TemplateArgumentLocInventIterator Old(*this);
5159 ++(*this);
5160 return Old;
5161 }
5162
5163 reference operator*() const {
5164 TemplateArgumentLoc Result;
5165 Self.InventTemplateArgumentLoc(*Iter, Result);
5166 return Result;
5167 }
5168
5169 pointer operator->() const { return pointer(**this); }
5170
5171 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5172 const TemplateArgumentLocInventIterator &Y) {
5173 return X.Iter == Y.Iter;
5174 }
5175
5176 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5177 const TemplateArgumentLocInventIterator &Y) {
5178 return X.Iter != Y.Iter;
5179 }
5180};
5181
5182template<typename Derived>
5183template<typename InputIterator>
5184bool TreeTransform<Derived>::TransformTemplateArguments(
5185 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5186 bool Uneval) {
5187 for (TemplateArgumentLoc In : llvm::make_range(First, Last)) {
5188 TemplateArgumentLoc Out;
5189 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5190 // Unpack argument packs, which we translate them into separate
5191 // arguments.
5192 // FIXME: We could do much better if we could guarantee that the
5193 // TemplateArgumentLocInfo for the pack expansion would be usable for
5194 // all of the template arguments in the argument pack.
5195 typedef TemplateArgumentLocInventIterator<Derived,
5196 TemplateArgument::pack_iterator>
5197 PackLocIterator;
5198
5199 TemplateArgumentListInfo *PackOutput = &Outputs;
5200 TemplateArgumentListInfo New;
5201
5202 if (TransformTemplateArguments(
5203 PackLocIterator(*this, In.getArgument().pack_begin()),
5204 PackLocIterator(*this, In.getArgument().pack_end()), *PackOutput,
5205 Uneval))
5206 return true;
5207
5208 continue;
5209 }
5210
5211 if (In.getArgument().isPackExpansion()) {
5212 UnexpandedInfo Info;
5213 TemplateArgumentLoc Prepared;
5214 if (getDerived().PreparePackForExpansion(In, Uneval, Prepared, Info))
5215 return true;
5216 if (!Info.Expand) {
5217 Outputs.addArgument(Loc: Prepared);
5218 continue;
5219 }
5220
5221 // The transform has determined that we should perform an elementwise
5222 // expansion of the pattern. Do so.
5223 std::optional<ForgetSubstitutionRAII> ForgetSubst;
5224 if (Info.ExpandUnderForgetSubstitions)
5225 ForgetSubst.emplace(getDerived());
5226 for (unsigned I = 0; I != *Info.NumExpansions; ++I) {
5227 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5228
5229 TemplateArgumentLoc Out;
5230 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5231 return true;
5232
5233 if (Out.getArgument().containsUnexpandedParameterPack()) {
5234 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5235 Info.OrigNumExpansions);
5236 if (Out.getArgument().isNull())
5237 return true;
5238 }
5239
5240 Outputs.addArgument(Loc: Out);
5241 }
5242
5243 // If we're supposed to retain a pack expansion, do so by temporarily
5244 // forgetting the partially-substituted parameter pack.
5245 if (Info.RetainExpansion) {
5246 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5247
5248 TemplateArgumentLoc Out;
5249 if (getDerived().TransformTemplateArgument(Prepared, Out, Uneval))
5250 return true;
5251
5252 Out = getDerived().RebuildPackExpansion(Out, Info.Ellipsis,
5253 Info.OrigNumExpansions);
5254 if (Out.getArgument().isNull())
5255 return true;
5256
5257 Outputs.addArgument(Loc: Out);
5258 }
5259
5260 continue;
5261 }
5262
5263 // The simple case:
5264 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5265 return true;
5266
5267 Outputs.addArgument(Loc: Out);
5268 }
5269
5270 return false;
5271}
5272
5273template <typename Derived>
5274template <typename InputIterator>
5275bool TreeTransform<Derived>::TransformConceptTemplateArguments(
5276 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5277 bool Uneval) {
5278
5279 // [C++26][temp.constr.normal]
5280 // any non-dependent concept template argument
5281 // is substituted into the constraint-expression of C.
5282 auto isNonDependentConceptArgument = [](const TemplateArgument &Arg) {
5283 return !Arg.isDependent() && Arg.isConceptOrConceptTemplateParameter();
5284 };
5285
5286 for (; First != Last; ++First) {
5287 TemplateArgumentLoc Out;
5288 TemplateArgumentLoc In = *First;
5289
5290 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5291 typedef TemplateArgumentLocInventIterator<Derived,
5292 TemplateArgument::pack_iterator>
5293 PackLocIterator;
5294 if (TransformConceptTemplateArguments(
5295 PackLocIterator(*this, In.getArgument().pack_begin()),
5296 PackLocIterator(*this, In.getArgument().pack_end()), Outputs,
5297 Uneval))
5298 return true;
5299 continue;
5300 }
5301
5302 if (!isNonDependentConceptArgument(In.getArgument())) {
5303 Outputs.addArgument(Loc: In);
5304 continue;
5305 }
5306
5307 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5308 return true;
5309
5310 Outputs.addArgument(Loc: Out);
5311 }
5312
5313 return false;
5314}
5315
5316// FIXME: Find ways to reduce code duplication for pack expansions.
5317template <typename Derived>
5318bool TreeTransform<Derived>::PreparePackForExpansion(TemplateArgumentLoc In,
5319 bool Uneval,
5320 TemplateArgumentLoc &Out,
5321 UnexpandedInfo &Info) {
5322 auto ComputeInfo = [this](TemplateArgumentLoc Arg,
5323 bool IsLateExpansionAttempt, UnexpandedInfo &Info,
5324 TemplateArgumentLoc &Pattern) {
5325 assert(Arg.getArgument().isPackExpansion());
5326 // We have a pack expansion, for which we will be substituting into the
5327 // pattern.
5328 Pattern = getSema().getTemplateArgumentPackExpansionPattern(
5329 Arg, Info.Ellipsis, Info.OrigNumExpansions);
5330 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5331 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5332 if (IsLateExpansionAttempt) {
5333 // Request expansion only when there is an opportunity to expand a pack
5334 // that required a substituion first.
5335 bool SawPackTypes =
5336 llvm::any_of(Unexpanded, [](UnexpandedParameterPack P) {
5337 return P.first.dyn_cast<const SubstBuiltinTemplatePackType *>();
5338 });
5339 if (!SawPackTypes) {
5340 Info.Expand = false;
5341 return false;
5342 }
5343 }
5344 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5345
5346 // Determine whether the set of unexpanded parameter packs can and
5347 // should be expanded.
5348 Info.Expand = true;
5349 Info.RetainExpansion = false;
5350 Info.NumExpansions = Info.OrigNumExpansions;
5351 return getDerived().TryExpandParameterPacks(
5352 Info.Ellipsis, Pattern.getSourceRange(), Unexpanded,
5353 /*FailOnPackProducingTemplates=*/false, Info.Expand,
5354 Info.RetainExpansion, Info.NumExpansions);
5355 };
5356
5357 TemplateArgumentLoc Pattern;
5358 if (ComputeInfo(In, false, Info, Pattern))
5359 return true;
5360
5361 if (Info.Expand) {
5362 Out = Pattern;
5363 return false;
5364 }
5365
5366 // The transform has determined that we should perform a simple
5367 // transformation on the pack expansion, producing another pack
5368 // expansion.
5369 TemplateArgumentLoc OutPattern;
5370 std::optional<Sema::ArgPackSubstIndexRAII> SubstIndex(
5371 std::in_place, getSema(), std::nullopt);
5372 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5373 return true;
5374
5375 Out = getDerived().RebuildPackExpansion(OutPattern, Info.Ellipsis,
5376 Info.NumExpansions);
5377 if (Out.getArgument().isNull())
5378 return true;
5379 SubstIndex.reset();
5380
5381 if (!OutPattern.getArgument().containsUnexpandedParameterPack())
5382 return false;
5383
5384 // Some packs will learn their length after substitution, e.g.
5385 // __builtin_dedup_pack<T,int> has size 1 or 2, depending on the substitution
5386 // value of `T`.
5387 //
5388 // We only expand after we know sizes of all packs, check if this is the case
5389 // or not. However, we avoid a full template substitution and only do
5390 // expanstions after this point.
5391
5392 // E.g. when substituting template arguments of tuple with {T -> int} in the
5393 // following example:
5394 // template <class T>
5395 // struct TupleWithInt {
5396 // using type = std::tuple<__builtin_dedup_pack<T, int>...>;
5397 // };
5398 // TupleWithInt<int>::type y;
5399 // At this point we will see the `__builtin_dedup_pack<int, int>` with a known
5400 // length and run `ComputeInfo()` to provide the necessary information to our
5401 // caller.
5402 //
5403 // Note that we may still have situations where builtin is not going to be
5404 // expanded. For example:
5405 // template <class T>
5406 // struct Foo {
5407 // template <class U> using tuple_with_t =
5408 // std::tuple<__builtin_dedup_pack<T, U, int>...>; using type =
5409 // tuple_with_t<short>;
5410 // }
5411 // Because the substitution into `type` happens in dependent context, `type`
5412 // will be `tuple<builtin_dedup_pack<T, short, int>...>` after substitution
5413 // and the caller will not be able to expand it.
5414 ForgetSubstitutionRAII ForgetSubst(getDerived());
5415 if (ComputeInfo(Out, true, Info, OutPattern))
5416 return true;
5417 if (!Info.Expand)
5418 return false;
5419 Out = OutPattern;
5420 Info.ExpandUnderForgetSubstitions = true;
5421 return false;
5422}
5423
5424//===----------------------------------------------------------------------===//
5425// Type transformation
5426//===----------------------------------------------------------------------===//
5427
5428template<typename Derived>
5429QualType TreeTransform<Derived>::TransformType(QualType T) {
5430 if (getDerived().AlreadyTransformed(T))
5431 return T;
5432
5433 // Temporary workaround. All of these transformations should
5434 // eventually turn into transformations on TypeLocs.
5435 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5436 T, getDerived().getBaseLocation());
5437
5438 TypeSourceInfo *NewTSI = getDerived().TransformType(TSI);
5439
5440 if (!NewTSI)
5441 return QualType();
5442
5443 return NewTSI->getType();
5444}
5445
5446template <typename Derived>
5447TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *TSI) {
5448 // Refine the base location to the type's location.
5449 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5450 getDerived().getBaseEntity());
5451 if (getDerived().AlreadyTransformed(TSI->getType()))
5452 return TSI;
5453
5454 TypeLocBuilder TLB;
5455
5456 TypeLoc TL = TSI->getTypeLoc();
5457 TLB.reserve(Requested: TL.getFullDataSize());
5458
5459 QualType Result = getDerived().TransformType(TLB, TL);
5460 if (Result.isNull())
5461 return nullptr;
5462
5463 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5464}
5465
5466template<typename Derived>
5467QualType
5468TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5469 switch (T.getTypeLocClass()) {
5470#define ABSTRACT_TYPELOC(CLASS, PARENT)
5471#define TYPELOC(CLASS, PARENT) \
5472 case TypeLoc::CLASS: \
5473 return getDerived().Transform##CLASS##Type(TLB, \
5474 T.castAs<CLASS##TypeLoc>());
5475#include "clang/AST/TypeLocNodes.def"
5476 }
5477
5478 llvm_unreachable("unhandled type loc!");
5479}
5480
5481template<typename Derived>
5482QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5483 if (!isa<DependentNameType>(Val: T))
5484 return TransformType(T);
5485
5486 if (getDerived().AlreadyTransformed(T))
5487 return T;
5488 TypeSourceInfo *TSI = getSema().Context.getTrivialTypeSourceInfo(
5489 T, getDerived().getBaseLocation());
5490 TypeSourceInfo *NewTSI = getDerived().TransformTypeWithDeducedTST(TSI);
5491 return NewTSI ? NewTSI->getType() : QualType();
5492}
5493
5494template <typename Derived>
5495TypeSourceInfo *
5496TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *TSI) {
5497 if (!isa<DependentNameType>(Val: TSI->getType()))
5498 return TransformType(TSI);
5499
5500 // Refine the base location to the type's location.
5501 TemporaryBase Rebase(*this, TSI->getTypeLoc().getBeginLoc(),
5502 getDerived().getBaseEntity());
5503 if (getDerived().AlreadyTransformed(TSI->getType()))
5504 return TSI;
5505
5506 TypeLocBuilder TLB;
5507
5508 TypeLoc TL = TSI->getTypeLoc();
5509 TLB.reserve(Requested: TL.getFullDataSize());
5510
5511 auto QTL = TL.getAs<QualifiedTypeLoc>();
5512 if (QTL)
5513 TL = QTL.getUnqualifiedLoc();
5514
5515 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5516
5517 QualType Result = getDerived().TransformDependentNameType(
5518 TLB, DNTL, /*DeducedTSTContext*/true);
5519 if (Result.isNull())
5520 return nullptr;
5521
5522 if (QTL) {
5523 Result = getDerived().RebuildQualifiedType(Result, QTL);
5524 if (Result.isNull())
5525 return nullptr;
5526 TLB.TypeWasModifiedSafely(T: Result);
5527 }
5528
5529 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5530}
5531
5532template<typename Derived>
5533QualType
5534TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5535 QualifiedTypeLoc T) {
5536 QualType Result;
5537 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5538 auto SuppressObjCLifetime =
5539 T.getType().getLocalQualifiers().hasObjCLifetime();
5540 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5541 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5542 SuppressObjCLifetime);
5543 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5544 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5545 TLB, STTP, SuppressObjCLifetime);
5546 } else {
5547 Result = getDerived().TransformType(TLB, UnqualTL);
5548 }
5549
5550 if (Result.isNull())
5551 return QualType();
5552
5553 Result = getDerived().RebuildQualifiedType(Result, T);
5554
5555 if (Result.isNull())
5556 return QualType();
5557
5558 // RebuildQualifiedType might have updated the type, but not in a way
5559 // that invalidates the TypeLoc. (There's no location information for
5560 // qualifiers.)
5561 TLB.TypeWasModifiedSafely(T: Result);
5562
5563 return Result;
5564}
5565
5566template <typename Derived>
5567QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5568 QualifiedTypeLoc TL) {
5569
5570 SourceLocation Loc = TL.getBeginLoc();
5571 Qualifiers Quals = TL.getType().getLocalQualifiers();
5572
5573 if ((T.getAddressSpace() != LangAS::Default &&
5574 Quals.getAddressSpace() != LangAS::Default) &&
5575 T.getAddressSpace() != Quals.getAddressSpace()) {
5576 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5577 << TL.getType() << T;
5578 return QualType();
5579 }
5580
5581 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5582 if (LocalPointerAuth.isPresent()) {
5583 if (T.getPointerAuth().isPresent()) {
5584 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5585 return QualType();
5586 }
5587 if (!T->isDependentType()) {
5588 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5589 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5590 return QualType();
5591 }
5592 }
5593 }
5594 // C++ [dcl.fct]p7:
5595 // [When] adding cv-qualifications on top of the function type [...] the
5596 // cv-qualifiers are ignored.
5597 if (T->isFunctionType()) {
5598 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5599 AddressSpace: Quals.getAddressSpace());
5600 return T;
5601 }
5602
5603 // C++ [dcl.ref]p1:
5604 // when the cv-qualifiers are introduced through the use of a typedef-name
5605 // or decltype-specifier [...] the cv-qualifiers are ignored.
5606 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5607 // applied to a reference type.
5608 if (T->isReferenceType()) {
5609 // The only qualifier that applies to a reference type is restrict.
5610 if (!Quals.hasRestrict())
5611 return T;
5612 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5613 }
5614
5615 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5616 // resulting type.
5617 if (Quals.hasObjCLifetime()) {
5618 if (!T->isObjCLifetimeType() && !T->isDependentType())
5619 Quals.removeObjCLifetime();
5620 else if (T.getObjCLifetime()) {
5621 // Objective-C ARC:
5622 // A lifetime qualifier applied to a substituted template parameter
5623 // overrides the lifetime qualifier from the template argument.
5624 const AutoType *AutoTy;
5625 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5626 // 'auto' types behave the same way as template parameters.
5627 QualType Deduced = AutoTy->getDeducedType();
5628 Qualifiers Qs = Deduced.getQualifiers();
5629 Qs.removeObjCLifetime();
5630 Deduced =
5631 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5632 T = SemaRef.Context.getAutoType(DK: AutoTy->getDeducedKind(), DeducedAsType: Deduced,
5633 Keyword: AutoTy->getKeyword(),
5634 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5635 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5636 } else {
5637 // Otherwise, complain about the addition of a qualifier to an
5638 // already-qualified type.
5639 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5640 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5641 Quals.removeObjCLifetime();
5642 }
5643 }
5644 }
5645
5646 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5647}
5648
5649template <typename Derived>
5650QualType TreeTransform<Derived>::TransformTypeInObjectScope(
5651 TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
5652 NamedDecl *FirstQualifierInScope) {
5653 assert(!getDerived().AlreadyTransformed(TL.getType()));
5654
5655 switch (TL.getTypeLocClass()) {
5656 case TypeLoc::TemplateSpecialization:
5657 return getDerived().TransformTemplateSpecializationType(
5658 TLB, TL.castAs<TemplateSpecializationTypeLoc>(), ObjectType,
5659 FirstQualifierInScope, /*AllowInjectedClassName=*/true);
5660 case TypeLoc::DependentName:
5661 return getDerived().TransformDependentNameType(
5662 TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
5663 ObjectType, FirstQualifierInScope);
5664 default:
5665 // Any dependent canonical type can appear here, through type alias
5666 // templates.
5667 return getDerived().TransformType(TLB, TL);
5668 }
5669}
5670
5671template <class TyLoc> static inline
5672QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5673 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5674 NewT.setNameLoc(T.getNameLoc());
5675 return T.getType();
5676}
5677
5678template<typename Derived>
5679QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5680 BuiltinTypeLoc T) {
5681 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5682 NewT.setBuiltinLoc(T.getBuiltinLoc());
5683 if (T.needsExtraLocalData())
5684 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5685 return T.getType();
5686}
5687
5688template<typename Derived>
5689QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5690 ComplexTypeLoc T) {
5691 // FIXME: recurse?
5692 return TransformTypeSpecType(TLB, T);
5693}
5694
5695template <typename Derived>
5696QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5697 AdjustedTypeLoc TL) {
5698 // Adjustments applied during transformation are handled elsewhere.
5699 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5700}
5701
5702template<typename Derived>
5703QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5704 DecayedTypeLoc TL) {
5705 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5706 if (OriginalType.isNull())
5707 return QualType();
5708
5709 QualType Result = TL.getType();
5710 if (getDerived().AlwaysRebuild() ||
5711 OriginalType != TL.getOriginalLoc().getType())
5712 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5713 TLB.push<DecayedTypeLoc>(T: Result);
5714 // Nothing to set for DecayedTypeLoc.
5715 return Result;
5716}
5717
5718template <typename Derived>
5719QualType
5720TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5721 ArrayParameterTypeLoc TL) {
5722 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5723 if (OriginalType.isNull())
5724 return QualType();
5725
5726 QualType Result = TL.getType();
5727 if (getDerived().AlwaysRebuild() ||
5728 OriginalType != TL.getElementLoc().getType())
5729 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5730 TLB.push<ArrayParameterTypeLoc>(T: Result);
5731 // Nothing to set for ArrayParameterTypeLoc.
5732 return Result;
5733}
5734
5735template<typename Derived>
5736QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5737 PointerTypeLoc TL) {
5738 QualType PointeeType
5739 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5740 if (PointeeType.isNull())
5741 return QualType();
5742
5743 QualType Result = TL.getType();
5744 if (PointeeType->getAs<ObjCObjectType>()) {
5745 // A dependent pointer type 'T *' has is being transformed such
5746 // that an Objective-C class type is being replaced for 'T'. The
5747 // resulting pointer type is an ObjCObjectPointerType, not a
5748 // PointerType.
5749 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5750
5751 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5752 NewT.setStarLoc(TL.getStarLoc());
5753 return Result;
5754 }
5755
5756 if (getDerived().AlwaysRebuild() ||
5757 PointeeType != TL.getPointeeLoc().getType()) {
5758 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5759 if (Result.isNull())
5760 return QualType();
5761 }
5762
5763 // Objective-C ARC can add lifetime qualifiers to the type that we're
5764 // pointing to.
5765 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5766
5767 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5768 NewT.setSigilLoc(TL.getSigilLoc());
5769 return Result;
5770}
5771
5772template<typename Derived>
5773QualType
5774TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5775 BlockPointerTypeLoc TL) {
5776 QualType PointeeType
5777 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5778 if (PointeeType.isNull())
5779 return QualType();
5780
5781 QualType Result = TL.getType();
5782 if (getDerived().AlwaysRebuild() ||
5783 PointeeType != TL.getPointeeLoc().getType()) {
5784 Result = getDerived().RebuildBlockPointerType(PointeeType,
5785 TL.getSigilLoc());
5786 if (Result.isNull())
5787 return QualType();
5788 }
5789
5790 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5791 NewT.setSigilLoc(TL.getSigilLoc());
5792 return Result;
5793}
5794
5795/// Transforms a reference type. Note that somewhat paradoxically we
5796/// don't care whether the type itself is an l-value type or an r-value
5797/// type; we only care if the type was *written* as an l-value type
5798/// or an r-value type.
5799template<typename Derived>
5800QualType
5801TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5802 ReferenceTypeLoc TL) {
5803 const ReferenceType *T = TL.getTypePtr();
5804
5805 // Note that this works with the pointee-as-written.
5806 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5807 if (PointeeType.isNull())
5808 return QualType();
5809
5810 QualType Result = TL.getType();
5811 if (getDerived().AlwaysRebuild() ||
5812 PointeeType != T->getPointeeTypeAsWritten()) {
5813 Result = getDerived().RebuildReferenceType(PointeeType,
5814 T->isSpelledAsLValue(),
5815 TL.getSigilLoc());
5816 if (Result.isNull())
5817 return QualType();
5818 }
5819
5820 // Objective-C ARC can add lifetime qualifiers to the type that we're
5821 // referring to.
5822 TLB.TypeWasModifiedSafely(
5823 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5824
5825 // r-value references can be rebuilt as l-value references.
5826 ReferenceTypeLoc NewTL;
5827 if (isa<LValueReferenceType>(Val: Result))
5828 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5829 else
5830 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5831 NewTL.setSigilLoc(TL.getSigilLoc());
5832
5833 return Result;
5834}
5835
5836template<typename Derived>
5837QualType
5838TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5839 LValueReferenceTypeLoc TL) {
5840 return TransformReferenceType(TLB, TL);
5841}
5842
5843template<typename Derived>
5844QualType
5845TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5846 RValueReferenceTypeLoc TL) {
5847 return TransformReferenceType(TLB, TL);
5848}
5849
5850template<typename Derived>
5851QualType
5852TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5853 MemberPointerTypeLoc TL) {
5854 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5855 if (PointeeType.isNull())
5856 return QualType();
5857
5858 const MemberPointerType *T = TL.getTypePtr();
5859
5860 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5861 NestedNameSpecifierLoc NewQualifierLoc =
5862 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5863 if (!NewQualifierLoc)
5864 return QualType();
5865
5866 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5867 if (OldCls) {
5868 NewCls = cast_or_null<CXXRecordDecl>(
5869 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5870 if (!NewCls)
5871 return QualType();
5872 }
5873
5874 QualType Result = TL.getType();
5875 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5876 NewQualifierLoc.getNestedNameSpecifier() !=
5877 OldQualifierLoc.getNestedNameSpecifier() ||
5878 NewCls != OldCls) {
5879 CXXScopeSpec SS;
5880 SS.Adopt(Other: NewQualifierLoc);
5881 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5882 TL.getStarLoc());
5883 if (Result.isNull())
5884 return QualType();
5885 }
5886
5887 // If we had to adjust the pointee type when building a member pointer, make
5888 // sure to push TypeLoc info for it.
5889 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5890 if (MPT && PointeeType != MPT->getPointeeType()) {
5891 assert(isa<AdjustedType>(MPT->getPointeeType()));
5892 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5893 }
5894
5895 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5896 NewTL.setSigilLoc(TL.getSigilLoc());
5897 NewTL.setQualifierLoc(NewQualifierLoc);
5898
5899 return Result;
5900}
5901
5902template<typename Derived>
5903QualType
5904TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5905 ConstantArrayTypeLoc TL) {
5906 const ConstantArrayType *T = TL.getTypePtr();
5907 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5908 if (ElementType.isNull())
5909 return QualType();
5910
5911 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5912 Expr *OldSize = TL.getSizeExpr();
5913 if (!OldSize)
5914 OldSize = const_cast<Expr*>(T->getSizeExpr());
5915 Expr *NewSize = nullptr;
5916 if (OldSize) {
5917 EnterExpressionEvaluationContext Unevaluated(
5918 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5919 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5920 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5921 }
5922
5923 QualType Result = TL.getType();
5924 if (getDerived().AlwaysRebuild() ||
5925 ElementType != T->getElementType() ||
5926 (T->getSizeExpr() && NewSize != OldSize)) {
5927 Result = getDerived().RebuildConstantArrayType(ElementType,
5928 T->getSizeModifier(),
5929 T->getSize(), NewSize,
5930 T->getIndexTypeCVRQualifiers(),
5931 TL.getBracketsRange());
5932 if (Result.isNull())
5933 return QualType();
5934 }
5935
5936 // We might have either a ConstantArrayType or a VariableArrayType now:
5937 // a ConstantArrayType is allowed to have an element type which is a
5938 // VariableArrayType if the type is dependent. Fortunately, all array
5939 // types have the same location layout.
5940 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5941 NewTL.setLBracketLoc(TL.getLBracketLoc());
5942 NewTL.setRBracketLoc(TL.getRBracketLoc());
5943 NewTL.setSizeExpr(NewSize);
5944
5945 return Result;
5946}
5947
5948template<typename Derived>
5949QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5950 TypeLocBuilder &TLB,
5951 IncompleteArrayTypeLoc TL) {
5952 const IncompleteArrayType *T = TL.getTypePtr();
5953 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5954 if (ElementType.isNull())
5955 return QualType();
5956
5957 QualType Result = TL.getType();
5958 if (getDerived().AlwaysRebuild() ||
5959 ElementType != T->getElementType()) {
5960 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5961 T->getSizeModifier(),
5962 T->getIndexTypeCVRQualifiers(),
5963 TL.getBracketsRange());
5964 if (Result.isNull())
5965 return QualType();
5966 }
5967
5968 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5969 NewTL.setLBracketLoc(TL.getLBracketLoc());
5970 NewTL.setRBracketLoc(TL.getRBracketLoc());
5971 NewTL.setSizeExpr(nullptr);
5972
5973 return Result;
5974}
5975
5976template<typename Derived>
5977QualType
5978TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5979 VariableArrayTypeLoc TL) {
5980 const VariableArrayType *T = TL.getTypePtr();
5981 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5982 if (ElementType.isNull())
5983 return QualType();
5984
5985 ExprResult SizeResult;
5986 {
5987 EnterExpressionEvaluationContext Context(
5988 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5989 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5990 }
5991 if (SizeResult.isInvalid())
5992 return QualType();
5993 SizeResult =
5994 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5995 if (SizeResult.isInvalid())
5996 return QualType();
5997
5998 Expr *Size = SizeResult.get();
5999
6000 QualType Result = TL.getType();
6001 if (getDerived().AlwaysRebuild() ||
6002 ElementType != T->getElementType() ||
6003 Size != T->getSizeExpr()) {
6004 Result = getDerived().RebuildVariableArrayType(ElementType,
6005 T->getSizeModifier(),
6006 Size,
6007 T->getIndexTypeCVRQualifiers(),
6008 TL.getBracketsRange());
6009 if (Result.isNull())
6010 return QualType();
6011 }
6012
6013 // We might have constant size array now, but fortunately it has the same
6014 // location layout.
6015 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6016 NewTL.setLBracketLoc(TL.getLBracketLoc());
6017 NewTL.setRBracketLoc(TL.getRBracketLoc());
6018 NewTL.setSizeExpr(Size);
6019
6020 return Result;
6021}
6022
6023template<typename Derived>
6024QualType
6025TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
6026 DependentSizedArrayTypeLoc TL) {
6027 const DependentSizedArrayType *T = TL.getTypePtr();
6028 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6029 if (ElementType.isNull())
6030 return QualType();
6031
6032 // Array bounds are constant expressions.
6033 EnterExpressionEvaluationContext Unevaluated(
6034 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6035
6036 // If we have a VLA then it won't be a constant.
6037 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
6038
6039 // Prefer the expression from the TypeLoc; the other may have been uniqued.
6040 Expr *origSize = TL.getSizeExpr();
6041 if (!origSize) origSize = T->getSizeExpr();
6042
6043 ExprResult sizeResult
6044 = getDerived().TransformExpr(origSize);
6045 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
6046 if (sizeResult.isInvalid())
6047 return QualType();
6048
6049 Expr *size = sizeResult.get();
6050
6051 QualType Result = TL.getType();
6052 if (getDerived().AlwaysRebuild() ||
6053 ElementType != T->getElementType() ||
6054 size != origSize) {
6055 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
6056 T->getSizeModifier(),
6057 size,
6058 T->getIndexTypeCVRQualifiers(),
6059 TL.getBracketsRange());
6060 if (Result.isNull())
6061 return QualType();
6062 }
6063
6064 // We might have any sort of array type now, but fortunately they
6065 // all have the same location layout.
6066 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
6067 NewTL.setLBracketLoc(TL.getLBracketLoc());
6068 NewTL.setRBracketLoc(TL.getRBracketLoc());
6069 NewTL.setSizeExpr(size);
6070
6071 return Result;
6072}
6073
6074template <typename Derived>
6075QualType TreeTransform<Derived>::TransformDependentVectorType(
6076 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
6077 const DependentVectorType *T = TL.getTypePtr();
6078 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6079 if (ElementType.isNull())
6080 return QualType();
6081
6082 EnterExpressionEvaluationContext Unevaluated(
6083 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6084
6085 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6086 Size = SemaRef.ActOnConstantExpression(Res: Size);
6087 if (Size.isInvalid())
6088 return QualType();
6089
6090 QualType Result = TL.getType();
6091 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6092 Size.get() != T->getSizeExpr()) {
6093 Result = getDerived().RebuildDependentVectorType(
6094 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
6095 if (Result.isNull())
6096 return QualType();
6097 }
6098
6099 // Result might be dependent or not.
6100 if (isa<DependentVectorType>(Val: Result)) {
6101 DependentVectorTypeLoc NewTL =
6102 TLB.push<DependentVectorTypeLoc>(T: Result);
6103 NewTL.setNameLoc(TL.getNameLoc());
6104 } else {
6105 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6106 NewTL.setNameLoc(TL.getNameLoc());
6107 }
6108
6109 return Result;
6110}
6111
6112template<typename Derived>
6113QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
6114 TypeLocBuilder &TLB,
6115 DependentSizedExtVectorTypeLoc TL) {
6116 const DependentSizedExtVectorType *T = TL.getTypePtr();
6117
6118 // FIXME: ext vector locs should be nested
6119 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6120 if (ElementType.isNull())
6121 return QualType();
6122
6123 // Vector sizes are constant expressions.
6124 EnterExpressionEvaluationContext Unevaluated(
6125 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6126
6127 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
6128 Size = SemaRef.ActOnConstantExpression(Res: Size);
6129 if (Size.isInvalid())
6130 return QualType();
6131
6132 QualType Result = TL.getType();
6133 if (getDerived().AlwaysRebuild() ||
6134 ElementType != T->getElementType() ||
6135 Size.get() != T->getSizeExpr()) {
6136 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
6137 Size.get(),
6138 T->getAttributeLoc());
6139 if (Result.isNull())
6140 return QualType();
6141 }
6142
6143 // Result might be dependent or not.
6144 if (isa<DependentSizedExtVectorType>(Val: Result)) {
6145 DependentSizedExtVectorTypeLoc NewTL
6146 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
6147 NewTL.setNameLoc(TL.getNameLoc());
6148 } else {
6149 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6150 NewTL.setNameLoc(TL.getNameLoc());
6151 }
6152
6153 return Result;
6154}
6155
6156template <typename Derived>
6157QualType
6158TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
6159 ConstantMatrixTypeLoc TL) {
6160 const ConstantMatrixType *T = TL.getTypePtr();
6161 QualType ElementType = getDerived().TransformType(T->getElementType());
6162 if (ElementType.isNull())
6163 return QualType();
6164
6165 QualType Result = TL.getType();
6166 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
6167 Result = getDerived().RebuildConstantMatrixType(
6168 ElementType, T->getNumRows(), T->getNumColumns());
6169 if (Result.isNull())
6170 return QualType();
6171 }
6172
6173 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
6174 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6175 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6176 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
6177 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
6178
6179 return Result;
6180}
6181
6182template <typename Derived>
6183QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
6184 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
6185 const DependentSizedMatrixType *T = TL.getTypePtr();
6186
6187 QualType ElementType = getDerived().TransformType(T->getElementType());
6188 if (ElementType.isNull()) {
6189 return QualType();
6190 }
6191
6192 // Matrix dimensions are constant expressions.
6193 EnterExpressionEvaluationContext Unevaluated(
6194 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6195
6196 Expr *origRows = TL.getAttrRowOperand();
6197 if (!origRows)
6198 origRows = T->getRowExpr();
6199 Expr *origColumns = TL.getAttrColumnOperand();
6200 if (!origColumns)
6201 origColumns = T->getColumnExpr();
6202
6203 ExprResult rowResult = getDerived().TransformExpr(origRows);
6204 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
6205 if (rowResult.isInvalid())
6206 return QualType();
6207
6208 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6209 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6210 if (columnResult.isInvalid())
6211 return QualType();
6212
6213 Expr *rows = rowResult.get();
6214 Expr *columns = columnResult.get();
6215
6216 QualType Result = TL.getType();
6217 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6218 rows != origRows || columns != origColumns) {
6219 Result = getDerived().RebuildDependentSizedMatrixType(
6220 ElementType, rows, columns, T->getAttributeLoc());
6221
6222 if (Result.isNull())
6223 return QualType();
6224 }
6225
6226 // We might have any sort of matrix type now, but fortunately they
6227 // all have the same location layout.
6228 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6229 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6230 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6231 NewTL.setAttrRowOperand(rows);
6232 NewTL.setAttrColumnOperand(columns);
6233 return Result;
6234}
6235
6236template <typename Derived>
6237QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6238 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6239 const DependentAddressSpaceType *T = TL.getTypePtr();
6240
6241 QualType pointeeType =
6242 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6243
6244 if (pointeeType.isNull())
6245 return QualType();
6246
6247 // Address spaces are constant expressions.
6248 EnterExpressionEvaluationContext Unevaluated(
6249 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6250
6251 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6252 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6253 if (AddrSpace.isInvalid())
6254 return QualType();
6255
6256 QualType Result = TL.getType();
6257 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6258 AddrSpace.get() != T->getAddrSpaceExpr()) {
6259 Result = getDerived().RebuildDependentAddressSpaceType(
6260 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6261 if (Result.isNull())
6262 return QualType();
6263 }
6264
6265 // Result might be dependent or not.
6266 if (isa<DependentAddressSpaceType>(Val: Result)) {
6267 DependentAddressSpaceTypeLoc NewTL =
6268 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6269
6270 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6271 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6272 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6273
6274 } else {
6275 TLB.TypeWasModifiedSafely(T: Result);
6276 }
6277
6278 return Result;
6279}
6280
6281template <typename Derived>
6282QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6283 VectorTypeLoc TL) {
6284 const VectorType *T = TL.getTypePtr();
6285 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6286 if (ElementType.isNull())
6287 return QualType();
6288
6289 QualType Result = TL.getType();
6290 if (getDerived().AlwaysRebuild() ||
6291 ElementType != T->getElementType()) {
6292 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6293 T->getVectorKind());
6294 if (Result.isNull())
6295 return QualType();
6296 }
6297
6298 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6299 NewTL.setNameLoc(TL.getNameLoc());
6300
6301 return Result;
6302}
6303
6304template<typename Derived>
6305QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6306 ExtVectorTypeLoc TL) {
6307 const VectorType *T = TL.getTypePtr();
6308 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6309 if (ElementType.isNull())
6310 return QualType();
6311
6312 QualType Result = TL.getType();
6313 if (getDerived().AlwaysRebuild() ||
6314 ElementType != T->getElementType()) {
6315 Result = getDerived().RebuildExtVectorType(ElementType,
6316 T->getNumElements(),
6317 /*FIXME*/ SourceLocation());
6318 if (Result.isNull())
6319 return QualType();
6320 }
6321
6322 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6323 NewTL.setNameLoc(TL.getNameLoc());
6324
6325 return Result;
6326}
6327
6328template <typename Derived>
6329ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6330 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6331 bool ExpectParameterPack) {
6332 TypeSourceInfo *OldTSI = OldParm->getTypeSourceInfo();
6333 TypeSourceInfo *NewTSI = nullptr;
6334
6335 if (NumExpansions && isa<PackExpansionType>(Val: OldTSI->getType())) {
6336 // If we're substituting into a pack expansion type and we know the
6337 // length we want to expand to, just substitute for the pattern.
6338 TypeLoc OldTL = OldTSI->getTypeLoc();
6339 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6340
6341 TypeLocBuilder TLB;
6342 TypeLoc NewTL = OldTSI->getTypeLoc();
6343 TLB.reserve(Requested: NewTL.getFullDataSize());
6344
6345 QualType Result = getDerived().TransformType(TLB,
6346 OldExpansionTL.getPatternLoc());
6347 if (Result.isNull())
6348 return nullptr;
6349
6350 Result = RebuildPackExpansionType(Pattern: Result,
6351 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6352 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6353 NumExpansions);
6354 if (Result.isNull())
6355 return nullptr;
6356
6357 PackExpansionTypeLoc NewExpansionTL
6358 = TLB.push<PackExpansionTypeLoc>(T: Result);
6359 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6360 NewTSI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6361 } else
6362 NewTSI = getDerived().TransformType(OldTSI);
6363 if (!NewTSI)
6364 return nullptr;
6365
6366 if (NewTSI == OldTSI && indexAdjustment == 0)
6367 return OldParm;
6368
6369 ParmVarDecl *newParm = ParmVarDecl::Create(
6370 C&: SemaRef.Context, DC: OldParm->getDeclContext(), StartLoc: OldParm->getInnerLocStart(),
6371 IdLoc: OldParm->getLocation(), Id: OldParm->getIdentifier(), T: NewTSI->getType(),
6372 TInfo: NewTSI, S: OldParm->getStorageClass(),
6373 /* DefArg */ DefArg: nullptr);
6374 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6375 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6376 getDerived().transformedLocalDecl(OldParm, {newParm});
6377 return newParm;
6378}
6379
6380template <typename Derived>
6381bool TreeTransform<Derived>::TransformFunctionTypeParams(
6382 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6383 const QualType *ParamTypes,
6384 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6385 SmallVectorImpl<QualType> &OutParamTypes,
6386 SmallVectorImpl<ParmVarDecl *> *PVars,
6387 Sema::ExtParameterInfoBuilder &PInfos,
6388 unsigned *LastParamTransformed) {
6389 int indexAdjustment = 0;
6390
6391 unsigned NumParams = Params.size();
6392 for (unsigned i = 0; i != NumParams; ++i) {
6393 if (LastParamTransformed)
6394 *LastParamTransformed = i;
6395 if (ParmVarDecl *OldParm = Params[i]) {
6396 assert(OldParm->getFunctionScopeIndex() == i);
6397
6398 UnsignedOrNone NumExpansions = std::nullopt;
6399 ParmVarDecl *NewParm = nullptr;
6400 if (OldParm->isParameterPack()) {
6401 // We have a function parameter pack that may need to be expanded.
6402 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6403
6404 // Find the parameter packs that could be expanded.
6405 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6406 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6407 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6408 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6409
6410 // Determine whether we should expand the parameter packs.
6411 bool ShouldExpand = false;
6412 bool RetainExpansion = false;
6413 UnsignedOrNone OrigNumExpansions = std::nullopt;
6414 if (Unexpanded.size() > 0) {
6415 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6416 NumExpansions = OrigNumExpansions;
6417 if (getDerived().TryExpandParameterPacks(
6418 ExpansionTL.getEllipsisLoc(), Pattern.getSourceRange(),
6419 Unexpanded, /*FailOnPackProducingTemplates=*/true,
6420 ShouldExpand, RetainExpansion, NumExpansions)) {
6421 return true;
6422 }
6423 } else {
6424#ifndef NDEBUG
6425 const AutoType *AT =
6426 Pattern.getType().getTypePtr()->getContainedAutoType();
6427 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6428 "Could not find parameter packs or undeduced auto type!");
6429#endif
6430 }
6431
6432 if (ShouldExpand) {
6433 // Expand the function parameter pack into multiple, separate
6434 // parameters.
6435 getDerived().ExpandingFunctionParameterPack(OldParm);
6436 for (unsigned I = 0; I != *NumExpansions; ++I) {
6437 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6438 ParmVarDecl *NewParm
6439 = getDerived().TransformFunctionTypeParam(OldParm,
6440 indexAdjustment++,
6441 OrigNumExpansions,
6442 /*ExpectParameterPack=*/false);
6443 if (!NewParm)
6444 return true;
6445
6446 if (ParamInfos)
6447 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6448 OutParamTypes.push_back(Elt: NewParm->getType());
6449 if (PVars)
6450 PVars->push_back(Elt: NewParm);
6451 }
6452
6453 // If we're supposed to retain a pack expansion, do so by temporarily
6454 // forgetting the partially-substituted parameter pack.
6455 if (RetainExpansion) {
6456 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6457 ParmVarDecl *NewParm
6458 = getDerived().TransformFunctionTypeParam(OldParm,
6459 indexAdjustment++,
6460 OrigNumExpansions,
6461 /*ExpectParameterPack=*/false);
6462 if (!NewParm)
6463 return true;
6464
6465 if (ParamInfos)
6466 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6467 OutParamTypes.push_back(Elt: NewParm->getType());
6468 if (PVars)
6469 PVars->push_back(Elt: NewParm);
6470 }
6471
6472 // The next parameter should have the same adjustment as the
6473 // last thing we pushed, but we post-incremented indexAdjustment
6474 // on every push. Also, if we push nothing, the adjustment should
6475 // go down by one.
6476 indexAdjustment--;
6477
6478 // We're done with the pack expansion.
6479 continue;
6480 }
6481
6482 // We'll substitute the parameter now without expanding the pack
6483 // expansion.
6484 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6485 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6486 indexAdjustment,
6487 NumExpansions,
6488 /*ExpectParameterPack=*/true);
6489 assert(NewParm->isParameterPack() &&
6490 "Parameter pack no longer a parameter pack after "
6491 "transformation.");
6492 } else {
6493 NewParm = getDerived().TransformFunctionTypeParam(
6494 OldParm, indexAdjustment, std::nullopt,
6495 /*ExpectParameterPack=*/false);
6496 }
6497
6498 if (!NewParm)
6499 return true;
6500
6501 if (ParamInfos)
6502 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6503 OutParamTypes.push_back(Elt: NewParm->getType());
6504 if (PVars)
6505 PVars->push_back(Elt: NewParm);
6506 continue;
6507 }
6508
6509 // Deal with the possibility that we don't have a parameter
6510 // declaration for this parameter.
6511 assert(ParamTypes);
6512 QualType OldType = ParamTypes[i];
6513 bool IsPackExpansion = false;
6514 UnsignedOrNone NumExpansions = std::nullopt;
6515 QualType NewType;
6516 if (const PackExpansionType *Expansion
6517 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6518 // We have a function parameter pack that may need to be expanded.
6519 QualType Pattern = Expansion->getPattern();
6520 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6521 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6522
6523 // Determine whether we should expand the parameter packs.
6524 bool ShouldExpand = false;
6525 bool RetainExpansion = false;
6526 if (getDerived().TryExpandParameterPacks(
6527 Loc, SourceRange(), Unexpanded,
6528 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
6529 RetainExpansion, NumExpansions)) {
6530 return true;
6531 }
6532
6533 if (ShouldExpand) {
6534 // Expand the function parameter pack into multiple, separate
6535 // parameters.
6536 for (unsigned I = 0; I != *NumExpansions; ++I) {
6537 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6538 QualType NewType = getDerived().TransformType(Pattern);
6539 if (NewType.isNull())
6540 return true;
6541
6542 if (NewType->containsUnexpandedParameterPack()) {
6543 NewType = getSema().getASTContext().getPackExpansionType(
6544 NewType, std::nullopt);
6545
6546 if (NewType.isNull())
6547 return true;
6548 }
6549
6550 if (ParamInfos)
6551 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6552 OutParamTypes.push_back(Elt: NewType);
6553 if (PVars)
6554 PVars->push_back(Elt: nullptr);
6555 }
6556
6557 // We're done with the pack expansion.
6558 continue;
6559 }
6560
6561 // If we're supposed to retain a pack expansion, do so by temporarily
6562 // forgetting the partially-substituted parameter pack.
6563 if (RetainExpansion) {
6564 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6565 QualType NewType = getDerived().TransformType(Pattern);
6566 if (NewType.isNull())
6567 return true;
6568
6569 if (ParamInfos)
6570 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6571 OutParamTypes.push_back(Elt: NewType);
6572 if (PVars)
6573 PVars->push_back(Elt: nullptr);
6574 }
6575
6576 // We'll substitute the parameter now without expanding the pack
6577 // expansion.
6578 OldType = Expansion->getPattern();
6579 IsPackExpansion = true;
6580 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6581 NewType = getDerived().TransformType(OldType);
6582 } else {
6583 NewType = getDerived().TransformType(OldType);
6584 }
6585
6586 if (NewType.isNull())
6587 return true;
6588
6589 if (IsPackExpansion)
6590 NewType = getSema().Context.getPackExpansionType(NewType,
6591 NumExpansions);
6592
6593 if (ParamInfos)
6594 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6595 OutParamTypes.push_back(Elt: NewType);
6596 if (PVars)
6597 PVars->push_back(Elt: nullptr);
6598 }
6599
6600#ifndef NDEBUG
6601 if (PVars) {
6602 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6603 if (ParmVarDecl *parm = (*PVars)[i])
6604 assert(parm->getFunctionScopeIndex() == i);
6605 }
6606#endif
6607
6608 return false;
6609}
6610
6611template<typename Derived>
6612QualType
6613TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6614 FunctionProtoTypeLoc TL) {
6615 SmallVector<QualType, 4> ExceptionStorage;
6616 return getDerived().TransformFunctionProtoType(
6617 TLB, TL, nullptr, Qualifiers(),
6618 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6619 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6620 ExceptionStorage, Changed);
6621 });
6622}
6623
6624template<typename Derived> template<typename Fn>
6625QualType TreeTransform<Derived>::TransformFunctionProtoType(
6626 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6627 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6628
6629 // Transform the parameters and return type.
6630 //
6631 // We are required to instantiate the params and return type in source order.
6632 // When the function has a trailing return type, we instantiate the
6633 // parameters before the return type, since the return type can then refer
6634 // to the parameters themselves (via decltype, sizeof, etc.).
6635 //
6636 SmallVector<QualType, 4> ParamTypes;
6637 SmallVector<ParmVarDecl*, 4> ParamDecls;
6638 Sema::ExtParameterInfoBuilder ExtParamInfos;
6639 const FunctionProtoType *T = TL.getTypePtr();
6640
6641 QualType ResultType;
6642
6643 if (T->hasTrailingReturn()) {
6644 if (getDerived().TransformFunctionTypeParams(
6645 TL.getBeginLoc(), TL.getParams(),
6646 TL.getTypePtr()->param_type_begin(),
6647 T->getExtParameterInfosOrNull(),
6648 ParamTypes, &ParamDecls, ExtParamInfos))
6649 return QualType();
6650
6651 {
6652 // C++11 [expr.prim.general]p3:
6653 // If a declaration declares a member function or member function
6654 // template of a class X, the expression this is a prvalue of type
6655 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6656 // and the end of the function-definition, member-declarator, or
6657 // declarator.
6658 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6659 Sema::CXXThisScopeRAII ThisScope(
6660 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6661
6662 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6663 if (ResultType.isNull())
6664 return QualType();
6665 }
6666 }
6667 else {
6668 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6669 if (ResultType.isNull())
6670 return QualType();
6671
6672 if (getDerived().TransformFunctionTypeParams(
6673 TL.getBeginLoc(), TL.getParams(),
6674 TL.getTypePtr()->param_type_begin(),
6675 T->getExtParameterInfosOrNull(),
6676 ParamTypes, &ParamDecls, ExtParamInfos))
6677 return QualType();
6678 }
6679
6680 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6681
6682 bool EPIChanged = false;
6683 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6684 return QualType();
6685
6686 // Handle extended parameter information.
6687 if (auto NewExtParamInfos =
6688 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6689 if (!EPI.ExtParameterInfos ||
6690 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6691 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6692 EPIChanged = true;
6693 }
6694 EPI.ExtParameterInfos = NewExtParamInfos;
6695 } else if (EPI.ExtParameterInfos) {
6696 EPIChanged = true;
6697 EPI.ExtParameterInfos = nullptr;
6698 }
6699
6700 // Transform any function effects with unevaluated conditions.
6701 // Hold this set in a local for the rest of this function, since EPI
6702 // may need to hold a FunctionEffectsRef pointing into it.
6703 std::optional<FunctionEffectSet> NewFX;
6704 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6705 NewFX.emplace();
6706 EnterExpressionEvaluationContext Unevaluated(
6707 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6708
6709 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6710 FunctionEffectWithCondition NewEC = PrevEC;
6711 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6712 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6713 if (NewExpr.isInvalid())
6714 return QualType();
6715 std::optional<FunctionEffectMode> Mode =
6716 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6717 if (!Mode)
6718 return QualType();
6719
6720 // The condition expression has been transformed, and re-evaluated.
6721 // It may or may not have become constant.
6722 switch (*Mode) {
6723 case FunctionEffectMode::True:
6724 NewEC.Cond = {};
6725 break;
6726 case FunctionEffectMode::False:
6727 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6728 NewEC.Cond = {};
6729 break;
6730 case FunctionEffectMode::Dependent:
6731 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6732 break;
6733 case FunctionEffectMode::None:
6734 llvm_unreachable(
6735 "FunctionEffectMode::None shouldn't be possible here");
6736 }
6737 }
6738 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6739 NewAttrLoc: TL.getBeginLoc())) {
6740 FunctionEffectSet::Conflicts Errs;
6741 NewFX->insert(NewEC, Errs);
6742 assert(Errs.empty());
6743 }
6744 }
6745 EPI.FunctionEffects = *NewFX;
6746 EPIChanged = true;
6747 }
6748
6749 QualType Result = TL.getType();
6750 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6751 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6752 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6753 if (Result.isNull())
6754 return QualType();
6755 }
6756
6757 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6758 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6759 NewTL.setLParenLoc(TL.getLParenLoc());
6760 NewTL.setRParenLoc(TL.getRParenLoc());
6761 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6762 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6763 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6764 NewTL.setParam(i, VD: ParamDecls[i]);
6765
6766 return Result;
6767}
6768
6769template<typename Derived>
6770bool TreeTransform<Derived>::TransformExceptionSpec(
6771 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6772 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6773 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6774
6775 // Instantiate a dynamic noexcept expression, if any.
6776 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6777 // Update this scrope because ContextDecl in Sema will be used in
6778 // TransformExpr.
6779 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6780 Sema::CXXThisScopeRAII ThisScope(
6781 SemaRef, Method ? Method->getParent() : nullptr,
6782 Method ? Method->getMethodQualifiers() : Qualifiers{},
6783 Method != nullptr);
6784 EnterExpressionEvaluationContext Unevaluated(
6785 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6786 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6787 if (NoexceptExpr.isInvalid())
6788 return true;
6789
6790 ExceptionSpecificationType EST = ESI.Type;
6791 NoexceptExpr =
6792 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6793 if (NoexceptExpr.isInvalid())
6794 return true;
6795
6796 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6797 Changed = true;
6798 ESI.NoexceptExpr = NoexceptExpr.get();
6799 ESI.Type = EST;
6800 }
6801
6802 if (ESI.Type != EST_Dynamic)
6803 return false;
6804
6805 // Instantiate a dynamic exception specification's type.
6806 for (QualType T : ESI.Exceptions) {
6807 if (const PackExpansionType *PackExpansion =
6808 T->getAs<PackExpansionType>()) {
6809 Changed = true;
6810
6811 // We have a pack expansion. Instantiate it.
6812 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6813 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6814 Unexpanded);
6815 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6816
6817 // Determine whether the set of unexpanded parameter packs can and
6818 // should
6819 // be expanded.
6820 bool Expand = false;
6821 bool RetainExpansion = false;
6822 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6823 // FIXME: Track the location of the ellipsis (and track source location
6824 // information for the types in the exception specification in general).
6825 if (getDerived().TryExpandParameterPacks(
6826 Loc, SourceRange(), Unexpanded,
6827 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
6828 NumExpansions))
6829 return true;
6830
6831 if (!Expand) {
6832 // We can't expand this pack expansion into separate arguments yet;
6833 // just substitute into the pattern and create a new pack expansion
6834 // type.
6835 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6836 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6837 if (U.isNull())
6838 return true;
6839
6840 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6841 Exceptions.push_back(Elt: U);
6842 continue;
6843 }
6844
6845 // Substitute into the pack expansion pattern for each slice of the
6846 // pack.
6847 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6848 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6849
6850 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6851 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6852 return true;
6853
6854 Exceptions.push_back(Elt: U);
6855 }
6856 } else {
6857 QualType U = getDerived().TransformType(T);
6858 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6859 return true;
6860 if (T != U)
6861 Changed = true;
6862
6863 Exceptions.push_back(Elt: U);
6864 }
6865 }
6866
6867 ESI.Exceptions = Exceptions;
6868 if (ESI.Exceptions.empty())
6869 ESI.Type = EST_DynamicNone;
6870 return false;
6871}
6872
6873template<typename Derived>
6874QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6875 TypeLocBuilder &TLB,
6876 FunctionNoProtoTypeLoc TL) {
6877 const FunctionNoProtoType *T = TL.getTypePtr();
6878 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6879 if (ResultType.isNull())
6880 return QualType();
6881
6882 QualType Result = TL.getType();
6883 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6884 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6885
6886 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6887 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6888 NewTL.setLParenLoc(TL.getLParenLoc());
6889 NewTL.setRParenLoc(TL.getRParenLoc());
6890 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6891
6892 return Result;
6893}
6894
6895template <typename Derived>
6896QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6897 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6898
6899 const UnresolvedUsingType *T = TL.getTypePtr();
6900 bool Changed = false;
6901
6902 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6903 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6904 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6905 if (!QualifierLoc)
6906 return QualType();
6907 Changed |= QualifierLoc != OldQualifierLoc;
6908 }
6909
6910 auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6911 if (!D)
6912 return QualType();
6913 Changed |= D != T->getDecl();
6914
6915 QualType Result = TL.getType();
6916 if (getDerived().AlwaysRebuild() || Changed) {
6917 Result = getDerived().RebuildUnresolvedUsingType(
6918 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
6919 D);
6920 if (Result.isNull())
6921 return QualType();
6922 }
6923
6924 if (isa<UsingType>(Val: Result))
6925 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6926 QualifierLoc, NameLoc: TL.getNameLoc());
6927 else
6928 TLB.push<UnresolvedUsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
6929 QualifierLoc, NameLoc: TL.getNameLoc());
6930 return Result;
6931}
6932
6933template <typename Derived>
6934QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6935 UsingTypeLoc TL) {
6936 const UsingType *T = TL.getTypePtr();
6937 bool Changed = false;
6938
6939 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6940 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6941 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6942 if (!QualifierLoc)
6943 return QualType();
6944 Changed |= QualifierLoc != OldQualifierLoc;
6945 }
6946
6947 auto *D = cast_or_null<UsingShadowDecl>(
6948 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6949 if (!D)
6950 return QualType();
6951 Changed |= D != T->getDecl();
6952
6953 QualType UnderlyingType = getDerived().TransformType(T->desugar());
6954 if (UnderlyingType.isNull())
6955 return QualType();
6956 Changed |= UnderlyingType != T->desugar();
6957
6958 QualType Result = TL.getType();
6959 if (getDerived().AlwaysRebuild() || Changed) {
6960 Result = getDerived().RebuildUsingType(
6961 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
6962 UnderlyingType);
6963 if (Result.isNull())
6964 return QualType();
6965 }
6966 TLB.push<UsingTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc,
6967 NameLoc: TL.getNameLoc());
6968 return Result;
6969}
6970
6971template<typename Derived>
6972QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6973 TypedefTypeLoc TL) {
6974 const TypedefType *T = TL.getTypePtr();
6975 bool Changed = false;
6976
6977 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
6978 if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
6979 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
6980 if (!QualifierLoc)
6981 return QualType();
6982 Changed |= QualifierLoc != OldQualifierLoc;
6983 }
6984
6985 auto *Typedef = cast_or_null<TypedefNameDecl>(
6986 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
6987 if (!Typedef)
6988 return QualType();
6989 Changed |= Typedef != T->getDecl();
6990
6991 // FIXME: Transform the UnderlyingType if different from decl.
6992
6993 QualType Result = TL.getType();
6994 if (getDerived().AlwaysRebuild() || Changed) {
6995 Result = getDerived().RebuildTypedefType(
6996 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
6997 if (Result.isNull())
6998 return QualType();
6999 }
7000
7001 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7002 QualifierLoc, NameLoc: TL.getNameLoc());
7003 return Result;
7004}
7005
7006template<typename Derived>
7007QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
7008 TypeOfExprTypeLoc TL) {
7009 // typeof expressions are not potentially evaluated contexts
7010 EnterExpressionEvaluationContext Unevaluated(
7011 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
7012 Sema::ReuseLambdaContextDecl);
7013
7014 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
7015 if (E.isInvalid())
7016 return QualType();
7017
7018 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
7019 if (E.isInvalid())
7020 return QualType();
7021
7022 QualType Result = TL.getType();
7023 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
7024 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
7025 Result =
7026 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
7027 if (Result.isNull())
7028 return QualType();
7029 }
7030
7031 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
7032 NewTL.setTypeofLoc(TL.getTypeofLoc());
7033 NewTL.setLParenLoc(TL.getLParenLoc());
7034 NewTL.setRParenLoc(TL.getRParenLoc());
7035
7036 return Result;
7037}
7038
7039template<typename Derived>
7040QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
7041 TypeOfTypeLoc TL) {
7042 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
7043 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
7044 if (!New_Under_TI)
7045 return QualType();
7046
7047 QualType Result = TL.getType();
7048 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
7049 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
7050 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
7051 if (Result.isNull())
7052 return QualType();
7053 }
7054
7055 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
7056 NewTL.setTypeofLoc(TL.getTypeofLoc());
7057 NewTL.setLParenLoc(TL.getLParenLoc());
7058 NewTL.setRParenLoc(TL.getRParenLoc());
7059 NewTL.setUnmodifiedTInfo(New_Under_TI);
7060
7061 return Result;
7062}
7063
7064template<typename Derived>
7065QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
7066 DecltypeTypeLoc TL) {
7067 const DecltypeType *T = TL.getTypePtr();
7068
7069 // decltype expressions are not potentially evaluated contexts
7070 EnterExpressionEvaluationContext Unevaluated(
7071 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
7072 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
7073
7074 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
7075 if (E.isInvalid())
7076 return QualType();
7077
7078 E = getSema().ActOnDecltypeExpression(E.get());
7079 if (E.isInvalid())
7080 return QualType();
7081
7082 QualType Result = TL.getType();
7083 if (getDerived().AlwaysRebuild() ||
7084 E.get() != T->getUnderlyingExpr()) {
7085 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
7086 if (Result.isNull())
7087 return QualType();
7088 }
7089 else E.get();
7090
7091 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
7092 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
7093 NewTL.setRParenLoc(TL.getRParenLoc());
7094 return Result;
7095}
7096
7097template <typename Derived>
7098QualType
7099TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
7100 PackIndexingTypeLoc TL) {
7101 // Transform the index
7102 ExprResult IndexExpr;
7103 {
7104 EnterExpressionEvaluationContext ConstantContext(
7105 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7106
7107 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
7108 if (IndexExpr.isInvalid())
7109 return QualType();
7110 }
7111 QualType Pattern = TL.getPattern();
7112
7113 const PackIndexingType *PIT = TL.getTypePtr();
7114 SmallVector<QualType, 5> SubtitutedTypes;
7115 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
7116
7117 bool NotYetExpanded = Types.empty();
7118 bool FullySubstituted = true;
7119
7120 if (Types.empty() && !PIT->expandsToEmptyPack())
7121 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
7122
7123 for (QualType T : Types) {
7124 if (!T->containsUnexpandedParameterPack()) {
7125 QualType Transformed = getDerived().TransformType(T);
7126 if (Transformed.isNull())
7127 return QualType();
7128 SubtitutedTypes.push_back(Elt: Transformed);
7129 continue;
7130 }
7131
7132 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7133 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
7134 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7135 // Determine whether the set of unexpanded parameter packs can and should
7136 // be expanded.
7137 bool ShouldExpand = true;
7138 bool RetainExpansion = false;
7139 UnsignedOrNone NumExpansions = std::nullopt;
7140 if (getDerived().TryExpandParameterPacks(
7141 TL.getEllipsisLoc(), SourceRange(), Unexpanded,
7142 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
7143 RetainExpansion, NumExpansions))
7144 return QualType();
7145 if (!ShouldExpand) {
7146 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7147 // FIXME: should we keep TypeLoc for individual expansions in
7148 // PackIndexingTypeLoc?
7149 TypeSourceInfo *TI =
7150 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
7151 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
7152 if (Pack.isNull())
7153 return QualType();
7154 if (NotYetExpanded) {
7155 FullySubstituted = false;
7156 QualType Out = getDerived().RebuildPackIndexingType(
7157 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7158 FullySubstituted);
7159 if (Out.isNull())
7160 return QualType();
7161
7162 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7163 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7164 return Out;
7165 }
7166 SubtitutedTypes.push_back(Elt: Pack);
7167 continue;
7168 }
7169 for (unsigned I = 0; I != *NumExpansions; ++I) {
7170 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
7171 QualType Out = getDerived().TransformType(T);
7172 if (Out.isNull())
7173 return QualType();
7174 SubtitutedTypes.push_back(Elt: Out);
7175 FullySubstituted &= !Out->containsUnexpandedParameterPack();
7176 }
7177 // If we're supposed to retain a pack expansion, do so by temporarily
7178 // forgetting the partially-substituted parameter pack.
7179 if (RetainExpansion) {
7180 FullySubstituted = false;
7181 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
7182 QualType Out = getDerived().TransformType(T);
7183 if (Out.isNull())
7184 return QualType();
7185 SubtitutedTypes.push_back(Elt: Out);
7186 }
7187 }
7188
7189 // A pack indexing type can appear in a larger pack expansion,
7190 // e.g. `Pack...[pack_of_indexes]...`
7191 // so we need to temporarily disable substitution of pack elements
7192 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7193 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
7194
7195 QualType Out = getDerived().RebuildPackIndexingType(
7196 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
7197 FullySubstituted, SubtitutedTypes);
7198 if (Out.isNull())
7199 return Out;
7200
7201 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
7202 Loc.setEllipsisLoc(TL.getEllipsisLoc());
7203 return Out;
7204}
7205
7206template<typename Derived>
7207QualType TreeTransform<Derived>::TransformUnaryTransformType(
7208 TypeLocBuilder &TLB,
7209 UnaryTransformTypeLoc TL) {
7210 QualType Result = TL.getType();
7211 TypeSourceInfo *NewBaseTSI = TL.getUnderlyingTInfo();
7212 if (Result->isDependentType()) {
7213 const UnaryTransformType *T = TL.getTypePtr();
7214
7215 NewBaseTSI = getDerived().TransformType(TL.getUnderlyingTInfo());
7216 if (!NewBaseTSI)
7217 return QualType();
7218 QualType NewBase = NewBaseTSI->getType();
7219
7220 Result = getDerived().RebuildUnaryTransformType(NewBase,
7221 T->getUTTKind(),
7222 TL.getKWLoc());
7223 if (Result.isNull())
7224 return QualType();
7225 }
7226
7227 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
7228 NewTL.setKWLoc(TL.getKWLoc());
7229 NewTL.setParensRange(TL.getParensRange());
7230 NewTL.setUnderlyingTInfo(NewBaseTSI);
7231 return Result;
7232}
7233
7234template<typename Derived>
7235QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
7236 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
7237 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
7238
7239 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7240 TemplateName TemplateName = getDerived().TransformTemplateName(
7241 QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
7242 TL.getTemplateNameLoc());
7243 if (TemplateName.isNull())
7244 return QualType();
7245
7246 QualType OldDeduced = T->getDeducedType();
7247 QualType NewDeduced;
7248 if (!OldDeduced.isNull()) {
7249 NewDeduced = getDerived().TransformType(OldDeduced);
7250 if (NewDeduced.isNull())
7251 return QualType();
7252 }
7253
7254 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7255 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7256 NewDeduced, T->getKeyword(), TemplateName);
7257 if (Result.isNull())
7258 return QualType();
7259
7260 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7261 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7262 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7263 NewTL.setQualifierLoc(QualifierLoc);
7264 return Result;
7265}
7266
7267template <typename Derived>
7268QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
7269 TagTypeLoc TL) {
7270 const TagType *T = TL.getTypePtr();
7271
7272 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7273 if (QualifierLoc) {
7274 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
7275 if (!QualifierLoc)
7276 return QualType();
7277 }
7278
7279 auto *TD = cast_or_null<TagDecl>(
7280 getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
7281 if (!TD)
7282 return QualType();
7283
7284 QualType Result = TL.getType();
7285 if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
7286 TD != T->getDecl()) {
7287 if (T->isCanonicalUnqualified())
7288 Result = getDerived().RebuildCanonicalTagType(TD);
7289 else
7290 Result = getDerived().RebuildTagType(
7291 T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
7292 if (Result.isNull())
7293 return QualType();
7294 }
7295
7296 TagTypeLoc NewTL = TLB.push<TagTypeLoc>(T: Result);
7297 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7298 NewTL.setQualifierLoc(QualifierLoc);
7299 NewTL.setNameLoc(TL.getNameLoc());
7300
7301 return Result;
7302}
7303
7304template <typename Derived>
7305QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7306 EnumTypeLoc TL) {
7307 return getDerived().TransformTagType(TLB, TL);
7308}
7309
7310template <typename Derived>
7311QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7312 RecordTypeLoc TL) {
7313 return getDerived().TransformTagType(TLB, TL);
7314}
7315
7316template<typename Derived>
7317QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7318 TypeLocBuilder &TLB,
7319 InjectedClassNameTypeLoc TL) {
7320 return getDerived().TransformTagType(TLB, TL);
7321}
7322
7323template<typename Derived>
7324QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7325 TypeLocBuilder &TLB,
7326 TemplateTypeParmTypeLoc TL) {
7327 return getDerived().TransformTemplateTypeParmType(
7328 TLB, TL,
7329 /*SuppressObjCLifetime=*/false);
7330}
7331
7332template <typename Derived>
7333QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7334 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7335 return TransformTypeSpecType(TLB, T: TL);
7336}
7337
7338template<typename Derived>
7339QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7340 TypeLocBuilder &TLB,
7341 SubstTemplateTypeParmTypeLoc TL) {
7342 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7343
7344 Decl *NewReplaced =
7345 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7346
7347 // Substitute into the replacement type, which itself might involve something
7348 // that needs to be transformed. This only tends to occur with default
7349 // template arguments of template template parameters.
7350 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7351 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7352 if (Replacement.isNull())
7353 return QualType();
7354
7355 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7356 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7357 Final: T->getFinal());
7358
7359 // Propagate type-source information.
7360 SubstTemplateTypeParmTypeLoc NewTL
7361 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7362 NewTL.setNameLoc(TL.getNameLoc());
7363 return Result;
7364
7365}
7366template <typename Derived>
7367QualType TreeTransform<Derived>::TransformSubstBuiltinTemplatePackType(
7368 TypeLocBuilder &TLB, SubstBuiltinTemplatePackTypeLoc TL) {
7369 return TransformTypeSpecType(TLB, T: TL);
7370}
7371
7372template<typename Derived>
7373QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7374 TypeLocBuilder &TLB,
7375 SubstTemplateTypeParmPackTypeLoc TL) {
7376 return getDerived().TransformSubstTemplateTypeParmPackType(
7377 TLB, TL, /*SuppressObjCLifetime=*/false);
7378}
7379
7380template <typename Derived>
7381QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7382 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7383 return TransformTypeSpecType(TLB, T: TL);
7384}
7385
7386template<typename Derived>
7387QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7388 AtomicTypeLoc TL) {
7389 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7390 if (ValueType.isNull())
7391 return QualType();
7392
7393 QualType Result = TL.getType();
7394 if (getDerived().AlwaysRebuild() ||
7395 ValueType != TL.getValueLoc().getType()) {
7396 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7397 if (Result.isNull())
7398 return QualType();
7399 }
7400
7401 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7402 NewTL.setKWLoc(TL.getKWLoc());
7403 NewTL.setLParenLoc(TL.getLParenLoc());
7404 NewTL.setRParenLoc(TL.getRParenLoc());
7405
7406 return Result;
7407}
7408
7409template <typename Derived>
7410QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7411 PipeTypeLoc TL) {
7412 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7413 if (ValueType.isNull())
7414 return QualType();
7415
7416 QualType Result = TL.getType();
7417 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7418 const PipeType *PT = Result->castAs<PipeType>();
7419 bool isReadPipe = PT->isReadOnly();
7420 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7421 if (Result.isNull())
7422 return QualType();
7423 }
7424
7425 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7426 NewTL.setKWLoc(TL.getKWLoc());
7427
7428 return Result;
7429}
7430
7431template <typename Derived>
7432QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7433 BitIntTypeLoc TL) {
7434 const BitIntType *EIT = TL.getTypePtr();
7435 QualType Result = TL.getType();
7436
7437 if (getDerived().AlwaysRebuild()) {
7438 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7439 EIT->getNumBits(), TL.getNameLoc());
7440 if (Result.isNull())
7441 return QualType();
7442 }
7443
7444 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7445 NewTL.setNameLoc(TL.getNameLoc());
7446 return Result;
7447}
7448
7449template <typename Derived>
7450QualType TreeTransform<Derived>::TransformDependentBitIntType(
7451 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7452 const DependentBitIntType *EIT = TL.getTypePtr();
7453
7454 EnterExpressionEvaluationContext Unevaluated(
7455 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7456 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7457 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7458
7459 if (BitsExpr.isInvalid())
7460 return QualType();
7461
7462 QualType Result = TL.getType();
7463
7464 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7465 Result = getDerived().RebuildDependentBitIntType(
7466 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7467
7468 if (Result.isNull())
7469 return QualType();
7470 }
7471
7472 if (isa<DependentBitIntType>(Val: Result)) {
7473 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7474 NewTL.setNameLoc(TL.getNameLoc());
7475 } else {
7476 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7477 NewTL.setNameLoc(TL.getNameLoc());
7478 }
7479 return Result;
7480}
7481
7482template <typename Derived>
7483QualType TreeTransform<Derived>::TransformPredefinedSugarType(
7484 TypeLocBuilder &TLB, PredefinedSugarTypeLoc TL) {
7485 llvm_unreachable("This type does not need to be transformed.");
7486}
7487
7488 /// Simple iterator that traverses the template arguments in a
7489 /// container that provides a \c getArgLoc() member function.
7490 ///
7491 /// This iterator is intended to be used with the iterator form of
7492 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7493 template<typename ArgLocContainer>
7494 class TemplateArgumentLocContainerIterator {
7495 ArgLocContainer *Container;
7496 unsigned Index;
7497
7498 public:
7499 typedef TemplateArgumentLoc value_type;
7500 typedef TemplateArgumentLoc reference;
7501 typedef int difference_type;
7502 typedef std::input_iterator_tag iterator_category;
7503
7504 class pointer {
7505 TemplateArgumentLoc Arg;
7506
7507 public:
7508 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7509
7510 const TemplateArgumentLoc *operator->() const {
7511 return &Arg;
7512 }
7513 };
7514
7515
7516 TemplateArgumentLocContainerIterator() {}
7517
7518 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7519 unsigned Index)
7520 : Container(&Container), Index(Index) { }
7521
7522 TemplateArgumentLocContainerIterator &operator++() {
7523 ++Index;
7524 return *this;
7525 }
7526
7527 TemplateArgumentLocContainerIterator operator++(int) {
7528 TemplateArgumentLocContainerIterator Old(*this);
7529 ++(*this);
7530 return Old;
7531 }
7532
7533 TemplateArgumentLoc operator*() const {
7534 return Container->getArgLoc(Index);
7535 }
7536
7537 pointer operator->() const {
7538 return pointer(Container->getArgLoc(Index));
7539 }
7540
7541 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7542 const TemplateArgumentLocContainerIterator &Y) {
7543 return X.Container == Y.Container && X.Index == Y.Index;
7544 }
7545
7546 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7547 const TemplateArgumentLocContainerIterator &Y) {
7548 return !(X == Y);
7549 }
7550 };
7551
7552template<typename Derived>
7553QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7554 AutoTypeLoc TL) {
7555 const AutoType *T = TL.getTypePtr();
7556 QualType OldDeduced = T->getDeducedType();
7557 QualType NewDeduced;
7558 if (!OldDeduced.isNull()) {
7559 NewDeduced = getDerived().TransformType(OldDeduced);
7560 if (NewDeduced.isNull())
7561 return QualType();
7562 }
7563
7564 ConceptDecl *NewCD = nullptr;
7565 TemplateArgumentListInfo NewTemplateArgs;
7566 NestedNameSpecifierLoc NewNestedNameSpec;
7567 if (T->isConstrained()) {
7568 assert(TL.getConceptReference());
7569 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7570 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7571
7572 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7573 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7574 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7575 if (getDerived().TransformTemplateArguments(
7576 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7577 NewTemplateArgs))
7578 return QualType();
7579
7580 if (TL.getNestedNameSpecifierLoc()) {
7581 NewNestedNameSpec
7582 = getDerived().TransformNestedNameSpecifierLoc(
7583 TL.getNestedNameSpecifierLoc());
7584 if (!NewNestedNameSpec)
7585 return QualType();
7586 }
7587 }
7588
7589 QualType Result = TL.getType();
7590 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7591 T->isDependentType() || T->isConstrained()) {
7592 // FIXME: Maybe don't rebuild if all template arguments are the same.
7593 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7594 NewArgList.reserve(N: NewTemplateArgs.size());
7595 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7596 NewArgList.push_back(Elt: ArgLoc.getArgument());
7597 Result = getDerived().RebuildAutoType(
7598 NewDeduced.isNull() ? DeducedKind::Undeduced : DeducedKind::Deduced,
7599 NewDeduced, T->getKeyword(), NewCD, NewArgList);
7600 if (Result.isNull())
7601 return QualType();
7602 }
7603
7604 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7605 NewTL.setNameLoc(TL.getNameLoc());
7606 NewTL.setRParenLoc(TL.getRParenLoc());
7607 NewTL.setConceptReference(nullptr);
7608
7609 if (T->isConstrained()) {
7610 DeclarationNameInfo DNI = DeclarationNameInfo(
7611 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7612 TL.getConceptNameLoc(),
7613 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7614 auto *CR = ConceptReference::Create(
7615 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7616 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7617 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7618 NewTL.setConceptReference(CR);
7619 }
7620
7621 return Result;
7622}
7623
7624template <typename Derived>
7625QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7626 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
7627 return getDerived().TransformTemplateSpecializationType(
7628 TLB, TL, /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7629 /*AllowInjectedClassName=*/false);
7630}
7631
7632template <typename Derived>
7633QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7634 TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL, QualType ObjectType,
7635 NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
7636 const TemplateSpecializationType *T = TL.getTypePtr();
7637
7638 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7639 TemplateName Template = getDerived().TransformTemplateName(
7640 QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
7641 TL.getTemplateNameLoc(), ObjectType, FirstQualifierInScope,
7642 AllowInjectedClassName);
7643 if (Template.isNull())
7644 return QualType();
7645
7646 TemplateArgumentListInfo NewTemplateArgs;
7647 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7648 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7649 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7650 ArgIterator;
7651 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7652 ArgIterator(TL, TL.getNumArgs()),
7653 NewTemplateArgs))
7654 return QualType();
7655
7656 // This needs to be rebuilt if either the arguments changed, or if the
7657 // original template changed. If the template changed, and even if the
7658 // arguments didn't change, these arguments might not correspond to their
7659 // respective parameters, therefore needing conversions.
7660 QualType Result = getDerived().RebuildTemplateSpecializationType(
7661 TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
7662 NewTemplateArgs);
7663
7664 if (!Result.isNull()) {
7665 TLB.push<TemplateSpecializationTypeLoc>(T: Result).set(
7666 ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, TemplateKeywordLoc: TL.getTemplateKeywordLoc(),
7667 NameLoc: TL.getTemplateNameLoc(), TAL: NewTemplateArgs);
7668 }
7669
7670 return Result;
7671}
7672
7673template <typename Derived>
7674QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7675 AttributedTypeLoc TL) {
7676 const AttributedType *oldType = TL.getTypePtr();
7677 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7678 if (modifiedType.isNull())
7679 return QualType();
7680
7681 // HLSL: re-validate matrix-layout markers after substitution. If the
7682 // post-substitution type is no longer a matrix, diagnose now.
7683 if (SemaRef.getLangOpts().HLSL &&
7684 SemaRef.HLSL().diagnoseMatrixLayoutInstantiation(
7685 K: oldType->getAttrKind(), T: modifiedType,
7686 Loc: TL.getAttr() ? TL.getAttr()->getLocation()
7687 : TL.getModifiedLoc().getBeginLoc()))
7688 return QualType();
7689
7690 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7691 const Attr *oldAttr = TL.getAttr();
7692 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7693 if (oldAttr && !newAttr)
7694 return QualType();
7695
7696 QualType result = TL.getType();
7697
7698 // FIXME: dependent operand expressions?
7699 if (getDerived().AlwaysRebuild() ||
7700 modifiedType != oldType->getModifiedType()) {
7701 // If the equivalent type is equal to the modified type, we don't want to
7702 // transform it as well because:
7703 //
7704 // 1. The transformation would yield the same result and is therefore
7705 // superfluous, and
7706 //
7707 // 2. Transforming the same type twice can cause problems, e.g. if it
7708 // is a FunctionProtoType, we may end up instantiating the function
7709 // parameters twice, which causes an assertion since the parameters
7710 // are already bound to their counterparts in the template for this
7711 // instantiation.
7712 //
7713 QualType equivalentType = modifiedType;
7714 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7715 TypeLocBuilder AuxiliaryTLB;
7716 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7717 equivalentType =
7718 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7719 if (equivalentType.isNull())
7720 return QualType();
7721 }
7722
7723 // Check whether we can add nullability; it is only represented as
7724 // type sugar, and therefore cannot be diagnosed in any other way.
7725 if (auto nullability = oldType->getImmediateNullability()) {
7726 if (!modifiedType->canHaveNullability()) {
7727 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7728 : TL.getModifiedLoc().getBeginLoc()),
7729 DiagID: diag::err_nullability_nonpointer)
7730 << DiagNullabilityKind(*nullability, false) << modifiedType;
7731 return QualType();
7732 }
7733 }
7734
7735 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7736 modifiedType,
7737 equivalentType,
7738 attr: TL.getAttr());
7739 }
7740
7741 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7742 newTL.setAttr(newAttr);
7743 return result;
7744}
7745
7746template <typename Derived>
7747QualType TreeTransform<Derived>::TransformCountAttributedType(
7748 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7749 const CountAttributedType *OldTy = TL.getTypePtr();
7750 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7751 if (InnerTy.isNull())
7752 return QualType();
7753
7754 Expr *OldCount = TL.getCountExpr();
7755 Expr *NewCount = nullptr;
7756 if (OldCount) {
7757 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7758 if (CountResult.isInvalid())
7759 return QualType();
7760 NewCount = CountResult.get();
7761 }
7762
7763 QualType Result = TL.getType();
7764 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7765 OldCount != NewCount) {
7766 // Currently, CountAttributedType can only wrap incomplete array types.
7767 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7768 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7769 }
7770
7771 TLB.push<CountAttributedTypeLoc>(T: Result);
7772 return Result;
7773}
7774
7775template <typename Derived>
7776QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7777 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7778 // The BTFTagAttributedType is available for C only.
7779 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7780}
7781
7782template <typename Derived>
7783QualType TreeTransform<Derived>::TransformOverflowBehaviorType(
7784 TypeLocBuilder &TLB, OverflowBehaviorTypeLoc TL) {
7785 const OverflowBehaviorType *OldTy = TL.getTypePtr();
7786 QualType InnerTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7787 if (InnerTy.isNull())
7788 return QualType();
7789
7790 QualType Result = TL.getType();
7791 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->getUnderlyingType()) {
7792 Result = SemaRef.Context.getOverflowBehaviorType(Kind: OldTy->getBehaviorKind(),
7793 Wrapped: InnerTy);
7794 if (Result.isNull())
7795 return QualType();
7796 }
7797
7798 OverflowBehaviorTypeLoc NewTL = TLB.push<OverflowBehaviorTypeLoc>(T: Result);
7799 NewTL.initializeLocal(Context&: SemaRef.Context, loc: TL.getAttrLoc());
7800 return Result;
7801}
7802
7803template <typename Derived>
7804QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7805 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7806
7807 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7808
7809 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7810 if (WrappedTy.isNull())
7811 return QualType();
7812
7813 QualType ContainedTy = QualType();
7814 QualType OldContainedTy = oldType->getContainedType();
7815 TypeSourceInfo *ContainedTSI = nullptr;
7816 if (!OldContainedTy.isNull()) {
7817 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7818 if (!oldContainedTSI)
7819 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7820 OldContainedTy, SourceLocation());
7821 ContainedTSI = getDerived().TransformType(oldContainedTSI);
7822 if (!ContainedTSI)
7823 return QualType();
7824 ContainedTy = ContainedTSI->getType();
7825 }
7826
7827 QualType Result = TL.getType();
7828 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7829 ContainedTy != oldType->getContainedType()) {
7830 Result = SemaRef.Context.getHLSLAttributedResourceType(
7831 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7832 }
7833
7834 HLSLAttributedResourceTypeLoc NewTL =
7835 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7836 NewTL.setSourceRange(TL.getLocalSourceRange());
7837 NewTL.setContainedTypeSourceInfo(ContainedTSI);
7838 return Result;
7839}
7840
7841template <typename Derived>
7842QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7843 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7844 // No transformations needed.
7845 return TL.getType();
7846}
7847
7848template<typename Derived>
7849QualType
7850TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7851 ParenTypeLoc TL) {
7852 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7853 if (Inner.isNull())
7854 return QualType();
7855
7856 QualType Result = TL.getType();
7857 if (getDerived().AlwaysRebuild() ||
7858 Inner != TL.getInnerLoc().getType()) {
7859 Result = getDerived().RebuildParenType(Inner);
7860 if (Result.isNull())
7861 return QualType();
7862 }
7863
7864 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7865 NewTL.setLParenLoc(TL.getLParenLoc());
7866 NewTL.setRParenLoc(TL.getRParenLoc());
7867 return Result;
7868}
7869
7870template <typename Derived>
7871QualType
7872TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7873 MacroQualifiedTypeLoc TL) {
7874 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7875 if (Inner.isNull())
7876 return QualType();
7877
7878 QualType Result = TL.getType();
7879 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7880 Result =
7881 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7882 if (Result.isNull())
7883 return QualType();
7884 }
7885
7886 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7887 NewTL.setExpansionLoc(TL.getExpansionLoc());
7888 return Result;
7889}
7890
7891template<typename Derived>
7892QualType TreeTransform<Derived>::TransformDependentNameType(
7893 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7894 return TransformDependentNameType(TLB, TL, false);
7895}
7896
7897template <typename Derived>
7898QualType TreeTransform<Derived>::TransformDependentNameType(
7899 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
7900 QualType ObjectType, NamedDecl *UnqualLookup) {
7901 const DependentNameType *T = TL.getTypePtr();
7902
7903 NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
7904 if (QualifierLoc) {
7905 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
7906 QualifierLoc, ObjectType, UnqualLookup);
7907 if (!QualifierLoc)
7908 return QualType();
7909 } else {
7910 assert((ObjectType.isNull() && !UnqualLookup) &&
7911 "must be transformed by TransformNestedNameSpecifierLoc");
7912 }
7913
7914 QualType Result
7915 = getDerived().RebuildDependentNameType(T->getKeyword(),
7916 TL.getElaboratedKeywordLoc(),
7917 QualifierLoc,
7918 T->getIdentifier(),
7919 TL.getNameLoc(),
7920 DeducedTSTContext);
7921 if (Result.isNull())
7922 return QualType();
7923
7924 if (isa<TagType>(Val: Result)) {
7925 auto NewTL = TLB.push<TagTypeLoc>(T: Result);
7926 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7927 NewTL.setQualifierLoc(QualifierLoc);
7928 NewTL.setNameLoc(TL.getNameLoc());
7929 } else if (isa<DeducedTemplateSpecializationType>(Val: Result)) {
7930 auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7931 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7932 NewTL.setTemplateNameLoc(TL.getNameLoc());
7933 NewTL.setQualifierLoc(QualifierLoc);
7934 } else if (isa<TypedefType>(Val: Result)) {
7935 TLB.push<TypedefTypeLoc>(T: Result).set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(),
7936 QualifierLoc, NameLoc: TL.getNameLoc());
7937 } else if (isa<UnresolvedUsingType>(Val: Result)) {
7938 auto NewTL = TLB.push<UnresolvedUsingTypeLoc>(T: Result);
7939 NewTL.set(ElaboratedKeywordLoc: TL.getElaboratedKeywordLoc(), QualifierLoc, NameLoc: TL.getNameLoc());
7940 } else {
7941 auto NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7942 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7943 NewTL.setQualifierLoc(QualifierLoc);
7944 NewTL.setNameLoc(TL.getNameLoc());
7945 }
7946 return Result;
7947}
7948
7949template<typename Derived>
7950QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7951 PackExpansionTypeLoc TL) {
7952 QualType Pattern
7953 = getDerived().TransformType(TLB, TL.getPatternLoc());
7954 if (Pattern.isNull())
7955 return QualType();
7956
7957 QualType Result = TL.getType();
7958 if (getDerived().AlwaysRebuild() ||
7959 Pattern != TL.getPatternLoc().getType()) {
7960 Result = getDerived().RebuildPackExpansionType(Pattern,
7961 TL.getPatternLoc().getSourceRange(),
7962 TL.getEllipsisLoc(),
7963 TL.getTypePtr()->getNumExpansions());
7964 if (Result.isNull())
7965 return QualType();
7966 }
7967
7968 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7969 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7970 return Result;
7971}
7972
7973template<typename Derived>
7974QualType
7975TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7976 ObjCInterfaceTypeLoc TL) {
7977 // ObjCInterfaceType is never dependent.
7978 TLB.pushFullCopy(L: TL);
7979 return TL.getType();
7980}
7981
7982template<typename Derived>
7983QualType
7984TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7985 ObjCTypeParamTypeLoc TL) {
7986 const ObjCTypeParamType *T = TL.getTypePtr();
7987 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7988 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7989 if (!OTP)
7990 return QualType();
7991
7992 QualType Result = TL.getType();
7993 if (getDerived().AlwaysRebuild() ||
7994 OTP != T->getDecl()) {
7995 Result = getDerived().RebuildObjCTypeParamType(
7996 OTP, TL.getProtocolLAngleLoc(),
7997 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7998 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7999 if (Result.isNull())
8000 return QualType();
8001 }
8002
8003 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
8004 if (TL.getNumProtocols()) {
8005 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8006 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8007 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8008 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8009 }
8010 return Result;
8011}
8012
8013template<typename Derived>
8014QualType
8015TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
8016 ObjCObjectTypeLoc TL) {
8017 // Transform base type.
8018 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
8019 if (BaseType.isNull())
8020 return QualType();
8021
8022 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
8023
8024 // Transform type arguments.
8025 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
8026 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
8027 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
8028 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
8029 QualType TypeArg = TypeArgInfo->getType();
8030 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
8031 AnyChanged = true;
8032
8033 // We have a pack expansion. Instantiate it.
8034 const auto *PackExpansion = PackExpansionLoc.getType()
8035 ->castAs<PackExpansionType>();
8036 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
8037 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
8038 Unexpanded);
8039 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
8040
8041 // Determine whether the set of unexpanded parameter packs can
8042 // and should be expanded.
8043 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
8044 bool Expand = false;
8045 bool RetainExpansion = false;
8046 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
8047 if (getDerived().TryExpandParameterPacks(
8048 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
8049 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
8050 RetainExpansion, NumExpansions))
8051 return QualType();
8052
8053 if (!Expand) {
8054 // We can't expand this pack expansion into separate arguments yet;
8055 // just substitute into the pattern and create a new pack expansion
8056 // type.
8057 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
8058
8059 TypeLocBuilder TypeArgBuilder;
8060 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8061 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
8062 PatternLoc);
8063 if (NewPatternType.isNull())
8064 return QualType();
8065
8066 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
8067 Pattern: NewPatternType, NumExpansions);
8068 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
8069 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
8070 NewTypeArgInfos.push_back(
8071 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8072 continue;
8073 }
8074
8075 // Substitute into the pack expansion pattern for each slice of the
8076 // pack.
8077 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8078 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8079
8080 TypeLocBuilder TypeArgBuilder;
8081 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8082
8083 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8084 PatternLoc);
8085 if (NewTypeArg.isNull())
8086 return QualType();
8087
8088 NewTypeArgInfos.push_back(
8089 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8090 }
8091
8092 continue;
8093 }
8094
8095 TypeLocBuilder TypeArgBuilder;
8096 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8097 QualType NewTypeArg =
8098 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8099 if (NewTypeArg.isNull())
8100 return QualType();
8101
8102 // If nothing changed, just keep the old TypeSourceInfo.
8103 if (NewTypeArg == TypeArg) {
8104 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8105 continue;
8106 }
8107
8108 NewTypeArgInfos.push_back(
8109 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8110 AnyChanged = true;
8111 }
8112
8113 QualType Result = TL.getType();
8114 if (getDerived().AlwaysRebuild() || AnyChanged) {
8115 // Rebuild the type.
8116 Result = getDerived().RebuildObjCObjectType(
8117 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8118 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8119 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8120 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8121
8122 if (Result.isNull())
8123 return QualType();
8124 }
8125
8126 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8127 NewT.setHasBaseTypeAsWritten(true);
8128 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8129 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8130 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8131 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8132 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8133 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8134 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8135 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8136 return Result;
8137}
8138
8139template<typename Derived>
8140QualType
8141TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8142 ObjCObjectPointerTypeLoc TL) {
8143 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8144 if (PointeeType.isNull())
8145 return QualType();
8146
8147 QualType Result = TL.getType();
8148 if (getDerived().AlwaysRebuild() ||
8149 PointeeType != TL.getPointeeLoc().getType()) {
8150 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8151 TL.getStarLoc());
8152 if (Result.isNull())
8153 return QualType();
8154 }
8155
8156 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8157 NewT.setStarLoc(TL.getStarLoc());
8158 return Result;
8159}
8160
8161//===----------------------------------------------------------------------===//
8162// Statement transformation
8163//===----------------------------------------------------------------------===//
8164template<typename Derived>
8165StmtResult
8166TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8167 return S;
8168}
8169
8170template<typename Derived>
8171StmtResult
8172TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8173 return getDerived().TransformCompoundStmt(S, false);
8174}
8175
8176template<typename Derived>
8177StmtResult
8178TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8179 bool IsStmtExpr) {
8180 Sema::CompoundScopeRAII CompoundScope(getSema());
8181 Sema::FPFeaturesStateRAII FPSave(getSema());
8182 if (S->hasStoredFPFeatures())
8183 getSema().resetFPOptions(
8184 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8185
8186 bool SubStmtInvalid = false;
8187 bool SubStmtChanged = false;
8188 SmallVector<Stmt*, 8> Statements;
8189 for (auto *B : S->body()) {
8190 StmtResult Result = getDerived().TransformStmt(
8191 B, IsStmtExpr && B == S->body_back() ? StmtDiscardKind::StmtExprResult
8192 : StmtDiscardKind::Discarded);
8193
8194 if (Result.isInvalid()) {
8195 // Immediately fail if this was a DeclStmt, since it's very
8196 // likely that this will cause problems for future statements.
8197 if (isa<DeclStmt>(Val: B))
8198 return StmtError();
8199
8200 // Otherwise, just keep processing substatements and fail later.
8201 SubStmtInvalid = true;
8202 continue;
8203 }
8204
8205 SubStmtChanged = SubStmtChanged || Result.get() != B;
8206 Statements.push_back(Elt: Result.getAs<Stmt>());
8207 }
8208
8209 if (SubStmtInvalid)
8210 return StmtError();
8211
8212 if (!getDerived().AlwaysRebuild() &&
8213 !SubStmtChanged)
8214 return S;
8215
8216 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8217 Statements,
8218 S->getRBracLoc(),
8219 IsStmtExpr);
8220}
8221
8222template<typename Derived>
8223StmtResult
8224TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8225 ExprResult LHS, RHS;
8226 {
8227 EnterExpressionEvaluationContext Unevaluated(
8228 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8229
8230 // Transform the left-hand case value.
8231 LHS = getDerived().TransformExpr(S->getLHS());
8232 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8233 if (LHS.isInvalid())
8234 return StmtError();
8235
8236 // Transform the right-hand case value (for the GNU case-range extension).
8237 RHS = getDerived().TransformExpr(S->getRHS());
8238 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8239 if (RHS.isInvalid())
8240 return StmtError();
8241 }
8242
8243 // Build the case statement.
8244 // Case statements are always rebuilt so that they will attached to their
8245 // transformed switch statement.
8246 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8247 LHS.get(),
8248 S->getEllipsisLoc(),
8249 RHS.get(),
8250 S->getColonLoc());
8251 if (Case.isInvalid())
8252 return StmtError();
8253
8254 // Transform the statement following the case
8255 StmtResult SubStmt =
8256 getDerived().TransformStmt(S->getSubStmt());
8257 if (SubStmt.isInvalid())
8258 return StmtError();
8259
8260 // Attach the body to the case statement
8261 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8262}
8263
8264template <typename Derived>
8265StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8266 // Transform the statement following the default case
8267 StmtResult SubStmt =
8268 getDerived().TransformStmt(S->getSubStmt());
8269 if (SubStmt.isInvalid())
8270 return StmtError();
8271
8272 // Default statements are always rebuilt
8273 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8274 SubStmt.get());
8275}
8276
8277template<typename Derived>
8278StmtResult
8279TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8280 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8281 if (SubStmt.isInvalid())
8282 return StmtError();
8283
8284 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8285 S->getDecl());
8286 if (!LD)
8287 return StmtError();
8288
8289 // If we're transforming "in-place" (we're not creating new local
8290 // declarations), assume we're replacing the old label statement
8291 // and clear out the reference to it.
8292 if (LD == S->getDecl())
8293 S->getDecl()->setStmt(nullptr);
8294
8295 // FIXME: Pass the real colon location in.
8296 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8297 cast<LabelDecl>(Val: LD), SourceLocation(),
8298 SubStmt.get());
8299}
8300
8301template <typename Derived>
8302const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8303 if (!R)
8304 return R;
8305
8306 switch (R->getKind()) {
8307// Transform attributes by calling TransformXXXAttr.
8308#define ATTR(X) \
8309 case attr::X: \
8310 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8311#include "clang/Basic/AttrList.inc"
8312 }
8313 return R;
8314}
8315
8316template <typename Derived>
8317const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8318 const Stmt *InstS,
8319 const Attr *R) {
8320 if (!R)
8321 return R;
8322
8323 switch (R->getKind()) {
8324// Transform attributes by calling TransformStmtXXXAttr.
8325#define ATTR(X) \
8326 case attr::X: \
8327 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8328#include "clang/Basic/AttrList.inc"
8329 }
8330 return TransformAttr(R);
8331}
8332
8333template <typename Derived>
8334StmtResult
8335TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8336 StmtDiscardKind SDK) {
8337 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8338 if (SubStmt.isInvalid())
8339 return StmtError();
8340
8341 bool AttrsChanged = false;
8342 SmallVector<const Attr *, 1> Attrs;
8343
8344 // Visit attributes and keep track if any are transformed.
8345 for (const auto *I : S->getAttrs()) {
8346 const Attr *R =
8347 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8348 AttrsChanged |= (I != R);
8349 if (R)
8350 Attrs.push_back(Elt: R);
8351 }
8352
8353 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8354 return S;
8355
8356 // If transforming the attributes failed for all of the attributes in the
8357 // statement, don't make an AttributedStmt without attributes.
8358 if (Attrs.empty())
8359 return SubStmt;
8360
8361 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8362 SubStmt.get());
8363}
8364
8365template<typename Derived>
8366StmtResult
8367TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8368 // Transform the initialization statement
8369 StmtResult Init = getDerived().TransformStmt(S->getInit());
8370 if (Init.isInvalid())
8371 return StmtError();
8372
8373 Sema::ConditionResult Cond;
8374 if (!S->isConsteval()) {
8375 // Transform the condition
8376 Cond = getDerived().TransformCondition(
8377 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8378 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8379 : Sema::ConditionKind::Boolean);
8380 if (Cond.isInvalid())
8381 return StmtError();
8382 }
8383
8384 // If this is a constexpr if, determine which arm we should instantiate.
8385 std::optional<bool> ConstexprConditionValue;
8386 if (S->isConstexpr())
8387 ConstexprConditionValue = Cond.getKnownValue();
8388
8389 // Transform the "then" branch.
8390 StmtResult Then;
8391 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8392 EnterExpressionEvaluationContext Ctx(
8393 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8394 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8395 S->isNonNegatedConsteval());
8396
8397 Then = getDerived().TransformStmt(S->getThen());
8398 if (Then.isInvalid())
8399 return StmtError();
8400 } else {
8401 // Discarded branch is replaced with empty CompoundStmt so we can keep
8402 // proper source location for start and end of original branch, so
8403 // subsequent transformations like CoverageMapping work properly
8404 Then = new (getSema().Context)
8405 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8406 }
8407
8408 // Transform the "else" branch.
8409 StmtResult Else;
8410 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8411 EnterExpressionEvaluationContext Ctx(
8412 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8413 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8414 S->isNegatedConsteval());
8415
8416 Else = getDerived().TransformStmt(S->getElse());
8417 if (Else.isInvalid())
8418 return StmtError();
8419 } else if (S->getElse() && ConstexprConditionValue &&
8420 *ConstexprConditionValue) {
8421 // Same thing here as with <then> branch, we are discarding it, we can't
8422 // replace it with NULL nor NullStmt as we need to keep for source location
8423 // range, for CoverageMapping
8424 Else = new (getSema().Context)
8425 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8426 }
8427
8428 if (!getDerived().AlwaysRebuild() &&
8429 Init.get() == S->getInit() &&
8430 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8431 Then.get() == S->getThen() &&
8432 Else.get() == S->getElse())
8433 return S;
8434
8435 return getDerived().RebuildIfStmt(
8436 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8437 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8438}
8439
8440template<typename Derived>
8441StmtResult
8442TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8443 // Transform the initialization statement
8444 StmtResult Init = getDerived().TransformStmt(S->getInit());
8445 if (Init.isInvalid())
8446 return StmtError();
8447
8448 // Transform the condition.
8449 Sema::ConditionResult Cond = getDerived().TransformCondition(
8450 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8451 Sema::ConditionKind::Switch);
8452 if (Cond.isInvalid())
8453 return StmtError();
8454
8455 // Rebuild the switch statement.
8456 StmtResult Switch =
8457 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8458 Init.get(), Cond, S->getRParenLoc());
8459 if (Switch.isInvalid())
8460 return StmtError();
8461
8462 // Transform the body of the switch statement.
8463 StmtResult Body = getDerived().TransformStmt(S->getBody());
8464 if (Body.isInvalid())
8465 return StmtError();
8466
8467 // Complete the switch statement.
8468 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8469 Body.get());
8470}
8471
8472template<typename Derived>
8473StmtResult
8474TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8475 // Transform the condition
8476 Sema::ConditionResult Cond = getDerived().TransformCondition(
8477 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8478 Sema::ConditionKind::Boolean);
8479 if (Cond.isInvalid())
8480 return StmtError();
8481
8482 // OpenACC Restricts a while-loop inside of certain construct/clause
8483 // combinations, so diagnose that here in OpenACC mode.
8484 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8485 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8486
8487 // Transform the body
8488 StmtResult Body = getDerived().TransformStmt(S->getBody());
8489 if (Body.isInvalid())
8490 return StmtError();
8491
8492 if (!getDerived().AlwaysRebuild() &&
8493 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8494 Body.get() == S->getBody())
8495 return Owned(S);
8496
8497 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8498 Cond, S->getRParenLoc(), Body.get());
8499}
8500
8501template<typename Derived>
8502StmtResult
8503TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8504 // OpenACC Restricts a do-loop inside of certain construct/clause
8505 // combinations, so diagnose that here in OpenACC mode.
8506 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8507 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8508
8509 // Transform the body
8510 StmtResult Body = getDerived().TransformStmt(S->getBody());
8511 if (Body.isInvalid())
8512 return StmtError();
8513
8514 // Transform the condition
8515 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8516 if (Cond.isInvalid())
8517 return StmtError();
8518
8519 if (!getDerived().AlwaysRebuild() &&
8520 Cond.get() == S->getCond() &&
8521 Body.get() == S->getBody())
8522 return S;
8523
8524 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8525 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8526 S->getRParenLoc());
8527}
8528
8529template<typename Derived>
8530StmtResult
8531TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8532 if (getSema().getLangOpts().OpenMP)
8533 getSema().OpenMP().startOpenMPLoop();
8534
8535 // Transform the initialization statement
8536 StmtResult Init = getDerived().TransformStmt(S->getInit());
8537 if (Init.isInvalid())
8538 return StmtError();
8539
8540 // In OpenMP loop region loop control variable must be captured and be
8541 // private. Perform analysis of first part (if any).
8542 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8543 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8544 Init.get());
8545
8546 // Transform the condition
8547 Sema::ConditionResult Cond = getDerived().TransformCondition(
8548 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8549 Sema::ConditionKind::Boolean);
8550 if (Cond.isInvalid())
8551 return StmtError();
8552
8553 // Transform the increment
8554 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8555 if (Inc.isInvalid())
8556 return StmtError();
8557
8558 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8559 if (S->getInc() && !FullInc.get())
8560 return StmtError();
8561
8562 // OpenACC Restricts a for-loop inside of certain construct/clause
8563 // combinations, so diagnose that here in OpenACC mode.
8564 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8565 SemaRef.OpenACC().ActOnForStmtBegin(
8566 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8567 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8568
8569 // Transform the body
8570 StmtResult Body = getDerived().TransformStmt(S->getBody());
8571 if (Body.isInvalid())
8572 return StmtError();
8573
8574 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8575
8576 if (!getDerived().AlwaysRebuild() &&
8577 Init.get() == S->getInit() &&
8578 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8579 Inc.get() == S->getInc() &&
8580 Body.get() == S->getBody())
8581 return S;
8582
8583 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8584 Init.get(), Cond, FullInc,
8585 S->getRParenLoc(), Body.get());
8586}
8587
8588template<typename Derived>
8589StmtResult
8590TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8591 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8592 S->getLabel());
8593 if (!LD)
8594 return StmtError();
8595
8596 // Goto statements must always be rebuilt, to resolve the label.
8597 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8598 cast<LabelDecl>(Val: LD));
8599}
8600
8601template<typename Derived>
8602StmtResult
8603TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8604 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8605 if (Target.isInvalid())
8606 return StmtError();
8607 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8608
8609 if (!getDerived().AlwaysRebuild() &&
8610 Target.get() == S->getTarget())
8611 return S;
8612
8613 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8614 Target.get());
8615}
8616
8617template<typename Derived>
8618StmtResult
8619TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8620 if (!S->hasLabelTarget())
8621 return S;
8622
8623 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8624 S->getLabelDecl());
8625 if (!LD)
8626 return StmtError();
8627
8628 return new (SemaRef.Context)
8629 ContinueStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8630}
8631
8632template<typename Derived>
8633StmtResult
8634TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8635 if (!S->hasLabelTarget())
8636 return S;
8637
8638 Decl *LD = getDerived().TransformDecl(S->getLabelDecl()->getLocation(),
8639 S->getLabelDecl());
8640 if (!LD)
8641 return StmtError();
8642
8643 return new (SemaRef.Context)
8644 BreakStmt(S->getKwLoc(), S->getLabelLoc(), cast<LabelDecl>(Val: LD));
8645}
8646
8647template <typename Derived>
8648StmtResult TreeTransform<Derived>::TransformDeferStmt(DeferStmt *S) {
8649 StmtResult Result = getDerived().TransformStmt(S->getBody());
8650 if (!Result.isUsable())
8651 return StmtError();
8652 return DeferStmt::Create(Context&: getSema().Context, DeferLoc: S->getDeferLoc(), Body: Result.get());
8653}
8654
8655template<typename Derived>
8656StmtResult
8657TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8658 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8659 /*NotCopyInit*/false);
8660 if (Result.isInvalid())
8661 return StmtError();
8662
8663 // FIXME: We always rebuild the return statement because there is no way
8664 // to tell whether the return type of the function has changed.
8665 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8666}
8667
8668template<typename Derived>
8669StmtResult
8670TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8671 bool DeclChanged = false;
8672 SmallVector<Decl *, 4> Decls;
8673 LambdaScopeInfo *LSI = getSema().getCurLambda();
8674 for (auto *D : S->decls()) {
8675 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8676 if (!Transformed)
8677 return StmtError();
8678
8679 if (Transformed != D)
8680 DeclChanged = true;
8681
8682 if (LSI) {
8683 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed)) {
8684 if (auto *TN = dyn_cast<TypedefNameDecl>(Val: TD)) {
8685 LSI->ContainsUnexpandedParameterPack |=
8686 TN->getUnderlyingType()->containsUnexpandedParameterPack();
8687 } else {
8688 LSI->ContainsUnexpandedParameterPack |=
8689 getSema()
8690 .getASTContext()
8691 .getTypeDeclType(TD)
8692 ->containsUnexpandedParameterPack();
8693 }
8694 }
8695 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8696 LSI->ContainsUnexpandedParameterPack |=
8697 VD->getType()->containsUnexpandedParameterPack();
8698 }
8699
8700 Decls.push_back(Elt: Transformed);
8701 }
8702
8703 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8704 return S;
8705
8706 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8707}
8708
8709template<typename Derived>
8710StmtResult
8711TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8712
8713 SmallVector<Expr*, 8> Constraints;
8714 SmallVector<Expr*, 8> Exprs;
8715 SmallVector<IdentifierInfo *, 4> Names;
8716
8717 SmallVector<Expr*, 8> Clobbers;
8718
8719 bool ExprsChanged = false;
8720
8721 auto RebuildString = [&](Expr *E) {
8722 ExprResult Result = getDerived().TransformExpr(E);
8723 if (!Result.isUsable())
8724 return Result;
8725 if (Result.get() != E) {
8726 ExprsChanged = true;
8727 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8728 }
8729 return Result;
8730 };
8731
8732 // Go through the outputs.
8733 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8734 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8735
8736 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8737 if (Result.isInvalid())
8738 return StmtError();
8739
8740 Constraints.push_back(Elt: Result.get());
8741
8742 // Transform the output expr.
8743 Expr *OutputExpr = S->getOutputExpr(i: I);
8744 Result = getDerived().TransformExpr(OutputExpr);
8745 if (Result.isInvalid())
8746 return StmtError();
8747
8748 ExprsChanged |= Result.get() != OutputExpr;
8749
8750 Exprs.push_back(Elt: Result.get());
8751 }
8752
8753 // Go through the inputs.
8754 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8755 Names.push_back(Elt: S->getInputIdentifier(i: I));
8756
8757 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8758 if (Result.isInvalid())
8759 return StmtError();
8760
8761 Constraints.push_back(Elt: Result.get());
8762
8763 // Transform the input expr.
8764 Expr *InputExpr = S->getInputExpr(i: I);
8765 Result = getDerived().TransformExpr(InputExpr);
8766 if (Result.isInvalid())
8767 return StmtError();
8768
8769 ExprsChanged |= Result.get() != InputExpr;
8770
8771 Exprs.push_back(Elt: Result.get());
8772 }
8773
8774 // Go through the Labels.
8775 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8776 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8777
8778 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8779 if (Result.isInvalid())
8780 return StmtError();
8781 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8782 Exprs.push_back(Elt: Result.get());
8783 }
8784
8785 // Go through the clobbers.
8786 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8787 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8788 if (Result.isInvalid())
8789 return StmtError();
8790 Clobbers.push_back(Elt: Result.get());
8791 }
8792
8793 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8794 if (AsmString.isInvalid())
8795 return StmtError();
8796
8797 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8798 return S;
8799
8800 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8801 S->isVolatile(), S->getNumOutputs(),
8802 S->getNumInputs(), Names.data(),
8803 Constraints, Exprs, AsmString.get(),
8804 Clobbers, S->getNumLabels(),
8805 S->getRParenLoc());
8806}
8807
8808template<typename Derived>
8809StmtResult
8810TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8811 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8812
8813 bool HadError = false, HadChange = false;
8814
8815 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8816 SmallVector<Expr*, 8> TransformedExprs;
8817 TransformedExprs.reserve(N: SrcExprs.size());
8818 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8819 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8820 if (!Result.isUsable()) {
8821 HadError = true;
8822 } else {
8823 HadChange |= (Result.get() != SrcExprs[i]);
8824 TransformedExprs.push_back(Elt: Result.get());
8825 }
8826 }
8827
8828 if (HadError) return StmtError();
8829 if (!HadChange && !getDerived().AlwaysRebuild())
8830 return Owned(S);
8831
8832 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8833 AsmToks, S->getAsmString(),
8834 S->getNumOutputs(), S->getNumInputs(),
8835 S->getAllConstraints(), S->getClobbers(),
8836 TransformedExprs, S->getEndLoc());
8837}
8838
8839// C++ Coroutines
8840template<typename Derived>
8841StmtResult
8842TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8843 auto *ScopeInfo = SemaRef.getCurFunction();
8844 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8845 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8846 ScopeInfo->NeedsCoroutineSuspends &&
8847 ScopeInfo->CoroutineSuspends.first == nullptr &&
8848 ScopeInfo->CoroutineSuspends.second == nullptr &&
8849 "expected clean scope info");
8850
8851 // Set that we have (possibly-invalid) suspend points before we do anything
8852 // that may fail.
8853 ScopeInfo->setNeedsCoroutineSuspends(false);
8854
8855 // We re-build the coroutine promise object (and the coroutine parameters its
8856 // type and constructor depend on) based on the types used in our current
8857 // function. We must do so, and set it on the current FunctionScopeInfo,
8858 // before attempting to transform the other parts of the coroutine body
8859 // statement, such as the implicit suspend statements (because those
8860 // statements reference the FunctionScopeInfo::CoroutinePromise).
8861 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8862 return StmtError();
8863 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8864 if (!Promise)
8865 return StmtError();
8866 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8867 ScopeInfo->CoroutinePromise = Promise;
8868
8869 // Transform the implicit coroutine statements constructed using dependent
8870 // types during the previous parse: initial and final suspensions, the return
8871 // object, and others. We also transform the coroutine function's body.
8872 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8873 if (InitSuspend.isInvalid())
8874 return StmtError();
8875 StmtResult FinalSuspend =
8876 getDerived().TransformStmt(S->getFinalSuspendStmt());
8877 if (FinalSuspend.isInvalid() ||
8878 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8879 return StmtError();
8880 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8881 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8882
8883 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8884 if (BodyRes.isInvalid())
8885 return StmtError();
8886
8887 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8888 if (Builder.isInvalid())
8889 return StmtError();
8890
8891 Expr *ReturnObject = S->getReturnValueInit();
8892 assert(ReturnObject && "the return object is expected to be valid");
8893 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8894 /*NoCopyInit*/ false);
8895 if (Res.isInvalid())
8896 return StmtError();
8897 Builder.ReturnValue = Res.get();
8898
8899 // If during the previous parse the coroutine still had a dependent promise
8900 // statement, we may need to build some implicit coroutine statements
8901 // (such as exception and fallthrough handlers) for the first time.
8902 if (S->hasDependentPromiseType()) {
8903 // We can only build these statements, however, if the current promise type
8904 // is not dependent.
8905 if (!Promise->getType()->isDependentType()) {
8906 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8907 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8908 "these nodes should not have been built yet");
8909 if (!Builder.buildDependentStatements())
8910 return StmtError();
8911 }
8912 } else {
8913 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8914 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8915 if (Res.isInvalid())
8916 return StmtError();
8917 Builder.OnFallthrough = Res.get();
8918 }
8919
8920 if (auto *OnException = S->getExceptionHandler()) {
8921 StmtResult Res = getDerived().TransformStmt(OnException);
8922 if (Res.isInvalid())
8923 return StmtError();
8924 Builder.OnException = Res.get();
8925 }
8926
8927 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8928 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8929 if (Res.isInvalid())
8930 return StmtError();
8931 Builder.ReturnStmtOnAllocFailure = Res.get();
8932 }
8933
8934 // Transform any additional statements we may have already built
8935 assert(S->getAllocate() && S->getDeallocate() &&
8936 "allocation and deallocation calls must already be built");
8937 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8938 if (AllocRes.isInvalid())
8939 return StmtError();
8940 Builder.Allocate = AllocRes.get();
8941
8942 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8943 if (DeallocRes.isInvalid())
8944 return StmtError();
8945 Builder.Deallocate = DeallocRes.get();
8946
8947 if (auto *ResultDecl = S->getResultDecl()) {
8948 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8949 if (Res.isInvalid())
8950 return StmtError();
8951 Builder.ResultDecl = Res.get();
8952 }
8953
8954 if (auto *ReturnStmt = S->getReturnStmt()) {
8955 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8956 if (Res.isInvalid())
8957 return StmtError();
8958 Builder.ReturnStmt = Res.get();
8959 }
8960 }
8961
8962 return getDerived().RebuildCoroutineBodyStmt(Builder);
8963}
8964
8965template<typename Derived>
8966StmtResult
8967TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8968 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8969 /*NotCopyInit*/false);
8970 if (Result.isInvalid())
8971 return StmtError();
8972
8973 // Always rebuild; we don't know if this needs to be injected into a new
8974 // context or if the promise type has changed.
8975 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8976 S->isImplicit());
8977}
8978
8979template <typename Derived>
8980ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8981 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8982 /*NotCopyInit*/ false);
8983 if (Operand.isInvalid())
8984 return ExprError();
8985
8986 // Rebuild the common-expr from the operand rather than transforming it
8987 // separately.
8988
8989 // FIXME: getCurScope() should not be used during template instantiation.
8990 // We should pick up the set of unqualified lookup results for operator
8991 // co_await during the initial parse.
8992 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8993 getSema().getCurScope(), E->getKeywordLoc());
8994
8995 // Always rebuild; we don't know if this needs to be injected into a new
8996 // context or if the promise type has changed.
8997 return getDerived().RebuildCoawaitExpr(
8998 E->getKeywordLoc(), Operand.get(),
8999 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
9000}
9001
9002template <typename Derived>
9003ExprResult
9004TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
9005 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
9006 /*NotCopyInit*/ false);
9007 if (OperandResult.isInvalid())
9008 return ExprError();
9009
9010 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
9011 E->getOperatorCoawaitLookup());
9012
9013 if (LookupResult.isInvalid())
9014 return ExprError();
9015
9016 // Always rebuild; we don't know if this needs to be injected into a new
9017 // context or if the promise type has changed.
9018 return getDerived().RebuildDependentCoawaitExpr(
9019 E->getKeywordLoc(), OperandResult.get(),
9020 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
9021}
9022
9023template<typename Derived>
9024ExprResult
9025TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
9026 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
9027 /*NotCopyInit*/false);
9028 if (Result.isInvalid())
9029 return ExprError();
9030
9031 // Always rebuild; we don't know if this needs to be injected into a new
9032 // context or if the promise type has changed.
9033 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
9034}
9035
9036// Objective-C Statements.
9037
9038template<typename Derived>
9039StmtResult
9040TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
9041 // Transform the body of the @try.
9042 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
9043 if (TryBody.isInvalid())
9044 return StmtError();
9045
9046 // Transform the @catch statements (if present).
9047 bool AnyCatchChanged = false;
9048 SmallVector<Stmt*, 8> CatchStmts;
9049 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
9050 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
9051 if (Catch.isInvalid())
9052 return StmtError();
9053 if (Catch.get() != S->getCatchStmt(I))
9054 AnyCatchChanged = true;
9055 CatchStmts.push_back(Elt: Catch.get());
9056 }
9057
9058 // Transform the @finally statement (if present).
9059 StmtResult Finally;
9060 if (S->getFinallyStmt()) {
9061 Finally = getDerived().TransformStmt(S->getFinallyStmt());
9062 if (Finally.isInvalid())
9063 return StmtError();
9064 }
9065
9066 // If nothing changed, just retain this statement.
9067 if (!getDerived().AlwaysRebuild() &&
9068 TryBody.get() == S->getTryBody() &&
9069 !AnyCatchChanged &&
9070 Finally.get() == S->getFinallyStmt())
9071 return S;
9072
9073 // Build a new statement.
9074 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
9075 CatchStmts, Finally.get());
9076}
9077
9078template<typename Derived>
9079StmtResult
9080TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
9081 // Transform the @catch parameter, if there is one.
9082 VarDecl *Var = nullptr;
9083 if (VarDecl *FromVar = S->getCatchParamDecl()) {
9084 TypeSourceInfo *TSInfo = nullptr;
9085 if (FromVar->getTypeSourceInfo()) {
9086 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
9087 if (!TSInfo)
9088 return StmtError();
9089 }
9090
9091 QualType T;
9092 if (TSInfo)
9093 T = TSInfo->getType();
9094 else {
9095 T = getDerived().TransformType(FromVar->getType());
9096 if (T.isNull())
9097 return StmtError();
9098 }
9099
9100 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9101 if (!Var)
9102 return StmtError();
9103 }
9104
9105 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9106 if (Body.isInvalid())
9107 return StmtError();
9108
9109 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9110 S->getRParenLoc(),
9111 Var, Body.get());
9112}
9113
9114template<typename Derived>
9115StmtResult
9116TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9117 // Transform the body.
9118 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9119 if (Body.isInvalid())
9120 return StmtError();
9121
9122 // If nothing changed, just retain this statement.
9123 if (!getDerived().AlwaysRebuild() &&
9124 Body.get() == S->getFinallyBody())
9125 return S;
9126
9127 // Build a new statement.
9128 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9129 Body.get());
9130}
9131
9132template<typename Derived>
9133StmtResult
9134TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9135 ExprResult Operand;
9136 if (S->getThrowExpr()) {
9137 Operand = getDerived().TransformExpr(S->getThrowExpr());
9138 if (Operand.isInvalid())
9139 return StmtError();
9140 }
9141
9142 if (!getDerived().AlwaysRebuild() &&
9143 Operand.get() == S->getThrowExpr())
9144 return S;
9145
9146 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9147}
9148
9149template<typename Derived>
9150StmtResult
9151TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9152 ObjCAtSynchronizedStmt *S) {
9153 // Transform the object we are locking.
9154 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9155 if (Object.isInvalid())
9156 return StmtError();
9157 Object =
9158 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9159 Object.get());
9160 if (Object.isInvalid())
9161 return StmtError();
9162
9163 // Transform the body.
9164 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9165 if (Body.isInvalid())
9166 return StmtError();
9167
9168 // If nothing change, just retain the current statement.
9169 if (!getDerived().AlwaysRebuild() &&
9170 Object.get() == S->getSynchExpr() &&
9171 Body.get() == S->getSynchBody())
9172 return S;
9173
9174 // Build a new statement.
9175 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9176 Object.get(), Body.get());
9177}
9178
9179template<typename Derived>
9180StmtResult
9181TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9182 ObjCAutoreleasePoolStmt *S) {
9183 // Transform the body.
9184 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9185 if (Body.isInvalid())
9186 return StmtError();
9187
9188 // If nothing changed, just retain this statement.
9189 if (!getDerived().AlwaysRebuild() &&
9190 Body.get() == S->getSubStmt())
9191 return S;
9192
9193 // Build a new statement.
9194 return getDerived().RebuildObjCAutoreleasePoolStmt(
9195 S->getAtLoc(), Body.get());
9196}
9197
9198template<typename Derived>
9199StmtResult
9200TreeTransform<Derived>::TransformObjCForCollectionStmt(
9201 ObjCForCollectionStmt *S) {
9202 // Transform the element statement.
9203 StmtResult Element = getDerived().TransformStmt(
9204 S->getElement(), StmtDiscardKind::NotDiscarded);
9205 if (Element.isInvalid())
9206 return StmtError();
9207
9208 // Transform the collection expression.
9209 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9210 if (Collection.isInvalid())
9211 return StmtError();
9212
9213 // Transform the body.
9214 StmtResult Body = getDerived().TransformStmt(S->getBody());
9215 if (Body.isInvalid())
9216 return StmtError();
9217
9218 // If nothing changed, just retain this statement.
9219 if (!getDerived().AlwaysRebuild() &&
9220 Element.get() == S->getElement() &&
9221 Collection.get() == S->getCollection() &&
9222 Body.get() == S->getBody())
9223 return S;
9224
9225 // Build a new statement.
9226 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9227 Element.get(),
9228 Collection.get(),
9229 S->getRParenLoc(),
9230 Body.get());
9231}
9232
9233template <typename Derived>
9234StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9235 // Transform the exception declaration, if any.
9236 VarDecl *Var = nullptr;
9237 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9238 TypeSourceInfo *T =
9239 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9240 if (!T)
9241 return StmtError();
9242
9243 Var = getDerived().RebuildExceptionDecl(
9244 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9245 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9246 if (!Var || Var->isInvalidDecl())
9247 return StmtError();
9248 }
9249
9250 // Transform the actual exception handler.
9251 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9252 if (Handler.isInvalid())
9253 return StmtError();
9254
9255 if (!getDerived().AlwaysRebuild() && !Var &&
9256 Handler.get() == S->getHandlerBlock())
9257 return S;
9258
9259 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9260}
9261
9262template <typename Derived>
9263StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9264 // Transform the try block itself.
9265 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9266 if (TryBlock.isInvalid())
9267 return StmtError();
9268
9269 // Transform the handlers.
9270 bool HandlerChanged = false;
9271 SmallVector<Stmt *, 8> Handlers;
9272 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9273 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9274 if (Handler.isInvalid())
9275 return StmtError();
9276
9277 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9278 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9279 }
9280
9281 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9282
9283 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9284 !HandlerChanged)
9285 return S;
9286
9287 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9288 Handlers);
9289}
9290
9291template<typename Derived>
9292StmtResult
9293TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9294 EnterExpressionEvaluationContext ForRangeInitContext(
9295 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9296 /*LambdaContextDecl=*/nullptr,
9297 Sema::ExpressionEvaluationContextRecord::EK_Other,
9298 getSema().getLangOpts().CPlusPlus23);
9299
9300 // P2718R0 - Lifetime extension in range-based for loops.
9301 if (getSema().getLangOpts().CPlusPlus23) {
9302 auto &LastRecord = getSema().currentEvaluationContext();
9303 LastRecord.InLifetimeExtendingContext = true;
9304 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9305 }
9306 StmtResult Init =
9307 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9308 if (Init.isInvalid())
9309 return StmtError();
9310
9311 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9312 if (Range.isInvalid())
9313 return StmtError();
9314
9315 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9316 assert(getSema().getLangOpts().CPlusPlus23 ||
9317 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9318 auto ForRangeLifetimeExtendTemps =
9319 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9320
9321 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9322 if (Begin.isInvalid())
9323 return StmtError();
9324 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9325 if (End.isInvalid())
9326 return StmtError();
9327
9328 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9329 if (Cond.isInvalid())
9330 return StmtError();
9331 if (Cond.get())
9332 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9333 if (Cond.isInvalid())
9334 return StmtError();
9335 if (Cond.get())
9336 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9337
9338 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9339 if (Inc.isInvalid())
9340 return StmtError();
9341 if (Inc.get())
9342 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9343
9344 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9345 if (LoopVar.isInvalid())
9346 return StmtError();
9347
9348 StmtResult NewStmt = S;
9349 if (getDerived().AlwaysRebuild() ||
9350 Init.get() != S->getInit() ||
9351 Range.get() != S->getRangeStmt() ||
9352 Begin.get() != S->getBeginStmt() ||
9353 End.get() != S->getEndStmt() ||
9354 Cond.get() != S->getCond() ||
9355 Inc.get() != S->getInc() ||
9356 LoopVar.get() != S->getLoopVarStmt()) {
9357 NewStmt = getDerived().RebuildCXXForRangeStmt(
9358 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9359 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9360 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9361 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9362 // Might not have attached any initializer to the loop variable.
9363 getSema().ActOnInitializerError(
9364 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9365 return StmtError();
9366 }
9367 }
9368
9369 // OpenACC Restricts a while-loop inside of certain construct/clause
9370 // combinations, so diagnose that here in OpenACC mode.
9371 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9372 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9373
9374 StmtResult Body = getDerived().TransformStmt(S->getBody());
9375 if (Body.isInvalid())
9376 return StmtError();
9377
9378 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9379
9380 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9381 // it now so we have a new statement to attach the body to.
9382 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9383 NewStmt = getDerived().RebuildCXXForRangeStmt(
9384 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9385 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9386 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9387 if (NewStmt.isInvalid())
9388 return StmtError();
9389 }
9390
9391 if (NewStmt.get() == S)
9392 return S;
9393
9394 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9395}
9396
9397template <typename Derived>
9398StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtPattern(
9399 CXXExpansionStmtPattern *S) {
9400 assert(SemaRef.CurContext->isExpansionStmt());
9401
9402 Decl *ESD =
9403 getDerived().TransformDecl(S->getDecl()->getLocation(), S->getDecl());
9404 if (!ESD || ESD->isInvalidDecl())
9405 return StmtError();
9406 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9407
9408 // This is required because some parts of an expansion statement (e.g. the
9409 // init-statement) are not in a dependent context and must thus be transformed
9410 // in the parent context.
9411 auto TransformStmtInParentContext = [&](Stmt *SubStmt) -> StmtResult {
9412 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9413 /*NewThis=*/false);
9414 return getDerived().TransformStmt(SubStmt);
9415 };
9416
9417 Stmt *Init = S->getInit();
9418 if (Init) {
9419 StmtResult SR = TransformStmtInParentContext(Init);
9420 if (SR.isInvalid())
9421 return StmtError();
9422 Init = SR.get();
9423 }
9424
9425 // Collect lifetime-extended temporaries in case this ends up being a
9426 // destructuring or iterating expansion statement.
9427 //
9428 // CWG 3140: Additionally, for iterating expansions statements, we need to
9429 // apply lifetime extension to the initializer of the range.
9430 ExprResult ExpansionInitializer;
9431 StmtResult Range;
9432 SmallVector<MaterializeTemporaryExpr *, 8> LifetimeExtendTemps;
9433 if (S->isDependent() || S->isIterating()) {
9434 EnterExpressionEvaluationContext ExprEvalCtx(
9435 SemaRef, SemaRef.currentEvaluationContext().Context);
9436 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9437 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9438
9439 if (S->isDependent()) {
9440 // The expansion initializer should not be in the context of the expansion
9441 // statement because it isn't instantiated when the expansion statement is
9442 // expanded.
9443 Sema::ContextRAII CtxGuard(SemaRef, SemaRef.CurContext->getParent(),
9444 /*NewThis=*/false);
9445 ExpansionInitializer =
9446 getDerived().TransformExpr(S->getExpansionInitializer());
9447 if (ExpansionInitializer.isInvalid())
9448 return StmtError();
9449 } else if (S->isIterating()) {
9450 Range = TransformStmtInParentContext(S->getRangeVarStmt());
9451 if (Range.isInvalid())
9452 return StmtError();
9453 }
9454
9455 ExpansionInitializer =
9456 SemaRef.MaybeCreateExprWithCleanups(SubExpr: ExpansionInitializer);
9457
9458 LifetimeExtendTemps =
9459 SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps;
9460 }
9461
9462 CXXExpansionStmtPattern *NewPattern = nullptr;
9463 if (S->isEnumerating()) {
9464 StmtResult ExpansionVar =
9465 getDerived().TransformStmt(S->getExpansionVarStmt());
9466 if (ExpansionVar.isInvalid())
9467 return StmtError();
9468
9469 NewPattern = CXXExpansionStmtPattern::CreateEnumerating(
9470 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9471 LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(), RParenLoc: S->getRParenLoc());
9472 } else if (S->isIterating()) {
9473 StmtResult Begin = TransformStmtInParentContext(S->getBeginVarStmt());
9474 StmtResult Iter = TransformStmtInParentContext(S->getIterVarStmt());
9475 if (Begin.isInvalid() || Iter.isInvalid())
9476 return StmtError();
9477
9478 // The expansion variable is part of the pattern only and never ends
9479 // up in the instantiations, so keep it in the expansion statement's
9480 // DeclContext.
9481 StmtResult ExpansionVar =
9482 getDerived().TransformStmt(S->getExpansionVarStmt());
9483 if (ExpansionVar.isInvalid())
9484 return StmtError();
9485
9486 NewPattern = CXXExpansionStmtPattern::CreateIterating(
9487 Context&: SemaRef.Context, ESD: NewESD, Init, ExpansionVar: ExpansionVar.getAs<DeclStmt>(),
9488 Range: Range.getAs<DeclStmt>(), Begin: Begin.getAs<DeclStmt>(),
9489 Iter: Iter.getAs<DeclStmt>(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9490 RParenLoc: S->getRParenLoc());
9491
9492 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9493 RangeVar: NewPattern->getRangeVar(), Temporaries: LifetimeExtendTemps);
9494 } else if (S->isDependent()) {
9495 StmtResult ExpansionVar =
9496 getDerived().TransformStmt(S->getExpansionVarStmt());
9497 if (ExpansionVar.isInvalid())
9498 return StmtError();
9499
9500 StmtResult Res = SemaRef.BuildNonEnumeratingCXXExpansionStmtPattern(
9501 ESD: NewESD, Init, ExpansionVarStmt: ExpansionVar.getAs<DeclStmt>(),
9502 ExpansionInitializer: ExpansionInitializer.get(), LParenLoc: S->getLParenLoc(), ColonLoc: S->getColonLoc(),
9503 RParenLoc: S->getRParenLoc(), LifetimeExtendTemps);
9504
9505 if (Res.isInvalid())
9506 return StmtError();
9507
9508 NewPattern = cast<CXXExpansionStmtPattern>(Val: Res.get());
9509 } else {
9510 // The only time we instantiate an expansion statement is if its expansion
9511 // size is dependent (otherwise, we only instantiate the expansions and
9512 // leave the underlying CXXExpansionStmtPattern as-is). Since destructuring
9513 // expansion statements never have a dependent size, we should never get
9514 // here.
9515 llvm_unreachable("destructuring pattern should never be instantiated");
9516 }
9517
9518 StmtResult Body = getDerived().TransformStmt(S->getBody());
9519 if (Body.isInvalid())
9520 return StmtError();
9521
9522 return SemaRef.FinishCXXExpansionStmt(Expansion: NewPattern, Body: Body.get());
9523}
9524
9525template <typename Derived>
9526StmtResult TreeTransform<Derived>::TransformCXXExpansionStmtInstantiation(
9527 CXXExpansionStmtInstantiation *S) {
9528 bool SubStmtChanged = false;
9529 auto TransformStmts = [&](SmallVectorImpl<Stmt *> &NewStmts,
9530 ArrayRef<Stmt *> OldStmts) {
9531 for (Stmt *OldDS : OldStmts) {
9532 StmtResult NewDS = getDerived().TransformStmt(OldDS);
9533 if (NewDS.isInvalid())
9534 return true;
9535
9536 SubStmtChanged |= NewDS.get() != OldDS;
9537 NewStmts.push_back(Elt: NewDS.get());
9538 }
9539
9540 return false;
9541 };
9542
9543 Decl *ESD =
9544 getDerived().TransformDecl(S->getParent()->getLocation(), S->getParent());
9545 if (!ESD || ESD->isInvalidDecl())
9546 return StmtError();
9547 CXXExpansionStmtDecl *NewESD = cast<CXXExpansionStmtDecl>(Val: ESD);
9548
9549 SmallVector<Stmt *> PreambleStmts;
9550 SmallVector<Stmt *> Instantiations;
9551
9552 // Apply lifetime extension to the preamble statements if this was a
9553 // destructuring expansion statement.
9554 {
9555 EnterExpressionEvaluationContext ExprEvalCtx(
9556 SemaRef, SemaRef.currentEvaluationContext().Context);
9557 SemaRef.currentEvaluationContext().InLifetimeExtendingContext = true;
9558 SemaRef.currentEvaluationContext().RebuildDefaultArgOrDefaultInit = true;
9559 if (TransformStmts(PreambleStmts, S->getPreambleStmts()))
9560 return StmtError();
9561
9562 if (S->shouldApplyLifetimeExtensionToPreamble()) {
9563 auto *VD =
9564 cast<VarDecl>(Val: cast<DeclStmt>(Val: PreambleStmts.front())->getSingleDecl());
9565 SemaRef.ApplyForRangeOrExpansionStatementLifetimeExtension(
9566 RangeVar: VD, Temporaries: SemaRef.currentEvaluationContext().ForRangeLifetimeExtendTemps);
9567 }
9568 }
9569
9570 if (TransformStmts(Instantiations, S->getInstantiations()))
9571 return StmtError();
9572
9573 if (!getDerived().AlwaysRebuild() && !SubStmtChanged)
9574 return S;
9575
9576 return CXXExpansionStmtInstantiation::Create(
9577 C&: SemaRef.Context, Parent: NewESD, Instantiations, PreambleStmts,
9578 ShouldApplyLifetimeExtensionToPreamble: S->shouldApplyLifetimeExtensionToPreamble());
9579}
9580
9581template <typename Derived>
9582ExprResult TreeTransform<Derived>::TransformCXXExpansionSelectExpr(
9583 CXXExpansionSelectExpr *E) {
9584 ExprResult Range = getDerived().TransformExpr(E->getRangeExpr());
9585 ExprResult Idx = getDerived().TransformExpr(E->getIndexExpr());
9586 if (Range.isInvalid() || Idx.isInvalid())
9587 return ExprError();
9588
9589 if (!getDerived().AlwaysRebuild() && Range.get() == E->getRangeExpr() &&
9590 Idx.get() == E->getIndexExpr())
9591 return E;
9592
9593 return SemaRef.BuildCXXExpansionSelectExpr(Range: Range.getAs<InitListExpr>(),
9594 Idx: Idx.get());
9595}
9596
9597template<typename Derived>
9598StmtResult
9599TreeTransform<Derived>::TransformMSDependentExistsStmt(
9600 MSDependentExistsStmt *S) {
9601 // Transform the nested-name-specifier, if any.
9602 NestedNameSpecifierLoc QualifierLoc;
9603 if (S->getQualifierLoc()) {
9604 QualifierLoc
9605 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9606 if (!QualifierLoc)
9607 return StmtError();
9608 }
9609
9610 // Transform the declaration name.
9611 DeclarationNameInfo NameInfo = S->getNameInfo();
9612 if (NameInfo.getName()) {
9613 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9614 if (!NameInfo.getName())
9615 return StmtError();
9616 }
9617
9618 // Check whether anything changed.
9619 if (!getDerived().AlwaysRebuild() &&
9620 QualifierLoc == S->getQualifierLoc() &&
9621 NameInfo.getName() == S->getNameInfo().getName())
9622 return S;
9623
9624 // Determine whether this name exists, if we can.
9625 CXXScopeSpec SS;
9626 SS.Adopt(Other: QualifierLoc);
9627 bool Dependent = false;
9628 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9629 case IfExistsResult::Exists:
9630 if (S->isIfExists())
9631 break;
9632
9633 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9634
9635 case IfExistsResult::DoesNotExist:
9636 if (S->isIfNotExists())
9637 break;
9638
9639 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9640
9641 case IfExistsResult::Dependent:
9642 Dependent = true;
9643 break;
9644
9645 case IfExistsResult::Error:
9646 return StmtError();
9647 }
9648
9649 // We need to continue with the instantiation, so do so now.
9650 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9651 if (SubStmt.isInvalid())
9652 return StmtError();
9653
9654 // If we have resolved the name, just transform to the substatement.
9655 if (!Dependent)
9656 return SubStmt;
9657
9658 // The name is still dependent, so build a dependent expression again.
9659 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9660 S->isIfExists(),
9661 QualifierLoc,
9662 NameInfo,
9663 SubStmt.get());
9664}
9665
9666template<typename Derived>
9667ExprResult
9668TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9669 NestedNameSpecifierLoc QualifierLoc;
9670 if (E->getQualifierLoc()) {
9671 QualifierLoc
9672 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9673 if (!QualifierLoc)
9674 return ExprError();
9675 }
9676
9677 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9678 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9679 if (!PD)
9680 return ExprError();
9681
9682 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9683 if (Base.isInvalid())
9684 return ExprError();
9685
9686 return new (SemaRef.getASTContext())
9687 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9688 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9689 QualifierLoc, E->getMemberLoc());
9690}
9691
9692template <typename Derived>
9693ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9694 MSPropertySubscriptExpr *E) {
9695 auto BaseRes = getDerived().TransformExpr(E->getBase());
9696 if (BaseRes.isInvalid())
9697 return ExprError();
9698 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9699 if (IdxRes.isInvalid())
9700 return ExprError();
9701
9702 if (!getDerived().AlwaysRebuild() &&
9703 BaseRes.get() == E->getBase() &&
9704 IdxRes.get() == E->getIdx())
9705 return E;
9706
9707 return getDerived().RebuildArraySubscriptExpr(
9708 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9709}
9710
9711template <typename Derived>
9712StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9713 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9714 if (TryBlock.isInvalid())
9715 return StmtError();
9716
9717 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9718 if (Handler.isInvalid())
9719 return StmtError();
9720
9721 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9722 Handler.get() == S->getHandler())
9723 return S;
9724
9725 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9726 TryBlock.get(), Handler.get());
9727}
9728
9729template <typename Derived>
9730StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9731 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9732 if (Block.isInvalid())
9733 return StmtError();
9734
9735 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9736}
9737
9738template <typename Derived>
9739StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9740 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9741 if (FilterExpr.isInvalid())
9742 return StmtError();
9743
9744 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9745 if (Block.isInvalid())
9746 return StmtError();
9747
9748 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9749 Block.get());
9750}
9751
9752template <typename Derived>
9753StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9754 if (isa<SEHFinallyStmt>(Val: Handler))
9755 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9756 else
9757 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9758}
9759
9760template<typename Derived>
9761StmtResult
9762TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9763 return S;
9764}
9765
9766//===----------------------------------------------------------------------===//
9767// OpenMP directive transformation
9768//===----------------------------------------------------------------------===//
9769
9770template <typename Derived>
9771StmtResult
9772TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9773 // OMPCanonicalLoops are eliminated during transformation, since they will be
9774 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9775 // after transformation.
9776 return getDerived().TransformStmt(L->getLoopStmt());
9777}
9778
9779template <typename Derived>
9780StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9781 OMPExecutableDirective *D) {
9782
9783 // Transform the clauses
9784 llvm::SmallVector<OMPClause *, 16> TClauses;
9785 ArrayRef<OMPClause *> Clauses = D->clauses();
9786 TClauses.reserve(N: Clauses.size());
9787 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9788 I != E; ++I) {
9789 if (*I) {
9790 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9791 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9792 getDerived().getSema().OpenMP().EndOpenMPClause();
9793 if (Clause)
9794 TClauses.push_back(Elt: Clause);
9795 } else {
9796 TClauses.push_back(Elt: nullptr);
9797 }
9798 }
9799 StmtResult AssociatedStmt;
9800 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9801 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9802 D->getDirectiveKind(),
9803 /*CurScope=*/nullptr);
9804 StmtResult Body;
9805 {
9806 Sema::CompoundScopeRAII CompoundScope(getSema());
9807 Stmt *CS;
9808 if (D->getDirectiveKind() == OMPD_atomic ||
9809 D->getDirectiveKind() == OMPD_critical ||
9810 D->getDirectiveKind() == OMPD_section ||
9811 D->getDirectiveKind() == OMPD_master)
9812 CS = D->getAssociatedStmt();
9813 else
9814 CS = D->getRawStmt();
9815 Body = getDerived().TransformStmt(CS);
9816 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9817 getSema().getLangOpts().OpenMPIRBuilder)
9818 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9819 }
9820 AssociatedStmt =
9821 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9822 if (AssociatedStmt.isInvalid()) {
9823 return StmtError();
9824 }
9825 }
9826 if (TClauses.size() != Clauses.size()) {
9827 return StmtError();
9828 }
9829
9830 // Transform directive name for 'omp critical' directive.
9831 DeclarationNameInfo DirName;
9832 if (D->getDirectiveKind() == OMPD_critical) {
9833 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9834 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9835 }
9836 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9837 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9838 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9839 } else if (D->getDirectiveKind() == OMPD_cancel) {
9840 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9841 }
9842
9843 return getDerived().RebuildOMPExecutableDirective(
9844 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9845 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9846}
9847
9848/// This is mostly the same as above, but allows 'informational' class
9849/// directives when rebuilding the stmt. It still takes an
9850/// OMPExecutableDirective-type argument because we're reusing that as the
9851/// superclass for the 'assume' directive at present, instead of defining a
9852/// mostly-identical OMPInformationalDirective parent class.
9853template <typename Derived>
9854StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9855 OMPExecutableDirective *D) {
9856
9857 // Transform the clauses
9858 llvm::SmallVector<OMPClause *, 16> TClauses;
9859 ArrayRef<OMPClause *> Clauses = D->clauses();
9860 TClauses.reserve(N: Clauses.size());
9861 for (OMPClause *C : Clauses) {
9862 if (C) {
9863 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9864 OMPClause *Clause = getDerived().TransformOMPClause(C);
9865 getDerived().getSema().OpenMP().EndOpenMPClause();
9866 if (Clause)
9867 TClauses.push_back(Elt: Clause);
9868 } else {
9869 TClauses.push_back(Elt: nullptr);
9870 }
9871 }
9872 StmtResult AssociatedStmt;
9873 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9874 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9875 D->getDirectiveKind(),
9876 /*CurScope=*/nullptr);
9877 StmtResult Body;
9878 {
9879 Sema::CompoundScopeRAII CompoundScope(getSema());
9880 assert(D->getDirectiveKind() == OMPD_assume &&
9881 "Unexpected informational directive");
9882 Stmt *CS = D->getAssociatedStmt();
9883 Body = getDerived().TransformStmt(CS);
9884 }
9885 AssociatedStmt =
9886 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9887 if (AssociatedStmt.isInvalid())
9888 return StmtError();
9889 }
9890 if (TClauses.size() != Clauses.size())
9891 return StmtError();
9892
9893 DeclarationNameInfo DirName;
9894
9895 return getDerived().RebuildOMPInformationalDirective(
9896 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9897 D->getBeginLoc(), D->getEndLoc());
9898}
9899
9900template <typename Derived>
9901StmtResult
9902TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9903 // TODO: Fix This
9904 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9905 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9906 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9907 return StmtError();
9908}
9909
9910template <typename Derived>
9911StmtResult
9912TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9916 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9917 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9918 return Res;
9919}
9920
9921template <typename Derived>
9922StmtResult
9923TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9924 DeclarationNameInfo DirName;
9925 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9926 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9927 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9928 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9929 return Res;
9930}
9931
9932template <typename Derived>
9933StmtResult
9934TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9935 DeclarationNameInfo DirName;
9936 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9937 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9938 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9939 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9940 return Res;
9941}
9942
9943template <typename Derived>
9944StmtResult
9945TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9946 DeclarationNameInfo DirName;
9947 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9948 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9949 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9950 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9951 return Res;
9952}
9953
9954template <typename Derived>
9955StmtResult
9956TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9957 DeclarationNameInfo DirName;
9958 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9959 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9960 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9961 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9962 return Res;
9963}
9964
9965template <typename Derived>
9966StmtResult
9967TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9968 DeclarationNameInfo DirName;
9969 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9970 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9971 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9972 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9973 return Res;
9974}
9975
9976template <typename Derived>
9977StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9978 OMPInterchangeDirective *D) {
9979 DeclarationNameInfo DirName;
9980 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9981 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9982 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9983 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9984 return Res;
9985}
9986
9987template <typename Derived>
9988StmtResult
9989TreeTransform<Derived>::TransformOMPSplitDirective(OMPSplitDirective *D) {
9990 DeclarationNameInfo DirName;
9991 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9992 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9993 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9994 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9995 return Res;
9996}
9997
9998template <typename Derived>
9999StmtResult
10000TreeTransform<Derived>::TransformOMPFuseDirective(OMPFuseDirective *D) {
10001 DeclarationNameInfo DirName;
10002 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10003 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
10004 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10005 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10006 return Res;
10007}
10008
10009template <typename Derived>
10010StmtResult
10011TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
10012 DeclarationNameInfo DirName;
10013 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10014 OMPD_for, DirName, nullptr, D->getBeginLoc());
10015 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10016 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10017 return Res;
10018}
10019
10020template <typename Derived>
10021StmtResult
10022TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
10023 DeclarationNameInfo DirName;
10024 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10025 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
10026 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10027 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10028 return Res;
10029}
10030
10031template <typename Derived>
10032StmtResult
10033TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
10034 DeclarationNameInfo DirName;
10035 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10036 OMPD_sections, DirName, nullptr, D->getBeginLoc());
10037 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10038 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10039 return Res;
10040}
10041
10042template <typename Derived>
10043StmtResult
10044TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
10045 DeclarationNameInfo DirName;
10046 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10047 OMPD_section, DirName, nullptr, D->getBeginLoc());
10048 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10049 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10050 return Res;
10051}
10052
10053template <typename Derived>
10054StmtResult
10055TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
10056 DeclarationNameInfo DirName;
10057 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10058 OMPD_scope, DirName, nullptr, D->getBeginLoc());
10059 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10060 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10061 return Res;
10062}
10063
10064template <typename Derived>
10065StmtResult
10066TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
10067 DeclarationNameInfo DirName;
10068 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10069 OMPD_single, DirName, nullptr, D->getBeginLoc());
10070 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10071 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10072 return Res;
10073}
10074
10075template <typename Derived>
10076StmtResult
10077TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
10078 DeclarationNameInfo DirName;
10079 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10080 OMPD_master, DirName, nullptr, D->getBeginLoc());
10081 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10082 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10083 return Res;
10084}
10085
10086template <typename Derived>
10087StmtResult
10088TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
10089 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10090 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
10091 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10092 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10093 return Res;
10094}
10095
10096template <typename Derived>
10097StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
10098 OMPParallelForDirective *D) {
10099 DeclarationNameInfo DirName;
10100 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10101 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
10102 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10103 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10104 return Res;
10105}
10106
10107template <typename Derived>
10108StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
10109 OMPParallelForSimdDirective *D) {
10110 DeclarationNameInfo DirName;
10111 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10112 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10113 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10114 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10115 return Res;
10116}
10117
10118template <typename Derived>
10119StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
10120 OMPParallelMasterDirective *D) {
10121 DeclarationNameInfo DirName;
10122 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10123 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
10124 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10125 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10126 return Res;
10127}
10128
10129template <typename Derived>
10130StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
10131 OMPParallelMaskedDirective *D) {
10132 DeclarationNameInfo DirName;
10133 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10134 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
10135 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10136 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10137 return Res;
10138}
10139
10140template <typename Derived>
10141StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
10142 OMPParallelSectionsDirective *D) {
10143 DeclarationNameInfo DirName;
10144 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10145 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
10146 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10147 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10148 return Res;
10149}
10150
10151template <typename Derived>
10152StmtResult
10153TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
10154 DeclarationNameInfo DirName;
10155 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10156 OMPD_task, DirName, nullptr, D->getBeginLoc());
10157 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10158 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10159 return Res;
10160}
10161
10162template <typename Derived>
10163StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
10164 OMPTaskyieldDirective *D) {
10165 DeclarationNameInfo DirName;
10166 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10167 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
10168 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10169 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10170 return Res;
10171}
10172
10173template <typename Derived>
10174StmtResult
10175TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
10176 DeclarationNameInfo DirName;
10177 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10178 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
10179 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10180 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10181 return Res;
10182}
10183
10184template <typename Derived>
10185StmtResult
10186TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
10187 DeclarationNameInfo DirName;
10188 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10189 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
10190 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10191 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10192 return Res;
10193}
10194
10195template <typename Derived>
10196StmtResult
10197TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
10198 DeclarationNameInfo DirName;
10199 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10200 OMPD_assume, DirName, nullptr, D->getBeginLoc());
10201 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
10202 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10203 return Res;
10204}
10205
10206template <typename Derived>
10207StmtResult
10208TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
10209 DeclarationNameInfo DirName;
10210 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10211 OMPD_error, DirName, nullptr, D->getBeginLoc());
10212 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10213 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10214 return Res;
10215}
10216
10217template <typename Derived>
10218StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
10219 OMPTaskgroupDirective *D) {
10220 DeclarationNameInfo DirName;
10221 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10222 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
10223 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10224 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10225 return Res;
10226}
10227
10228template <typename Derived>
10229StmtResult
10230TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
10231 DeclarationNameInfo DirName;
10232 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10233 OMPD_flush, DirName, nullptr, D->getBeginLoc());
10234 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10235 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10236 return Res;
10237}
10238
10239template <typename Derived>
10240StmtResult
10241TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
10242 DeclarationNameInfo DirName;
10243 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10244 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
10245 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10246 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10247 return Res;
10248}
10249
10250template <typename Derived>
10251StmtResult
10252TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
10253 DeclarationNameInfo DirName;
10254 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10255 OMPD_scan, DirName, nullptr, D->getBeginLoc());
10256 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10257 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10258 return Res;
10259}
10260
10261template <typename Derived>
10262StmtResult
10263TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
10264 DeclarationNameInfo DirName;
10265 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10266 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
10267 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10268 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10269 return Res;
10270}
10271
10272template <typename Derived>
10273StmtResult
10274TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
10275 DeclarationNameInfo DirName;
10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10277 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
10278 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10279 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10280 return Res;
10281}
10282
10283template <typename Derived>
10284StmtResult
10285TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
10286 DeclarationNameInfo DirName;
10287 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10288 OMPD_target, DirName, nullptr, D->getBeginLoc());
10289 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10290 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10291 return Res;
10292}
10293
10294template <typename Derived>
10295StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
10296 OMPTargetDataDirective *D) {
10297 DeclarationNameInfo DirName;
10298 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10299 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
10300 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10301 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10302 return Res;
10303}
10304
10305template <typename Derived>
10306StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
10307 OMPTargetEnterDataDirective *D) {
10308 DeclarationNameInfo DirName;
10309 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10310 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
10311 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10312 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10313 return Res;
10314}
10315
10316template <typename Derived>
10317StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
10318 OMPTargetExitDataDirective *D) {
10319 DeclarationNameInfo DirName;
10320 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10321 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10322 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10323 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10324 return Res;
10325}
10326
10327template <typename Derived>
10328StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10329 OMPTargetParallelDirective *D) {
10330 DeclarationNameInfo DirName;
10331 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10332 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10333 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10334 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10335 return Res;
10336}
10337
10338template <typename Derived>
10339StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10340 OMPTargetParallelForDirective *D) {
10341 DeclarationNameInfo DirName;
10342 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10343 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10344 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10345 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10346 return Res;
10347}
10348
10349template <typename Derived>
10350StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10351 OMPTargetUpdateDirective *D) {
10352 DeclarationNameInfo DirName;
10353 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10354 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10355 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10356 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10357 return Res;
10358}
10359
10360template <typename Derived>
10361StmtResult
10362TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10363 DeclarationNameInfo DirName;
10364 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10365 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10366 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10367 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10368 return Res;
10369}
10370
10371template <typename Derived>
10372StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10373 OMPCancellationPointDirective *D) {
10374 DeclarationNameInfo DirName;
10375 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10376 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10377 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10378 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10379 return Res;
10380}
10381
10382template <typename Derived>
10383StmtResult
10384TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10385 DeclarationNameInfo DirName;
10386 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10387 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10388 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10389 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10390 return Res;
10391}
10392
10393template <typename Derived>
10394StmtResult
10395TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10396 DeclarationNameInfo DirName;
10397 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10398 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10399 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10400 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10401 return Res;
10402}
10403
10404template <typename Derived>
10405StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10406 OMPTaskLoopSimdDirective *D) {
10407 DeclarationNameInfo DirName;
10408 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10409 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10410 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10411 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10412 return Res;
10413}
10414
10415template <typename Derived>
10416StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10417 OMPMasterTaskLoopDirective *D) {
10418 DeclarationNameInfo DirName;
10419 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10420 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10421 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10422 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10423 return Res;
10424}
10425
10426template <typename Derived>
10427StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10428 OMPMaskedTaskLoopDirective *D) {
10429 DeclarationNameInfo DirName;
10430 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10431 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10432 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10433 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10434 return Res;
10435}
10436
10437template <typename Derived>
10438StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10439 OMPMasterTaskLoopSimdDirective *D) {
10440 DeclarationNameInfo DirName;
10441 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10442 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10443 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10444 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10445 return Res;
10446}
10447
10448template <typename Derived>
10449StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10450 OMPMaskedTaskLoopSimdDirective *D) {
10451 DeclarationNameInfo DirName;
10452 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10453 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10454 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10455 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10456 return Res;
10457}
10458
10459template <typename Derived>
10460StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10461 OMPParallelMasterTaskLoopDirective *D) {
10462 DeclarationNameInfo DirName;
10463 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10464 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10465 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10466 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10467 return Res;
10468}
10469
10470template <typename Derived>
10471StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10472 OMPParallelMaskedTaskLoopDirective *D) {
10473 DeclarationNameInfo DirName;
10474 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10475 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10476 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10477 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10478 return Res;
10479}
10480
10481template <typename Derived>
10482StmtResult
10483TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10484 OMPParallelMasterTaskLoopSimdDirective *D) {
10485 DeclarationNameInfo DirName;
10486 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10487 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10488 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10489 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10490 return Res;
10491}
10492
10493template <typename Derived>
10494StmtResult
10495TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10496 OMPParallelMaskedTaskLoopSimdDirective *D) {
10497 DeclarationNameInfo DirName;
10498 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10499 OMPD_parallel_masked_taskloop_simd, 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>::TransformOMPDistributeDirective(
10507 OMPDistributeDirective *D) {
10508 DeclarationNameInfo DirName;
10509 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10510 OMPD_distribute, 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>::TransformOMPDistributeParallelForDirective(
10518 OMPDistributeParallelForDirective *D) {
10519 DeclarationNameInfo DirName;
10520 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10521 OMPD_distribute_parallel_for, 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
10529TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10530 OMPDistributeParallelForSimdDirective *D) {
10531 DeclarationNameInfo DirName;
10532 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10533 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10534 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10535 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10536 return Res;
10537}
10538
10539template <typename Derived>
10540StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10541 OMPDistributeSimdDirective *D) {
10542 DeclarationNameInfo DirName;
10543 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10544 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10545 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10546 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10547 return Res;
10548}
10549
10550template <typename Derived>
10551StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10552 OMPTargetParallelForSimdDirective *D) {
10553 DeclarationNameInfo DirName;
10554 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10555 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10556 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10557 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10558 return Res;
10559}
10560
10561template <typename Derived>
10562StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10563 OMPTargetSimdDirective *D) {
10564 DeclarationNameInfo DirName;
10565 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10566 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10567 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10568 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10569 return Res;
10570}
10571
10572template <typename Derived>
10573StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10574 OMPTeamsDistributeDirective *D) {
10575 DeclarationNameInfo DirName;
10576 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10577 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10578 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10579 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10580 return Res;
10581}
10582
10583template <typename Derived>
10584StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10585 OMPTeamsDistributeSimdDirective *D) {
10586 DeclarationNameInfo DirName;
10587 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10588 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10589 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10590 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10591 return Res;
10592}
10593
10594template <typename Derived>
10595StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10596 OMPTeamsDistributeParallelForSimdDirective *D) {
10597 DeclarationNameInfo DirName;
10598 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10599 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10600 D->getBeginLoc());
10601 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10602 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10603 return Res;
10604}
10605
10606template <typename Derived>
10607StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10608 OMPTeamsDistributeParallelForDirective *D) {
10609 DeclarationNameInfo DirName;
10610 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10611 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10612 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10613 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10614 return Res;
10615}
10616
10617template <typename Derived>
10618StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10619 OMPTargetTeamsDirective *D) {
10620 DeclarationNameInfo DirName;
10621 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10622 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10623 auto Res = getDerived().TransformOMPExecutableDirective(D);
10624 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10625 return Res;
10626}
10627
10628template <typename Derived>
10629StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10630 OMPTargetTeamsDistributeDirective *D) {
10631 DeclarationNameInfo DirName;
10632 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10633 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10634 auto Res = getDerived().TransformOMPExecutableDirective(D);
10635 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10636 return Res;
10637}
10638
10639template <typename Derived>
10640StmtResult
10641TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10642 OMPTargetTeamsDistributeParallelForDirective *D) {
10643 DeclarationNameInfo DirName;
10644 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10645 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10646 D->getBeginLoc());
10647 auto Res = getDerived().TransformOMPExecutableDirective(D);
10648 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10649 return Res;
10650}
10651
10652template <typename Derived>
10653StmtResult TreeTransform<Derived>::
10654 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10655 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10656 DeclarationNameInfo DirName;
10657 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10658 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10659 D->getBeginLoc());
10660 auto Res = getDerived().TransformOMPExecutableDirective(D);
10661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10662 return Res;
10663}
10664
10665template <typename Derived>
10666StmtResult
10667TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10668 OMPTargetTeamsDistributeSimdDirective *D) {
10669 DeclarationNameInfo DirName;
10670 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10671 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10672 auto Res = getDerived().TransformOMPExecutableDirective(D);
10673 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10674 return Res;
10675}
10676
10677template <typename Derived>
10678StmtResult
10679TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10680 DeclarationNameInfo DirName;
10681 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10682 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10683 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10684 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10685 return Res;
10686}
10687
10688template <typename Derived>
10689StmtResult
10690TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10691 DeclarationNameInfo DirName;
10692 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10693 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10694 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10695 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10696 return Res;
10697}
10698
10699template <typename Derived>
10700StmtResult
10701TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10702 DeclarationNameInfo DirName;
10703 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10704 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10705 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10706 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10707 return Res;
10708}
10709
10710template <typename Derived>
10711StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10712 OMPGenericLoopDirective *D) {
10713 DeclarationNameInfo DirName;
10714 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10715 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10716 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10717 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10718 return Res;
10719}
10720
10721template <typename Derived>
10722StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10723 OMPTeamsGenericLoopDirective *D) {
10724 DeclarationNameInfo DirName;
10725 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10726 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10727 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10728 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10729 return Res;
10730}
10731
10732template <typename Derived>
10733StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10734 OMPTargetTeamsGenericLoopDirective *D) {
10735 DeclarationNameInfo DirName;
10736 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10737 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10738 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10739 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10740 return Res;
10741}
10742
10743template <typename Derived>
10744StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10745 OMPParallelGenericLoopDirective *D) {
10746 DeclarationNameInfo DirName;
10747 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10748 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10749 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10750 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10751 return Res;
10752}
10753
10754template <typename Derived>
10755StmtResult
10756TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10757 OMPTargetParallelGenericLoopDirective *D) {
10758 DeclarationNameInfo DirName;
10759 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10760 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10761 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10762 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10763 return Res;
10764}
10765
10766//===----------------------------------------------------------------------===//
10767// OpenMP clause transformation
10768//===----------------------------------------------------------------------===//
10769template <typename Derived>
10770OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10771 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10772 if (Cond.isInvalid())
10773 return nullptr;
10774 return getDerived().RebuildOMPIfClause(
10775 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10776 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10777}
10778
10779template <typename Derived>
10780OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10781 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10782 if (Cond.isInvalid())
10783 return nullptr;
10784 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10785 C->getLParenLoc(), C->getEndLoc());
10786}
10787
10788template <typename Derived>
10789OMPClause *
10790TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10791 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10792 if (NumThreads.isInvalid())
10793 return nullptr;
10794 return getDerived().RebuildOMPNumThreadsClause(
10795 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10796 C->getModifierLoc(), C->getEndLoc());
10797}
10798
10799template <typename Derived>
10800OMPClause *
10801TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10802 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10803 if (E.isInvalid())
10804 return nullptr;
10805 return getDerived().RebuildOMPSafelenClause(
10806 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10807}
10808
10809template <typename Derived>
10810OMPClause *
10811TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10812 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10813 if (E.isInvalid())
10814 return nullptr;
10815 return getDerived().RebuildOMPAllocatorClause(
10816 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10817}
10818
10819template <typename Derived>
10820OMPClause *
10821TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10822 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10823 if (E.isInvalid())
10824 return nullptr;
10825 return getDerived().RebuildOMPSimdlenClause(
10826 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10827}
10828
10829template <typename Derived>
10830OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10831 SmallVector<Expr *, 4> TransformedSizes;
10832 TransformedSizes.reserve(N: C->getNumSizes());
10833 bool Changed = false;
10834 for (Expr *E : C->getSizesRefs()) {
10835 if (!E) {
10836 TransformedSizes.push_back(Elt: nullptr);
10837 continue;
10838 }
10839
10840 ExprResult T = getDerived().TransformExpr(E);
10841 if (T.isInvalid())
10842 return nullptr;
10843 if (E != T.get())
10844 Changed = true;
10845 TransformedSizes.push_back(Elt: T.get());
10846 }
10847
10848 if (!Changed && !getDerived().AlwaysRebuild())
10849 return C;
10850 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10851 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10852}
10853
10854template <typename Derived>
10855OMPClause *
10856TreeTransform<Derived>::TransformOMPCountsClause(OMPCountsClause *C) {
10857 SmallVector<Expr *, 4> TransformedCounts;
10858 TransformedCounts.reserve(N: C->getNumCounts());
10859 for (Expr *E : C->getCountsRefs()) {
10860 if (!E) {
10861 TransformedCounts.push_back(Elt: nullptr);
10862 continue;
10863 }
10864
10865 ExprResult T = getDerived().TransformExpr(E);
10866 if (T.isInvalid())
10867 return nullptr;
10868 TransformedCounts.push_back(Elt: T.get());
10869 }
10870
10871 return RebuildOMPCountsClause(Counts: TransformedCounts, StartLoc: C->getBeginLoc(),
10872 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc(),
10873 FillIdx: C->getOmpFillIndex(), FillLoc: C->getOmpFillLoc());
10874}
10875
10876template <typename Derived>
10877OMPClause *
10878TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10879 SmallVector<Expr *> TransformedArgs;
10880 TransformedArgs.reserve(N: C->getNumLoops());
10881 bool Changed = false;
10882 for (Expr *E : C->getArgsRefs()) {
10883 if (!E) {
10884 TransformedArgs.push_back(Elt: nullptr);
10885 continue;
10886 }
10887
10888 ExprResult T = getDerived().TransformExpr(E);
10889 if (T.isInvalid())
10890 return nullptr;
10891 if (E != T.get())
10892 Changed = true;
10893 TransformedArgs.push_back(Elt: T.get());
10894 }
10895
10896 if (!Changed && !getDerived().AlwaysRebuild())
10897 return C;
10898 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10899 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10900}
10901
10902template <typename Derived>
10903OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10904 if (!getDerived().AlwaysRebuild())
10905 return C;
10906 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10907}
10908
10909template <typename Derived>
10910OMPClause *
10911TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10912 ExprResult T = getDerived().TransformExpr(C->getFactor());
10913 if (T.isInvalid())
10914 return nullptr;
10915 Expr *Factor = T.get();
10916 bool Changed = Factor != C->getFactor();
10917
10918 if (!Changed && !getDerived().AlwaysRebuild())
10919 return C;
10920 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10921 EndLoc: C->getEndLoc());
10922}
10923
10924template <typename Derived>
10925OMPClause *
10926TreeTransform<Derived>::TransformOMPLoopRangeClause(OMPLoopRangeClause *C) {
10927 ExprResult F = getDerived().TransformExpr(C->getFirst());
10928 if (F.isInvalid())
10929 return nullptr;
10930
10931 ExprResult Cn = getDerived().TransformExpr(C->getCount());
10932 if (Cn.isInvalid())
10933 return nullptr;
10934
10935 Expr *First = F.get();
10936 Expr *Count = Cn.get();
10937
10938 bool Changed = (First != C->getFirst()) || (Count != C->getCount());
10939
10940 // If no changes and AlwaysRebuild() is false, return the original clause
10941 if (!Changed && !getDerived().AlwaysRebuild())
10942 return C;
10943
10944 return RebuildOMPLoopRangeClause(First, Count, StartLoc: C->getBeginLoc(),
10945 LParenLoc: C->getLParenLoc(), FirstLoc: C->getFirstLoc(),
10946 CountLoc: C->getCountLoc(), EndLoc: C->getEndLoc());
10947}
10948
10949template <typename Derived>
10950OMPClause *
10951TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10952 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10953 if (E.isInvalid())
10954 return nullptr;
10955 return getDerived().RebuildOMPCollapseClause(
10956 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10957}
10958
10959template <typename Derived>
10960OMPClause *
10961TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10962 return getDerived().RebuildOMPDefaultClause(
10963 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getDefaultVC(),
10964 C->getDefaultVCLoc(), C->getBeginLoc(), C->getLParenLoc(),
10965 C->getEndLoc());
10966}
10967
10968template <typename Derived>
10969OMPClause *
10970TreeTransform<Derived>::TransformOMPThreadsetClause(OMPThreadsetClause *C) {
10971 // No need to rebuild this clause, no template-dependent parameters.
10972 return C;
10973}
10974
10975template <typename Derived>
10976OMPClause *
10977TreeTransform<Derived>::TransformOMPTransparentClause(OMPTransparentClause *C) {
10978 Expr *Impex = C->getImpexType();
10979 ExprResult TransformedImpex = getDerived().TransformExpr(Impex);
10980
10981 if (TransformedImpex.isInvalid())
10982 return nullptr;
10983
10984 return getDerived().RebuildOMPTransparentClause(
10985 TransformedImpex.get(), C->getBeginLoc(), C->getLParenLoc(),
10986 C->getEndLoc());
10987}
10988
10989template <typename Derived>
10990OMPClause *
10991TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10992 return getDerived().RebuildOMPProcBindClause(
10993 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10994 C->getLParenLoc(), C->getEndLoc());
10995}
10996
10997template <typename Derived>
10998OMPClause *
10999TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
11000 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11001 if (E.isInvalid())
11002 return nullptr;
11003 return getDerived().RebuildOMPScheduleClause(
11004 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
11005 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11006 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
11007 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11008}
11009
11010template <typename Derived>
11011OMPClause *
11012TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
11013 ExprResult E;
11014 if (auto *Num = C->getNumForLoops()) {
11015 E = getDerived().TransformExpr(Num);
11016 if (E.isInvalid())
11017 return nullptr;
11018 }
11019 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
11020 C->getLParenLoc(), E.get());
11021}
11022
11023template <typename Derived>
11024OMPClause *
11025TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
11026 ExprResult E;
11027 if (Expr *Evt = C->getEventHandler()) {
11028 E = getDerived().TransformExpr(Evt);
11029 if (E.isInvalid())
11030 return nullptr;
11031 }
11032 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
11033 C->getLParenLoc(), C->getEndLoc());
11034}
11035
11036template <typename Derived>
11037OMPClause *
11038TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
11039 ExprResult Cond;
11040 if (auto *Condition = C->getCondition()) {
11041 Cond = getDerived().TransformExpr(Condition);
11042 if (Cond.isInvalid())
11043 return nullptr;
11044 }
11045 return getDerived().RebuildOMPNowaitClause(Cond.get(), C->getBeginLoc(),
11046 C->getLParenLoc(), C->getEndLoc());
11047}
11048
11049template <typename Derived>
11050OMPClause *
11051TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
11052 // No need to rebuild this clause, no template-dependent parameters.
11053 return C;
11054}
11055
11056template <typename Derived>
11057OMPClause *
11058TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
11059 // No need to rebuild this clause, no template-dependent parameters.
11060 return C;
11061}
11062
11063template <typename Derived>
11064OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
11065 // No need to rebuild this clause, no template-dependent parameters.
11066 return C;
11067}
11068
11069template <typename Derived>
11070OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
11071 // No need to rebuild this clause, no template-dependent parameters.
11072 return C;
11073}
11074
11075template <typename Derived>
11076OMPClause *
11077TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
11078 // No need to rebuild this clause, no template-dependent parameters.
11079 return C;
11080}
11081
11082template <typename Derived>
11083OMPClause *
11084TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
11085 // No need to rebuild this clause, no template-dependent parameters.
11086 return C;
11087}
11088
11089template <typename Derived>
11090OMPClause *
11091TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
11092 // No need to rebuild this clause, no template-dependent parameters.
11093 return C;
11094}
11095
11096template <typename Derived>
11097OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
11098 // No need to rebuild this clause, no template-dependent parameters.
11099 return C;
11100}
11101
11102template <typename Derived>
11103OMPClause *
11104TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
11105 return C;
11106}
11107
11108template <typename Derived>
11109OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
11110 ExprResult E = getDerived().TransformExpr(C->getExpr());
11111 if (E.isInvalid())
11112 return nullptr;
11113 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
11114 C->getLParenLoc(), C->getEndLoc());
11115}
11116
11117template <typename Derived>
11118OMPClause *
11119TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
11120 return C;
11121}
11122
11123template <typename Derived>
11124OMPClause *
11125TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
11126 return C;
11127}
11128template <typename Derived>
11129OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
11130 OMPNoOpenMPRoutinesClause *C) {
11131 return C;
11132}
11133template <typename Derived>
11134OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
11135 OMPNoOpenMPConstructsClause *C) {
11136 return C;
11137}
11138template <typename Derived>
11139OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
11140 OMPNoParallelismClause *C) {
11141 return C;
11142}
11143
11144template <typename Derived>
11145OMPClause *
11146TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
11147 // No need to rebuild this clause, no template-dependent parameters.
11148 return C;
11149}
11150
11151template <typename Derived>
11152OMPClause *
11153TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
11154 // No need to rebuild this clause, no template-dependent parameters.
11155 return C;
11156}
11157
11158template <typename Derived>
11159OMPClause *
11160TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
11161 // No need to rebuild this clause, no template-dependent parameters.
11162 return C;
11163}
11164
11165template <typename Derived>
11166OMPClause *
11167TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
11168 // No need to rebuild this clause, no template-dependent parameters.
11169 return C;
11170}
11171
11172template <typename Derived>
11173OMPClause *
11174TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
11175 // No need to rebuild this clause, no template-dependent parameters.
11176 return C;
11177}
11178
11179template <typename Derived>
11180OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
11181 // No need to rebuild this clause, no template-dependent parameters.
11182 return C;
11183}
11184
11185template <typename Derived>
11186OMPClause *
11187TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
11188 // No need to rebuild this clause, no template-dependent parameters.
11189 return C;
11190}
11191
11192template <typename Derived>
11193OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
11194 // No need to rebuild this clause, no template-dependent parameters.
11195 return C;
11196}
11197
11198template <typename Derived>
11199OMPClause *
11200TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
11201 // No need to rebuild this clause, no template-dependent parameters.
11202 return C;
11203}
11204
11205template <typename Derived>
11206OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
11207 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
11208 if (IVR.isInvalid())
11209 return nullptr;
11210
11211 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
11212 for (OMPInitClause::PrefView P : C->prefs()) {
11213 Expr *NewFr = nullptr;
11214 if (P.Fr) {
11215 ExprResult ER = getDerived().TransformExpr(P.Fr);
11216 if (ER.isInvalid())
11217 return nullptr;
11218 NewFr = ER.get();
11219 }
11220 SmallVector<Expr *, 2> NewAttrs;
11221 NewAttrs.reserve(N: P.Attrs.size());
11222 for (Expr *A : P.Attrs) {
11223 ExprResult ER = getDerived().TransformExpr(A);
11224 if (ER.isInvalid())
11225 return nullptr;
11226 NewAttrs.push_back(Elt: ER.get());
11227 }
11228 InteropInfo.Prefs.emplace_back(Args&: NewFr, Args: std::move(NewAttrs));
11229 }
11230 InteropInfo.HasPreferAttrs = C->hasPreferAttrs();
11231 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
11232 C->getBeginLoc(), C->getLParenLoc(),
11233 C->getVarLoc(), C->getEndLoc());
11234}
11235
11236template <typename Derived>
11237OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
11238 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
11239 if (ER.isInvalid())
11240 return nullptr;
11241 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
11242 C->getLParenLoc(), C->getVarLoc(),
11243 C->getEndLoc());
11244}
11245
11246template <typename Derived>
11247OMPClause *
11248TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
11249 ExprResult ER;
11250 if (Expr *IV = C->getInteropVar()) {
11251 ER = getDerived().TransformExpr(IV);
11252 if (ER.isInvalid())
11253 return nullptr;
11254 }
11255 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
11256 C->getLParenLoc(), C->getVarLoc(),
11257 C->getEndLoc());
11258}
11259
11260template <typename Derived>
11261OMPClause *
11262TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
11263 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11264 if (Cond.isInvalid())
11265 return nullptr;
11266 return getDerived().RebuildOMPNovariantsClause(
11267 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11268}
11269
11270template <typename Derived>
11271OMPClause *
11272TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
11273 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
11274 if (Cond.isInvalid())
11275 return nullptr;
11276 return getDerived().RebuildOMPNocontextClause(
11277 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11278}
11279
11280template <typename Derived>
11281OMPClause *
11282TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
11283 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
11284 if (ThreadID.isInvalid())
11285 return nullptr;
11286 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
11287 C->getLParenLoc(), C->getEndLoc());
11288}
11289
11290template <typename Derived>
11291OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
11292 ExprResult E = getDerived().TransformExpr(C->getAlignment());
11293 if (E.isInvalid())
11294 return nullptr;
11295 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
11296 C->getLParenLoc(), C->getEndLoc());
11297}
11298
11299template <typename Derived>
11300OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
11301 OMPUnifiedAddressClause *C) {
11302 llvm_unreachable("unified_address clause cannot appear in dependent context");
11303}
11304
11305template <typename Derived>
11306OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
11307 OMPUnifiedSharedMemoryClause *C) {
11308 llvm_unreachable(
11309 "unified_shared_memory clause cannot appear in dependent context");
11310}
11311
11312template <typename Derived>
11313OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
11314 OMPReverseOffloadClause *C) {
11315 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
11316}
11317
11318template <typename Derived>
11319OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
11320 OMPDynamicAllocatorsClause *C) {
11321 llvm_unreachable(
11322 "dynamic_allocators clause cannot appear in dependent context");
11323}
11324
11325template <typename Derived>
11326OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
11327 OMPAtomicDefaultMemOrderClause *C) {
11328 llvm_unreachable(
11329 "atomic_default_mem_order clause cannot appear in dependent context");
11330}
11331
11332template <typename Derived>
11333OMPClause *
11334TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
11335 llvm_unreachable("self_maps clause cannot appear in dependent context");
11336}
11337
11338template <typename Derived>
11339OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
11340 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
11341 C->getBeginLoc(), C->getLParenLoc(),
11342 C->getEndLoc());
11343}
11344
11345template <typename Derived>
11346OMPClause *
11347TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
11348 return getDerived().RebuildOMPSeverityClause(
11349 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
11350 C->getLParenLoc(), C->getEndLoc());
11351}
11352
11353template <typename Derived>
11354OMPClause *
11355TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
11356 ExprResult E = getDerived().TransformExpr(C->getMessageString());
11357 if (E.isInvalid())
11358 return nullptr;
11359 return getDerived().RebuildOMPMessageClause(
11360 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11361}
11362
11363template <typename Derived>
11364OMPClause *
11365TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
11366 llvm::SmallVector<Expr *, 16> Vars;
11367 Vars.reserve(N: C->varlist_size());
11368 for (auto *VE : C->varlist()) {
11369 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11370 if (EVar.isInvalid())
11371 return nullptr;
11372 Vars.push_back(Elt: EVar.get());
11373 }
11374 return getDerived().RebuildOMPPrivateClause(
11375 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11376}
11377
11378template <typename Derived>
11379OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
11380 OMPFirstprivateClause *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 return getDerived().RebuildOMPFirstprivateClause(
11390 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11391}
11392
11393template <typename Derived>
11394OMPClause *
11395TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
11396 llvm::SmallVector<Expr *, 16> Vars;
11397 Vars.reserve(N: C->varlist_size());
11398 for (auto *VE : C->varlist()) {
11399 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11400 if (EVar.isInvalid())
11401 return nullptr;
11402 Vars.push_back(Elt: EVar.get());
11403 }
11404 return getDerived().RebuildOMPLastprivateClause(
11405 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
11406 C->getLParenLoc(), C->getEndLoc());
11407}
11408
11409template <typename Derived>
11410OMPClause *
11411TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11412 llvm::SmallVector<Expr *, 16> Vars;
11413 Vars.reserve(N: C->varlist_size());
11414 for (auto *VE : C->varlist()) {
11415 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11416 if (EVar.isInvalid())
11417 return nullptr;
11418 Vars.push_back(Elt: EVar.get());
11419 }
11420 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11421 C->getLParenLoc(), C->getEndLoc());
11422}
11423
11424template <typename Derived>
11425OMPClause *
11426TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11427 llvm::SmallVector<Expr *, 16> Vars;
11428 Vars.reserve(N: C->varlist_size());
11429 for (auto *VE : C->varlist()) {
11430 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11431 if (EVar.isInvalid())
11432 return nullptr;
11433 Vars.push_back(Elt: EVar.get());
11434 }
11435 CXXScopeSpec ReductionIdScopeSpec;
11436 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11437
11438 DeclarationNameInfo NameInfo = C->getNameInfo();
11439 if (NameInfo.getName()) {
11440 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11441 if (!NameInfo.getName())
11442 return nullptr;
11443 }
11444 // Build a list of all UDR decls with the same names ranged by the Scopes.
11445 // The Scope boundary is a duplication of the previous decl.
11446 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11447 for (auto *E : C->reduction_ops()) {
11448 // Transform all the decls.
11449 if (E) {
11450 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11451 UnresolvedSet<8> Decls;
11452 for (auto *D : ULE->decls()) {
11453 NamedDecl *InstD =
11454 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11455 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11456 }
11457 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11458 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11459 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11460 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11461 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11462 } else
11463 UnresolvedReductions.push_back(Elt: nullptr);
11464 }
11465 return getDerived().RebuildOMPReductionClause(
11466 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11467 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11468 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11469}
11470
11471template <typename Derived>
11472OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11473 OMPTaskReductionClause *C) {
11474 llvm::SmallVector<Expr *, 16> Vars;
11475 Vars.reserve(N: C->varlist_size());
11476 for (auto *VE : C->varlist()) {
11477 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11478 if (EVar.isInvalid())
11479 return nullptr;
11480 Vars.push_back(Elt: EVar.get());
11481 }
11482 CXXScopeSpec ReductionIdScopeSpec;
11483 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11484
11485 DeclarationNameInfo NameInfo = C->getNameInfo();
11486 if (NameInfo.getName()) {
11487 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11488 if (!NameInfo.getName())
11489 return nullptr;
11490 }
11491 // Build a list of all UDR decls with the same names ranged by the Scopes.
11492 // The Scope boundary is a duplication of the previous decl.
11493 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11494 for (auto *E : C->reduction_ops()) {
11495 // Transform all the decls.
11496 if (E) {
11497 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11498 UnresolvedSet<8> Decls;
11499 for (auto *D : ULE->decls()) {
11500 NamedDecl *InstD =
11501 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11502 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11503 }
11504 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11505 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11506 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11507 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11508 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11509 } else
11510 UnresolvedReductions.push_back(Elt: nullptr);
11511 }
11512 return getDerived().RebuildOMPTaskReductionClause(
11513 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11514 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11515}
11516
11517template <typename Derived>
11518OMPClause *
11519TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11520 llvm::SmallVector<Expr *, 16> Vars;
11521 Vars.reserve(N: C->varlist_size());
11522 for (auto *VE : C->varlist()) {
11523 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11524 if (EVar.isInvalid())
11525 return nullptr;
11526 Vars.push_back(Elt: EVar.get());
11527 }
11528 CXXScopeSpec ReductionIdScopeSpec;
11529 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11530
11531 DeclarationNameInfo NameInfo = C->getNameInfo();
11532 if (NameInfo.getName()) {
11533 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11534 if (!NameInfo.getName())
11535 return nullptr;
11536 }
11537 // Build a list of all UDR decls with the same names ranged by the Scopes.
11538 // The Scope boundary is a duplication of the previous decl.
11539 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11540 for (auto *E : C->reduction_ops()) {
11541 // Transform all the decls.
11542 if (E) {
11543 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11544 UnresolvedSet<8> Decls;
11545 for (auto *D : ULE->decls()) {
11546 NamedDecl *InstD =
11547 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11548 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11549 }
11550 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11551 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11552 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11553 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11554 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11555 } else
11556 UnresolvedReductions.push_back(Elt: nullptr);
11557 }
11558 return getDerived().RebuildOMPInReductionClause(
11559 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11560 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11561}
11562
11563template <typename Derived>
11564OMPClause *
11565TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11566 llvm::SmallVector<Expr *, 16> Vars;
11567 Vars.reserve(N: C->varlist_size());
11568 for (auto *VE : C->varlist()) {
11569 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11570 if (EVar.isInvalid())
11571 return nullptr;
11572 Vars.push_back(Elt: EVar.get());
11573 }
11574 ExprResult Step = getDerived().TransformExpr(C->getStep());
11575 if (Step.isInvalid())
11576 return nullptr;
11577 return getDerived().RebuildOMPLinearClause(
11578 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11579 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11580 C->getEndLoc());
11581}
11582
11583template <typename Derived>
11584OMPClause *
11585TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11586 llvm::SmallVector<Expr *, 16> Vars;
11587 Vars.reserve(N: C->varlist_size());
11588 for (auto *VE : C->varlist()) {
11589 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11590 if (EVar.isInvalid())
11591 return nullptr;
11592 Vars.push_back(Elt: EVar.get());
11593 }
11594 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11595 if (Alignment.isInvalid())
11596 return nullptr;
11597 return getDerived().RebuildOMPAlignedClause(
11598 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11599 C->getColonLoc(), C->getEndLoc());
11600}
11601
11602template <typename Derived>
11603OMPClause *
11604TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11605 llvm::SmallVector<Expr *, 16> Vars;
11606 Vars.reserve(N: C->varlist_size());
11607 for (auto *VE : C->varlist()) {
11608 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11609 if (EVar.isInvalid())
11610 return nullptr;
11611 Vars.push_back(Elt: EVar.get());
11612 }
11613 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11614 C->getLParenLoc(), C->getEndLoc());
11615}
11616
11617template <typename Derived>
11618OMPClause *
11619TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11620 llvm::SmallVector<Expr *, 16> 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().RebuildOMPCopyprivateClause(
11629 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11630}
11631
11632template <typename Derived>
11633OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11634 llvm::SmallVector<Expr *, 16> Vars;
11635 Vars.reserve(N: C->varlist_size());
11636 for (auto *VE : C->varlist()) {
11637 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11638 if (EVar.isInvalid())
11639 return nullptr;
11640 Vars.push_back(Elt: EVar.get());
11641 }
11642 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11643 C->getLParenLoc(), C->getEndLoc());
11644}
11645
11646template <typename Derived>
11647OMPClause *
11648TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11649 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11650 if (E.isInvalid())
11651 return nullptr;
11652 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11653 C->getLParenLoc(), C->getEndLoc());
11654}
11655
11656template <typename Derived>
11657OMPClause *
11658TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11659 llvm::SmallVector<Expr *, 16> Vars;
11660 Expr *DepModifier = C->getModifier();
11661 if (DepModifier) {
11662 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11663 if (DepModRes.isInvalid())
11664 return nullptr;
11665 DepModifier = DepModRes.get();
11666 }
11667 Vars.reserve(N: C->varlist_size());
11668 for (auto *VE : C->varlist()) {
11669 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11670 if (EVar.isInvalid())
11671 return nullptr;
11672 Vars.push_back(Elt: EVar.get());
11673 }
11674 return getDerived().RebuildOMPDependClause(
11675 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11676 C->getOmpAllMemoryLoc()},
11677 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11678}
11679
11680template <typename Derived>
11681OMPClause *
11682TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11683 ExprResult E = getDerived().TransformExpr(C->getDevice());
11684 if (E.isInvalid())
11685 return nullptr;
11686 return getDerived().RebuildOMPDeviceClause(
11687 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11688 C->getModifierLoc(), C->getEndLoc());
11689}
11690
11691template <typename Derived, class T>
11692bool transformOMPMappableExprListClause(
11693 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11694 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11695 DeclarationNameInfo &MapperIdInfo,
11696 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11697 // Transform expressions in the list.
11698 Vars.reserve(N: C->varlist_size());
11699 for (auto *VE : C->varlist()) {
11700 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11701 if (EVar.isInvalid())
11702 return true;
11703 Vars.push_back(Elt: EVar.get());
11704 }
11705 // Transform mapper scope specifier and identifier.
11706 NestedNameSpecifierLoc QualifierLoc;
11707 if (C->getMapperQualifierLoc()) {
11708 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11709 C->getMapperQualifierLoc());
11710 if (!QualifierLoc)
11711 return true;
11712 }
11713 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11714 MapperIdInfo = C->getMapperIdInfo();
11715 if (MapperIdInfo.getName()) {
11716 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11717 if (!MapperIdInfo.getName())
11718 return true;
11719 }
11720 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11721 // the previous user-defined mapper lookup in dependent environment.
11722 for (auto *E : C->mapperlists()) {
11723 // Transform all the decls.
11724 if (E) {
11725 auto *ULE = cast<UnresolvedLookupExpr>(E);
11726 UnresolvedSet<8> Decls;
11727 for (auto *D : ULE->decls()) {
11728 NamedDecl *InstD =
11729 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11730 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11731 }
11732 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11733 TT.getSema().Context, /*NamingClass=*/nullptr,
11734 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11735 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11736 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11737 } else {
11738 UnresolvedMappers.push_back(Elt: nullptr);
11739 }
11740 }
11741 return false;
11742}
11743
11744template <typename Derived>
11745OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11746 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11747 llvm::SmallVector<Expr *, 16> Vars;
11748 Expr *IteratorModifier = C->getIteratorModifier();
11749 if (IteratorModifier) {
11750 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11751 if (MapModRes.isInvalid())
11752 return nullptr;
11753 IteratorModifier = MapModRes.get();
11754 }
11755 CXXScopeSpec MapperIdScopeSpec;
11756 DeclarationNameInfo MapperIdInfo;
11757 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11758 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11759 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11760 return nullptr;
11761 return getDerived().RebuildOMPMapClause(
11762 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11763 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11764 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11765}
11766
11767template <typename Derived>
11768OMPClause *
11769TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11770 Expr *Allocator = C->getAllocator();
11771 if (Allocator) {
11772 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11773 if (AllocatorRes.isInvalid())
11774 return nullptr;
11775 Allocator = AllocatorRes.get();
11776 }
11777 Expr *Alignment = C->getAlignment();
11778 if (Alignment) {
11779 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11780 if (AlignmentRes.isInvalid())
11781 return nullptr;
11782 Alignment = AlignmentRes.get();
11783 }
11784 llvm::SmallVector<Expr *, 16> Vars;
11785 Vars.reserve(N: C->varlist_size());
11786 for (auto *VE : C->varlist()) {
11787 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11788 if (EVar.isInvalid())
11789 return nullptr;
11790 Vars.push_back(Elt: EVar.get());
11791 }
11792 return getDerived().RebuildOMPAllocateClause(
11793 Allocator, Alignment, C->getFirstAllocateModifier(),
11794 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11795 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11796 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11797}
11798
11799template <typename Derived>
11800OMPClause *
11801TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11802 llvm::SmallVector<Expr *, 3> Vars;
11803 Vars.reserve(N: C->varlist_size());
11804 for (auto *VE : C->varlist()) {
11805 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11806 if (EVar.isInvalid())
11807 return nullptr;
11808 Vars.push_back(Elt: EVar.get());
11809 }
11810 Expr *ModifierExpr = C->getModifierExpr();
11811 if (ModifierExpr) {
11812 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
11813 if (EVar.isInvalid())
11814 return nullptr;
11815 ModifierExpr = EVar.get();
11816 }
11817 return getDerived().RebuildOMPNumTeamsClause(
11818 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
11819 OMPC_NUMTEAMS_unknown, nullptr, SourceLocation(), C->getBeginLoc(),
11820 C->getLParenLoc(), C->getEndLoc());
11821}
11822
11823template <typename Derived>
11824OMPClause *
11825TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11826 llvm::SmallVector<Expr *, 3> Vars;
11827 Vars.reserve(N: C->varlist_size());
11828 for (auto *VE : C->varlist()) {
11829 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11830 if (EVar.isInvalid())
11831 return nullptr;
11832 Vars.push_back(Elt: EVar.get());
11833 }
11834 Expr *ModifierExpr = C->getModifierExpr();
11835 if (ModifierExpr) {
11836 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: ModifierExpr));
11837 if (EVar.isInvalid())
11838 return nullptr;
11839 ModifierExpr = EVar.get();
11840 }
11841 return getDerived().RebuildOMPThreadLimitClause(
11842 Vars, C->getModifier(), ModifierExpr, C->getModifierLoc(),
11843 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11844}
11845
11846template <typename Derived>
11847OMPClause *
11848TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11849 ExprResult E = getDerived().TransformExpr(C->getPriority());
11850 if (E.isInvalid())
11851 return nullptr;
11852 return getDerived().RebuildOMPPriorityClause(
11853 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11854}
11855
11856template <typename Derived>
11857OMPClause *
11858TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11859 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11860 if (E.isInvalid())
11861 return nullptr;
11862 return getDerived().RebuildOMPGrainsizeClause(
11863 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11864 C->getModifierLoc(), C->getEndLoc());
11865}
11866
11867template <typename Derived>
11868OMPClause *
11869TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11870 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11871 if (E.isInvalid())
11872 return nullptr;
11873 return getDerived().RebuildOMPNumTasksClause(
11874 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11875 C->getModifierLoc(), C->getEndLoc());
11876}
11877
11878template <typename Derived>
11879OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11880 ExprResult E = getDerived().TransformExpr(C->getHint());
11881 if (E.isInvalid())
11882 return nullptr;
11883 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11884 C->getLParenLoc(), C->getEndLoc());
11885}
11886
11887template <typename Derived>
11888OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11889 OMPDistScheduleClause *C) {
11890 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11891 if (E.isInvalid())
11892 return nullptr;
11893 return getDerived().RebuildOMPDistScheduleClause(
11894 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11895 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11896}
11897
11898template <typename Derived>
11899OMPClause *
11900TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11901 // Rebuild Defaultmap Clause since we need to invoke the checking of
11902 // defaultmap(none:variable-category) after template initialization.
11903 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11904 C->getDefaultmapKind(),
11905 C->getBeginLoc(),
11906 C->getLParenLoc(),
11907 C->getDefaultmapModifierLoc(),
11908 C->getDefaultmapKindLoc(),
11909 C->getEndLoc());
11910}
11911
11912template <typename Derived>
11913OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11914 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11915 llvm::SmallVector<Expr *, 16> Vars;
11916 Expr *IteratorModifier = C->getIteratorModifier();
11917 if (IteratorModifier) {
11918 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11919 if (MapModRes.isInvalid())
11920 return nullptr;
11921 IteratorModifier = MapModRes.get();
11922 }
11923 CXXScopeSpec MapperIdScopeSpec;
11924 DeclarationNameInfo MapperIdInfo;
11925 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11926 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11927 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11928 return nullptr;
11929 return getDerived().RebuildOMPToClause(
11930 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11931 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11932 UnresolvedMappers);
11933}
11934
11935template <typename Derived>
11936OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11937 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11938 llvm::SmallVector<Expr *, 16> Vars;
11939 Expr *IteratorModifier = C->getIteratorModifier();
11940 if (IteratorModifier) {
11941 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11942 if (MapModRes.isInvalid())
11943 return nullptr;
11944 IteratorModifier = MapModRes.get();
11945 }
11946 CXXScopeSpec MapperIdScopeSpec;
11947 DeclarationNameInfo MapperIdInfo;
11948 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11949 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11950 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11951 return nullptr;
11952 return getDerived().RebuildOMPFromClause(
11953 C->getMotionModifiers(), C->getMotionModifiersLoc(), IteratorModifier,
11954 MapperIdScopeSpec, MapperIdInfo, C->getColonLoc(), Vars, Locs,
11955 UnresolvedMappers);
11956}
11957
11958template <typename Derived>
11959OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11960 OMPUseDevicePtrClause *C) {
11961 llvm::SmallVector<Expr *, 16> Vars;
11962 Vars.reserve(N: C->varlist_size());
11963 for (auto *VE : C->varlist()) {
11964 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11965 if (EVar.isInvalid())
11966 return nullptr;
11967 Vars.push_back(Elt: EVar.get());
11968 }
11969 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11970 return getDerived().RebuildOMPUseDevicePtrClause(
11971 Vars, Locs, C->getFallbackModifier(), C->getFallbackModifierLoc());
11972}
11973
11974template <typename Derived>
11975OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11976 OMPUseDeviceAddrClause *C) {
11977 llvm::SmallVector<Expr *, 16> Vars;
11978 Vars.reserve(N: C->varlist_size());
11979 for (auto *VE : C->varlist()) {
11980 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11981 if (EVar.isInvalid())
11982 return nullptr;
11983 Vars.push_back(Elt: EVar.get());
11984 }
11985 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11986 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11987}
11988
11989template <typename Derived>
11990OMPClause *
11991TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11992 llvm::SmallVector<Expr *, 16> Vars;
11993 Vars.reserve(N: C->varlist_size());
11994 for (auto *VE : C->varlist()) {
11995 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11996 if (EVar.isInvalid())
11997 return nullptr;
11998 Vars.push_back(Elt: EVar.get());
11999 }
12000 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12001 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
12002}
12003
12004template <typename Derived>
12005OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
12006 OMPHasDeviceAddrClause *C) {
12007 llvm::SmallVector<Expr *, 16> Vars;
12008 Vars.reserve(N: C->varlist_size());
12009 for (auto *VE : C->varlist()) {
12010 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12011 if (EVar.isInvalid())
12012 return nullptr;
12013 Vars.push_back(Elt: EVar.get());
12014 }
12015 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12016 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
12017}
12018
12019template <typename Derived>
12020OMPClause *
12021TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
12022 llvm::SmallVector<Expr *, 16> Vars;
12023 Vars.reserve(N: C->varlist_size());
12024 for (auto *VE : C->varlist()) {
12025 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12026 if (EVar.isInvalid())
12027 return nullptr;
12028 Vars.push_back(Elt: EVar.get());
12029 }
12030 return getDerived().RebuildOMPNontemporalClause(
12031 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12032}
12033
12034template <typename Derived>
12035OMPClause *
12036TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
12037 llvm::SmallVector<Expr *, 16> Vars;
12038 Vars.reserve(N: C->varlist_size());
12039 for (auto *VE : C->varlist()) {
12040 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12041 if (EVar.isInvalid())
12042 return nullptr;
12043 Vars.push_back(Elt: EVar.get());
12044 }
12045 return getDerived().RebuildOMPInclusiveClause(
12046 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12047}
12048
12049template <typename Derived>
12050OMPClause *
12051TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
12052 llvm::SmallVector<Expr *, 16> Vars;
12053 Vars.reserve(N: C->varlist_size());
12054 for (auto *VE : C->varlist()) {
12055 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12056 if (EVar.isInvalid())
12057 return nullptr;
12058 Vars.push_back(Elt: EVar.get());
12059 }
12060 return getDerived().RebuildOMPExclusiveClause(
12061 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12062}
12063
12064template <typename Derived>
12065OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
12066 OMPUsesAllocatorsClause *C) {
12067 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
12068 Data.reserve(N: C->getNumberOfAllocators());
12069 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
12070 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
12071 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
12072 if (Allocator.isInvalid())
12073 continue;
12074 ExprResult AllocatorTraits;
12075 if (Expr *AT = D.AllocatorTraits) {
12076 AllocatorTraits = getDerived().TransformExpr(AT);
12077 if (AllocatorTraits.isInvalid())
12078 continue;
12079 }
12080 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
12081 NewD.Allocator = Allocator.get();
12082 NewD.AllocatorTraits = AllocatorTraits.get();
12083 NewD.LParenLoc = D.LParenLoc;
12084 NewD.RParenLoc = D.RParenLoc;
12085 }
12086 return getDerived().RebuildOMPUsesAllocatorsClause(
12087 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12088}
12089
12090template <typename Derived>
12091OMPClause *
12092TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
12093 SmallVector<Expr *, 4> Locators;
12094 Locators.reserve(N: C->varlist_size());
12095 ExprResult ModifierRes;
12096 if (Expr *Modifier = C->getModifier()) {
12097 ModifierRes = getDerived().TransformExpr(Modifier);
12098 if (ModifierRes.isInvalid())
12099 return nullptr;
12100 }
12101 for (Expr *E : C->varlist()) {
12102 ExprResult Locator = getDerived().TransformExpr(E);
12103 if (Locator.isInvalid())
12104 continue;
12105 Locators.push_back(Elt: Locator.get());
12106 }
12107 return getDerived().RebuildOMPAffinityClause(
12108 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
12109 ModifierRes.get(), Locators);
12110}
12111
12112template <typename Derived>
12113OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
12114 return getDerived().RebuildOMPOrderClause(
12115 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
12116 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
12117}
12118
12119template <typename Derived>
12120OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
12121 return getDerived().RebuildOMPBindClause(
12122 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
12123 C->getLParenLoc(), C->getEndLoc());
12124}
12125
12126template <typename Derived>
12127OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
12128 OMPXDynCGroupMemClause *C) {
12129 ExprResult Size = getDerived().TransformExpr(C->getSize());
12130 if (Size.isInvalid())
12131 return nullptr;
12132 return getDerived().RebuildOMPXDynCGroupMemClause(
12133 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12134}
12135
12136template <typename Derived>
12137OMPClause *TreeTransform<Derived>::TransformOMPDynGroupprivateClause(
12138 OMPDynGroupprivateClause *C) {
12139 ExprResult Size = getDerived().TransformExpr(C->getSize());
12140 if (Size.isInvalid())
12141 return nullptr;
12142 return getDerived().RebuildOMPDynGroupprivateClause(
12143 C->getDynGroupprivateModifier(), C->getDynGroupprivateFallbackModifier(),
12144 Size.get(), C->getBeginLoc(), C->getLParenLoc(),
12145 C->getDynGroupprivateModifierLoc(),
12146 C->getDynGroupprivateFallbackModifierLoc(), C->getEndLoc());
12147}
12148
12149template <typename Derived>
12150OMPClause *
12151TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
12152 llvm::SmallVector<Expr *, 16> Vars;
12153 Vars.reserve(N: C->varlist_size());
12154 for (auto *VE : C->varlist()) {
12155 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
12156 if (EVar.isInvalid())
12157 return nullptr;
12158 Vars.push_back(Elt: EVar.get());
12159 }
12160 return getDerived().RebuildOMPDoacrossClause(
12161 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
12162 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12163}
12164
12165template <typename Derived>
12166OMPClause *
12167TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
12168 SmallVector<const Attr *> NewAttrs;
12169 for (auto *A : C->getAttrs())
12170 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
12171 return getDerived().RebuildOMPXAttributeClause(
12172 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
12173}
12174
12175template <typename Derived>
12176OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
12177 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
12178}
12179
12180//===----------------------------------------------------------------------===//
12181// OpenACC transformation
12182//===----------------------------------------------------------------------===//
12183namespace {
12184template <typename Derived>
12185class OpenACCClauseTransform final
12186 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
12187 TreeTransform<Derived> &Self;
12188 ArrayRef<const OpenACCClause *> ExistingClauses;
12189 SemaOpenACC::OpenACCParsedClause &ParsedClause;
12190 OpenACCClause *NewClause = nullptr;
12191
12192 ExprResult VisitVar(Expr *VarRef) {
12193 ExprResult Res = Self.TransformExpr(VarRef);
12194
12195 if (!Res.isUsable())
12196 return Res;
12197
12198 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12199 ParsedClause.getClauseKind(),
12200 Res.get());
12201
12202 return Res;
12203 }
12204
12205 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
12206 llvm::SmallVector<Expr *> InstantiatedVarList;
12207 for (Expr *CurVar : VarList) {
12208 ExprResult VarRef = VisitVar(VarRef: CurVar);
12209
12210 if (VarRef.isUsable())
12211 InstantiatedVarList.push_back(Elt: VarRef.get());
12212 }
12213
12214 return InstantiatedVarList;
12215 }
12216
12217public:
12218 OpenACCClauseTransform(TreeTransform<Derived> &Self,
12219 ArrayRef<const OpenACCClause *> ExistingClauses,
12220 SemaOpenACC::OpenACCParsedClause &PC)
12221 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
12222
12223 OpenACCClause *CreatedClause() const { return NewClause; }
12224
12225#define VISIT_CLAUSE(CLAUSE_NAME) \
12226 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
12227#include "clang/Basic/OpenACCClauses.def"
12228};
12229
12230template <typename Derived>
12231void OpenACCClauseTransform<Derived>::VisitDefaultClause(
12232 const OpenACCDefaultClause &C) {
12233 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
12234
12235 NewClause = OpenACCDefaultClause::Create(
12236 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
12237 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12238 EndLoc: ParsedClause.getEndLoc());
12239}
12240
12241template <typename Derived>
12242void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
12243 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12244 assert(Cond && "If constructed with invalid Condition");
12245 Sema::ConditionResult Res = Self.TransformCondition(
12246 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
12247
12248 if (Res.isInvalid() || !Res.get().second)
12249 return;
12250
12251 ParsedClause.setConditionDetails(Res.get().second);
12252
12253 NewClause = OpenACCIfClause::Create(
12254 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12255 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
12256 EndLoc: ParsedClause.getEndLoc());
12257}
12258
12259template <typename Derived>
12260void OpenACCClauseTransform<Derived>::VisitSelfClause(
12261 const OpenACCSelfClause &C) {
12262
12263 // If this is an 'update' 'self' clause, this is actually a var list instead.
12264 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
12265 llvm::SmallVector<Expr *> InstantiatedVarList;
12266 for (Expr *CurVar : C.getVarList()) {
12267 ExprResult Res = Self.TransformExpr(CurVar);
12268
12269 if (!Res.isUsable())
12270 continue;
12271
12272 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
12273 ParsedClause.getClauseKind(),
12274 Res.get());
12275
12276 if (Res.isUsable())
12277 InstantiatedVarList.push_back(Elt: Res.get());
12278 }
12279
12280 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12281 ModKind: OpenACCModifierKind::Invalid);
12282
12283 NewClause = OpenACCSelfClause::Create(
12284 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12285 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
12286 ParsedClause.getEndLoc());
12287 } else {
12288
12289 if (C.hasConditionExpr()) {
12290 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
12291 Sema::ConditionResult Res =
12292 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
12293 Sema::ConditionKind::Boolean);
12294
12295 if (Res.isInvalid() || !Res.get().second)
12296 return;
12297
12298 ParsedClause.setConditionDetails(Res.get().second);
12299 }
12300
12301 NewClause = OpenACCSelfClause::Create(
12302 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
12303 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
12304 ParsedClause.getEndLoc());
12305 }
12306}
12307
12308template <typename Derived>
12309void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
12310 const OpenACCNumGangsClause &C) {
12311 llvm::SmallVector<Expr *> InstantiatedIntExprs;
12312
12313 for (Expr *CurIntExpr : C.getIntExprs()) {
12314 ExprResult Res = Self.TransformExpr(CurIntExpr);
12315
12316 if (!Res.isUsable())
12317 return;
12318
12319 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12320 C.getClauseKind(),
12321 C.getBeginLoc(), Res.get());
12322 if (!Res.isUsable())
12323 return;
12324
12325 InstantiatedIntExprs.push_back(Elt: Res.get());
12326 }
12327
12328 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
12329 NewClause = OpenACCNumGangsClause::Create(
12330 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12331 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
12332 EndLoc: ParsedClause.getEndLoc());
12333}
12334
12335template <typename Derived>
12336void OpenACCClauseTransform<Derived>::VisitPrivateClause(
12337 const OpenACCPrivateClause &C) {
12338 llvm::SmallVector<Expr *> InstantiatedVarList;
12339 llvm::SmallVector<OpenACCPrivateRecipe> InitRecipes;
12340
12341 for (const auto [RefExpr, InitRecipe] :
12342 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12343 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12344
12345 if (VarRef.isUsable()) {
12346 InstantiatedVarList.push_back(Elt: VarRef.get());
12347
12348 // We only have to create a new one if it is dependent, and Sema won't
12349 // make one of these unless the type is non-dependent.
12350 if (InitRecipe.isSet())
12351 InitRecipes.push_back(Elt: InitRecipe);
12352 else
12353 InitRecipes.push_back(
12354 Elt: Self.getSema().OpenACC().CreatePrivateInitRecipe(VarRef.get()));
12355 }
12356 }
12357 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12358 ModKind: OpenACCModifierKind::Invalid);
12359
12360 NewClause = OpenACCPrivateClause::Create(
12361 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12362 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12363 EndLoc: ParsedClause.getEndLoc());
12364}
12365
12366template <typename Derived>
12367void OpenACCClauseTransform<Derived>::VisitHostClause(
12368 const OpenACCHostClause &C) {
12369 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12370 OpenACCModifierKind::Invalid);
12371
12372 NewClause = OpenACCHostClause::Create(
12373 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12374 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12375 EndLoc: ParsedClause.getEndLoc());
12376}
12377
12378template <typename Derived>
12379void OpenACCClauseTransform<Derived>::VisitDeviceClause(
12380 const OpenACCDeviceClause &C) {
12381 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12382 OpenACCModifierKind::Invalid);
12383
12384 NewClause = OpenACCDeviceClause::Create(
12385 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12386 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12387 EndLoc: ParsedClause.getEndLoc());
12388}
12389
12390template <typename Derived>
12391void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
12392 const OpenACCFirstPrivateClause &C) {
12393 llvm::SmallVector<Expr *> InstantiatedVarList;
12394 llvm::SmallVector<OpenACCFirstPrivateRecipe> InitRecipes;
12395
12396 for (const auto [RefExpr, InitRecipe] :
12397 llvm::zip(t: C.getVarList(), u: C.getInitRecipes())) {
12398 ExprResult VarRef = VisitVar(VarRef: RefExpr);
12399
12400 if (VarRef.isUsable()) {
12401 InstantiatedVarList.push_back(Elt: VarRef.get());
12402
12403 // We only have to create a new one if it is dependent, and Sema won't
12404 // make one of these unless the type is non-dependent.
12405 if (InitRecipe.isSet())
12406 InitRecipes.push_back(Elt: InitRecipe);
12407 else
12408 InitRecipes.push_back(
12409 Elt: Self.getSema().OpenACC().CreateFirstPrivateInitRecipe(
12410 VarRef.get()));
12411 }
12412 }
12413 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
12414 ModKind: OpenACCModifierKind::Invalid);
12415
12416 NewClause = OpenACCFirstPrivateClause::Create(
12417 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12418 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(), InitRecipes,
12419 EndLoc: ParsedClause.getEndLoc());
12420}
12421
12422template <typename Derived>
12423void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
12424 const OpenACCNoCreateClause &C) {
12425 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12426 OpenACCModifierKind::Invalid);
12427
12428 NewClause = OpenACCNoCreateClause::Create(
12429 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12430 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12431 EndLoc: ParsedClause.getEndLoc());
12432}
12433
12434template <typename Derived>
12435void OpenACCClauseTransform<Derived>::VisitPresentClause(
12436 const OpenACCPresentClause &C) {
12437 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12438 OpenACCModifierKind::Invalid);
12439
12440 NewClause = OpenACCPresentClause::Create(
12441 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12442 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12443 EndLoc: ParsedClause.getEndLoc());
12444}
12445
12446template <typename Derived>
12447void OpenACCClauseTransform<Derived>::VisitCopyClause(
12448 const OpenACCCopyClause &C) {
12449 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12450 C.getModifierList());
12451
12452 NewClause = OpenACCCopyClause::Create(
12453 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12454 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12455 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12456 EndLoc: ParsedClause.getEndLoc());
12457}
12458
12459template <typename Derived>
12460void OpenACCClauseTransform<Derived>::VisitLinkClause(
12461 const OpenACCLinkClause &C) {
12462 llvm_unreachable("link clause not valid unless a decl transform");
12463}
12464
12465template <typename Derived>
12466void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
12467 const OpenACCDeviceResidentClause &C) {
12468 llvm_unreachable("device_resident clause not valid unless a decl transform");
12469}
12470template <typename Derived>
12471void OpenACCClauseTransform<Derived>::VisitNoHostClause(
12472 const OpenACCNoHostClause &C) {
12473 llvm_unreachable("nohost clause not valid unless a decl transform");
12474}
12475template <typename Derived>
12476void OpenACCClauseTransform<Derived>::VisitBindClause(
12477 const OpenACCBindClause &C) {
12478 llvm_unreachable("bind clause not valid unless a decl transform");
12479}
12480
12481template <typename Derived>
12482void OpenACCClauseTransform<Derived>::VisitCopyInClause(
12483 const OpenACCCopyInClause &C) {
12484 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12485 C.getModifierList());
12486
12487 NewClause = OpenACCCopyInClause::Create(
12488 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12489 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12490 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12491 EndLoc: ParsedClause.getEndLoc());
12492}
12493
12494template <typename Derived>
12495void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
12496 const OpenACCCopyOutClause &C) {
12497 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12498 C.getModifierList());
12499
12500 NewClause = OpenACCCopyOutClause::Create(
12501 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12502 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12503 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12504 EndLoc: ParsedClause.getEndLoc());
12505}
12506
12507template <typename Derived>
12508void OpenACCClauseTransform<Derived>::VisitCreateClause(
12509 const OpenACCCreateClause &C) {
12510 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12511 C.getModifierList());
12512
12513 NewClause = OpenACCCreateClause::Create(
12514 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12515 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12516 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12517 EndLoc: ParsedClause.getEndLoc());
12518}
12519template <typename Derived>
12520void OpenACCClauseTransform<Derived>::VisitAttachClause(
12521 const OpenACCAttachClause &C) {
12522 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12523
12524 // Ensure each var is a pointer type.
12525 llvm::erase_if(VarList, [&](Expr *E) {
12526 return Self.getSema().OpenACC().CheckVarIsPointerType(
12527 OpenACCClauseKind::Attach, E);
12528 });
12529
12530 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12531 NewClause = OpenACCAttachClause::Create(
12532 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12533 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12534 EndLoc: ParsedClause.getEndLoc());
12535}
12536
12537template <typename Derived>
12538void OpenACCClauseTransform<Derived>::VisitDetachClause(
12539 const OpenACCDetachClause &C) {
12540 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12541
12542 // Ensure each var is a pointer type.
12543 llvm::erase_if(VarList, [&](Expr *E) {
12544 return Self.getSema().OpenACC().CheckVarIsPointerType(
12545 OpenACCClauseKind::Detach, E);
12546 });
12547
12548 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12549 NewClause = OpenACCDetachClause::Create(
12550 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12551 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12552 EndLoc: ParsedClause.getEndLoc());
12553}
12554
12555template <typename Derived>
12556void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12557 const OpenACCDeleteClause &C) {
12558 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12559 OpenACCModifierKind::Invalid);
12560 NewClause = OpenACCDeleteClause::Create(
12561 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12562 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12563 EndLoc: ParsedClause.getEndLoc());
12564}
12565
12566template <typename Derived>
12567void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12568 const OpenACCUseDeviceClause &C) {
12569 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12570 OpenACCModifierKind::Invalid);
12571 NewClause = OpenACCUseDeviceClause::Create(
12572 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12573 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12574 EndLoc: ParsedClause.getEndLoc());
12575}
12576
12577template <typename Derived>
12578void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12579 const OpenACCDevicePtrClause &C) {
12580 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12581
12582 // Ensure each var is a pointer type.
12583 llvm::erase_if(VarList, [&](Expr *E) {
12584 return Self.getSema().OpenACC().CheckVarIsPointerType(
12585 OpenACCClauseKind::DevicePtr, E);
12586 });
12587
12588 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12589 NewClause = OpenACCDevicePtrClause::Create(
12590 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12591 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12592 EndLoc: ParsedClause.getEndLoc());
12593}
12594
12595template <typename Derived>
12596void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12597 const OpenACCNumWorkersClause &C) {
12598 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12599 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12600
12601 ExprResult Res = Self.TransformExpr(IntExpr);
12602 if (!Res.isUsable())
12603 return;
12604
12605 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12606 C.getClauseKind(),
12607 C.getBeginLoc(), Res.get());
12608 if (!Res.isUsable())
12609 return;
12610
12611 ParsedClause.setIntExprDetails(Res.get());
12612 NewClause = OpenACCNumWorkersClause::Create(
12613 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12614 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12615 EndLoc: ParsedClause.getEndLoc());
12616}
12617
12618template <typename Derived>
12619void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12620 const OpenACCDeviceNumClause &C) {
12621 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12622 assert(IntExpr && "device_num clause constructed with invalid int expr");
12623
12624 ExprResult Res = Self.TransformExpr(IntExpr);
12625 if (!Res.isUsable())
12626 return;
12627
12628 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12629 C.getClauseKind(),
12630 C.getBeginLoc(), Res.get());
12631 if (!Res.isUsable())
12632 return;
12633
12634 ParsedClause.setIntExprDetails(Res.get());
12635 NewClause = OpenACCDeviceNumClause::Create(
12636 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12637 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12638 EndLoc: ParsedClause.getEndLoc());
12639}
12640
12641template <typename Derived>
12642void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12643 const OpenACCDefaultAsyncClause &C) {
12644 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12645 assert(IntExpr && "default_async clause constructed with invalid int expr");
12646
12647 ExprResult Res = Self.TransformExpr(IntExpr);
12648 if (!Res.isUsable())
12649 return;
12650
12651 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12652 C.getClauseKind(),
12653 C.getBeginLoc(), Res.get());
12654 if (!Res.isUsable())
12655 return;
12656
12657 ParsedClause.setIntExprDetails(Res.get());
12658 NewClause = OpenACCDefaultAsyncClause::Create(
12659 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12660 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12661 EndLoc: ParsedClause.getEndLoc());
12662}
12663
12664template <typename Derived>
12665void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12666 const OpenACCVectorLengthClause &C) {
12667 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12668 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12669
12670 ExprResult Res = Self.TransformExpr(IntExpr);
12671 if (!Res.isUsable())
12672 return;
12673
12674 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12675 C.getClauseKind(),
12676 C.getBeginLoc(), Res.get());
12677 if (!Res.isUsable())
12678 return;
12679
12680 ParsedClause.setIntExprDetails(Res.get());
12681 NewClause = OpenACCVectorLengthClause::Create(
12682 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12683 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12684 EndLoc: ParsedClause.getEndLoc());
12685}
12686
12687template <typename Derived>
12688void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12689 const OpenACCAsyncClause &C) {
12690 if (C.hasIntExpr()) {
12691 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12692 if (!Res.isUsable())
12693 return;
12694
12695 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12696 C.getClauseKind(),
12697 C.getBeginLoc(), Res.get());
12698 if (!Res.isUsable())
12699 return;
12700 ParsedClause.setIntExprDetails(Res.get());
12701 }
12702
12703 NewClause = OpenACCAsyncClause::Create(
12704 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12705 LParenLoc: ParsedClause.getLParenLoc(),
12706 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12707 : nullptr,
12708 EndLoc: ParsedClause.getEndLoc());
12709}
12710
12711template <typename Derived>
12712void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12713 const OpenACCWorkerClause &C) {
12714 if (C.hasIntExpr()) {
12715 // restrictions on this expression are all "does it exist in certain
12716 // situations" that are not possible to be dependent, so the only check we
12717 // have is that it transforms, and is an int expression.
12718 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12719 if (!Res.isUsable())
12720 return;
12721
12722 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12723 C.getClauseKind(),
12724 C.getBeginLoc(), Res.get());
12725 if (!Res.isUsable())
12726 return;
12727 ParsedClause.setIntExprDetails(Res.get());
12728 }
12729
12730 NewClause = OpenACCWorkerClause::Create(
12731 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12732 LParenLoc: ParsedClause.getLParenLoc(),
12733 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12734 : nullptr,
12735 EndLoc: ParsedClause.getEndLoc());
12736}
12737
12738template <typename Derived>
12739void OpenACCClauseTransform<Derived>::VisitVectorClause(
12740 const OpenACCVectorClause &C) {
12741 if (C.hasIntExpr()) {
12742 // restrictions on this expression are all "does it exist in certain
12743 // situations" that are not possible to be dependent, so the only check we
12744 // have is that it transforms, and is an int expression.
12745 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12746 if (!Res.isUsable())
12747 return;
12748
12749 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12750 C.getClauseKind(),
12751 C.getBeginLoc(), Res.get());
12752 if (!Res.isUsable())
12753 return;
12754 ParsedClause.setIntExprDetails(Res.get());
12755 }
12756
12757 NewClause = OpenACCVectorClause::Create(
12758 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12759 LParenLoc: ParsedClause.getLParenLoc(),
12760 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12761 : nullptr,
12762 EndLoc: ParsedClause.getEndLoc());
12763}
12764
12765template <typename Derived>
12766void OpenACCClauseTransform<Derived>::VisitWaitClause(
12767 const OpenACCWaitClause &C) {
12768 if (C.hasExprs()) {
12769 Expr *DevNumExpr = nullptr;
12770 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12771
12772 // Instantiate devnum expr if it exists.
12773 if (C.getDevNumExpr()) {
12774 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12775 if (!Res.isUsable())
12776 return;
12777 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12778 C.getClauseKind(),
12779 C.getBeginLoc(), Res.get());
12780 if (!Res.isUsable())
12781 return;
12782
12783 DevNumExpr = Res.get();
12784 }
12785
12786 // Instantiate queue ids.
12787 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12788 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12789 if (!Res.isUsable())
12790 return;
12791 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12792 C.getClauseKind(),
12793 C.getBeginLoc(), Res.get());
12794 if (!Res.isUsable())
12795 return;
12796
12797 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12798 }
12799
12800 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12801 IntExprs: std::move(InstantiatedQueueIdExprs));
12802 }
12803
12804 NewClause = OpenACCWaitClause::Create(
12805 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12806 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12807 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12808 EndLoc: ParsedClause.getEndLoc());
12809}
12810
12811template <typename Derived>
12812void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12813 const OpenACCDeviceTypeClause &C) {
12814 // Nothing to transform here, just create a new version of 'C'.
12815 NewClause = OpenACCDeviceTypeClause::Create(
12816 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12817 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12818 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12819}
12820
12821template <typename Derived>
12822void OpenACCClauseTransform<Derived>::VisitAutoClause(
12823 const OpenACCAutoClause &C) {
12824 // Nothing to do, so just create a new node.
12825 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12826 BeginLoc: ParsedClause.getBeginLoc(),
12827 EndLoc: ParsedClause.getEndLoc());
12828}
12829
12830template <typename Derived>
12831void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12832 const OpenACCIndependentClause &C) {
12833 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12834 BeginLoc: ParsedClause.getBeginLoc(),
12835 EndLoc: ParsedClause.getEndLoc());
12836}
12837
12838template <typename Derived>
12839void OpenACCClauseTransform<Derived>::VisitSeqClause(
12840 const OpenACCSeqClause &C) {
12841 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12842 BeginLoc: ParsedClause.getBeginLoc(),
12843 EndLoc: ParsedClause.getEndLoc());
12844}
12845template <typename Derived>
12846void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12847 const OpenACCFinalizeClause &C) {
12848 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12849 BeginLoc: ParsedClause.getBeginLoc(),
12850 EndLoc: ParsedClause.getEndLoc());
12851}
12852
12853template <typename Derived>
12854void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12855 const OpenACCIfPresentClause &C) {
12856 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12857 BeginLoc: ParsedClause.getBeginLoc(),
12858 EndLoc: ParsedClause.getEndLoc());
12859}
12860
12861template <typename Derived>
12862void OpenACCClauseTransform<Derived>::VisitReductionClause(
12863 const OpenACCReductionClause &C) {
12864 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12865 SmallVector<Expr *> ValidVars;
12866 llvm::SmallVector<OpenACCReductionRecipeWithStorage> Recipes;
12867
12868 for (const auto [Var, OrigRecipe] :
12869 llvm::zip(t&: TransformedVars, u: C.getRecipes())) {
12870 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12871 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12872 if (Res.isUsable()) {
12873 ValidVars.push_back(Elt: Res.get());
12874
12875 if (OrigRecipe.isSet())
12876 Recipes.emplace_back(Args: OrigRecipe.AllocaDecl, Args: OrigRecipe.CombinerRecipes);
12877 else
12878 Recipes.push_back(Self.getSema().OpenACC().CreateReductionInitRecipe(
12879 C.getReductionOp(), Res.get()));
12880 }
12881 }
12882
12883 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12884 ExistingClauses, ParsedClause.getDirectiveKind(),
12885 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12886 C.getReductionOp(), ValidVars, Recipes, ParsedClause.getEndLoc());
12887}
12888
12889template <typename Derived>
12890void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12891 const OpenACCCollapseClause &C) {
12892 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12893 assert(LoopCount && "collapse clause constructed with invalid loop count");
12894
12895 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12896
12897 if (!NewLoopCount.isUsable())
12898 return;
12899
12900 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12901 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12902 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12903
12904 // FIXME: It isn't clear whether this is properly tested here, we should
12905 // probably see if we can come up with a test for this.
12906 if (!NewLoopCount.isUsable())
12907 return;
12908
12909 NewLoopCount =
12910 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12911
12912 // FIXME: It isn't clear whether this is properly tested here, we should
12913 // probably see if we can come up with a test for this.
12914 if (!NewLoopCount.isUsable())
12915 return;
12916
12917 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12918 NewClause = OpenACCCollapseClause::Create(
12919 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12920 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12921 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12922}
12923
12924template <typename Derived>
12925void OpenACCClauseTransform<Derived>::VisitTileClause(
12926 const OpenACCTileClause &C) {
12927
12928 llvm::SmallVector<Expr *> TransformedExprs;
12929
12930 for (Expr *E : C.getSizeExprs()) {
12931 ExprResult NewSizeExpr = Self.TransformExpr(E);
12932
12933 if (!NewSizeExpr.isUsable())
12934 return;
12935
12936 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12937 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12938 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12939
12940 // FIXME: It isn't clear whether this is properly tested here, we should
12941 // probably see if we can come up with a test for this.
12942 if (!NewSizeExpr.isUsable())
12943 return;
12944
12945 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12946
12947 if (!NewSizeExpr.isUsable())
12948 return;
12949 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12950 }
12951
12952 ParsedClause.setIntExprDetails(TransformedExprs);
12953 NewClause = OpenACCTileClause::Create(
12954 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12955 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12956 EndLoc: ParsedClause.getEndLoc());
12957}
12958template <typename Derived>
12959void OpenACCClauseTransform<Derived>::VisitGangClause(
12960 const OpenACCGangClause &C) {
12961 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12962 llvm::SmallVector<Expr *> TransformedIntExprs;
12963
12964 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12965 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12966 if (!ER.isUsable())
12967 continue;
12968
12969 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12970 ParsedClause.getDirectiveKind(),
12971 C.getExpr(I).first, ER.get());
12972 if (!ER.isUsable())
12973 continue;
12974 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12975 TransformedIntExprs.push_back(Elt: ER.get());
12976 }
12977
12978 NewClause = Self.getSema().OpenACC().CheckGangClause(
12979 ParsedClause.getDirectiveKind(), ExistingClauses,
12980 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12981 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12982}
12983} // namespace
12984template <typename Derived>
12985OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12986 ArrayRef<const OpenACCClause *> ExistingClauses,
12987 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12988
12989 SemaOpenACC::OpenACCParsedClause ParsedClause(
12990 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12991 ParsedClause.setEndLoc(OldClause->getEndLoc());
12992
12993 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12994 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12995
12996 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12997 ParsedClause};
12998 Transform.Visit(OldClause);
12999
13000 return Transform.CreatedClause();
13001}
13002
13003template <typename Derived>
13004llvm::SmallVector<OpenACCClause *>
13005TreeTransform<Derived>::TransformOpenACCClauseList(
13006 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
13007 llvm::SmallVector<OpenACCClause *> TransformedClauses;
13008 for (const auto *Clause : OldClauses) {
13009 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
13010 TransformedClauses, DirKind, Clause))
13011 TransformedClauses.push_back(Elt: TransformedClause);
13012 }
13013 return TransformedClauses;
13014}
13015
13016template <typename Derived>
13017StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
13018 OpenACCComputeConstruct *C) {
13019 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13020
13021 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13022 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13023 C->clauses());
13024
13025 if (getSema().OpenACC().ActOnStartStmtDirective(
13026 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13027 return StmtError();
13028
13029 // Transform Structured Block.
13030 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13031 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13032 C->clauses(), TransformedClauses);
13033 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13034 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13035 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13036
13037 return getDerived().RebuildOpenACCComputeConstruct(
13038 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13039 C->getEndLoc(), TransformedClauses, StrBlock);
13040}
13041
13042template <typename Derived>
13043StmtResult
13044TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
13045
13046 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13047
13048 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13049 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13050 C->clauses());
13051
13052 if (getSema().OpenACC().ActOnStartStmtDirective(
13053 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13054 return StmtError();
13055
13056 // Transform Loop.
13057 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13058 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13059 C->clauses(), TransformedClauses);
13060 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13061 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13062 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13063
13064 return getDerived().RebuildOpenACCLoopConstruct(
13065 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13066 TransformedClauses, Loop);
13067}
13068
13069template <typename Derived>
13070StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
13071 OpenACCCombinedConstruct *C) {
13072 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13073
13074 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13075 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13076 C->clauses());
13077
13078 if (getSema().OpenACC().ActOnStartStmtDirective(
13079 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13080 return StmtError();
13081
13082 // Transform Loop.
13083 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13084 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13085 C->clauses(), TransformedClauses);
13086 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
13087 Loop = getSema().OpenACC().ActOnAssociatedStmt(
13088 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
13089
13090 return getDerived().RebuildOpenACCCombinedConstruct(
13091 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
13092 C->getEndLoc(), TransformedClauses, Loop);
13093}
13094
13095template <typename Derived>
13096StmtResult
13097TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
13098 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13099
13100 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13101 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13102 C->clauses());
13103 if (getSema().OpenACC().ActOnStartStmtDirective(
13104 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13105 return StmtError();
13106
13107 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13108 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13109 C->clauses(), TransformedClauses);
13110 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13111 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13112 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13113
13114 return getDerived().RebuildOpenACCDataConstruct(
13115 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13116 TransformedClauses, StrBlock);
13117}
13118
13119template <typename Derived>
13120StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
13121 OpenACCEnterDataConstruct *C) {
13122 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13123
13124 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13125 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13126 C->clauses());
13127 if (getSema().OpenACC().ActOnStartStmtDirective(
13128 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13129 return StmtError();
13130
13131 return getDerived().RebuildOpenACCEnterDataConstruct(
13132 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13133 TransformedClauses);
13134}
13135
13136template <typename Derived>
13137StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
13138 OpenACCExitDataConstruct *C) {
13139 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13140
13141 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13142 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13143 C->clauses());
13144 if (getSema().OpenACC().ActOnStartStmtDirective(
13145 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13146 return StmtError();
13147
13148 return getDerived().RebuildOpenACCExitDataConstruct(
13149 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13150 TransformedClauses);
13151}
13152
13153template <typename Derived>
13154StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
13155 OpenACCHostDataConstruct *C) {
13156 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13157
13158 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13159 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13160 C->clauses());
13161 if (getSema().OpenACC().ActOnStartStmtDirective(
13162 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13163 return StmtError();
13164
13165 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13166 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
13167 C->clauses(), TransformedClauses);
13168 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
13169 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
13170 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
13171
13172 return getDerived().RebuildOpenACCHostDataConstruct(
13173 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13174 TransformedClauses, StrBlock);
13175}
13176
13177template <typename Derived>
13178StmtResult
13179TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
13180 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13181
13182 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13183 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13184 C->clauses());
13185 if (getSema().OpenACC().ActOnStartStmtDirective(
13186 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13187 return StmtError();
13188
13189 return getDerived().RebuildOpenACCInitConstruct(
13190 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13191 TransformedClauses);
13192}
13193
13194template <typename Derived>
13195StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
13196 OpenACCShutdownConstruct *C) {
13197 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13198
13199 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13200 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13201 C->clauses());
13202 if (getSema().OpenACC().ActOnStartStmtDirective(
13203 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13204 return StmtError();
13205
13206 return getDerived().RebuildOpenACCShutdownConstruct(
13207 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13208 TransformedClauses);
13209}
13210template <typename Derived>
13211StmtResult
13212TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
13213 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13214
13215 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13216 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13217 C->clauses());
13218 if (getSema().OpenACC().ActOnStartStmtDirective(
13219 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13220 return StmtError();
13221
13222 return getDerived().RebuildOpenACCSetConstruct(
13223 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13224 TransformedClauses);
13225}
13226
13227template <typename Derived>
13228StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
13229 OpenACCUpdateConstruct *C) {
13230 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13231
13232 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13233 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13234 C->clauses());
13235 if (getSema().OpenACC().ActOnStartStmtDirective(
13236 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13237 return StmtError();
13238
13239 return getDerived().RebuildOpenACCUpdateConstruct(
13240 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
13241 TransformedClauses);
13242}
13243
13244template <typename Derived>
13245StmtResult
13246TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
13247 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13248
13249 ExprResult DevNumExpr;
13250 if (C->hasDevNumExpr()) {
13251 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
13252
13253 if (DevNumExpr.isUsable())
13254 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
13255 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
13256 C->getBeginLoc(), DevNumExpr.get());
13257 }
13258
13259 llvm::SmallVector<Expr *> QueueIdExprs;
13260
13261 for (Expr *QE : C->getQueueIdExprs()) {
13262 assert(QE && "Null queue id expr?");
13263 ExprResult NewEQ = getDerived().TransformExpr(QE);
13264
13265 if (!NewEQ.isUsable())
13266 break;
13267 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
13268 OpenACCClauseKind::Invalid,
13269 C->getBeginLoc(), NewEQ.get());
13270 if (NewEQ.isUsable())
13271 QueueIdExprs.push_back(Elt: NewEQ.get());
13272 }
13273
13274 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13275 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13276 C->clauses());
13277
13278 if (getSema().OpenACC().ActOnStartStmtDirective(
13279 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
13280 return StmtError();
13281
13282 return getDerived().RebuildOpenACCWaitConstruct(
13283 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13284 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
13285 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
13286}
13287template <typename Derived>
13288StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
13289 OpenACCCacheConstruct *C) {
13290 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13291
13292 llvm::SmallVector<Expr *> TransformedVarList;
13293 for (Expr *Var : C->getVarList()) {
13294 assert(Var && "Null var listexpr?");
13295
13296 ExprResult NewVar = getDerived().TransformExpr(Var);
13297
13298 if (!NewVar.isUsable())
13299 break;
13300
13301 NewVar = getSema().OpenACC().ActOnVar(
13302 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
13303 if (!NewVar.isUsable())
13304 break;
13305
13306 TransformedVarList.push_back(Elt: NewVar.get());
13307 }
13308
13309 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13310 C->getBeginLoc(), {}))
13311 return StmtError();
13312
13313 return getDerived().RebuildOpenACCCacheConstruct(
13314 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
13315 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
13316 C->getEndLoc());
13317}
13318
13319template <typename Derived>
13320StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
13321 OpenACCAtomicConstruct *C) {
13322 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
13323
13324 llvm::SmallVector<OpenACCClause *> TransformedClauses =
13325 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
13326 C->clauses());
13327
13328 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
13329 C->getBeginLoc(), {}))
13330 return StmtError();
13331
13332 // Transform Associated Stmt.
13333 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
13334 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
13335
13336 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
13337 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
13338 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
13339 AssocStmt);
13340
13341 return getDerived().RebuildOpenACCAtomicConstruct(
13342 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
13343 C->getEndLoc(), TransformedClauses, AssocStmt);
13344}
13345
13346template <typename Derived>
13347ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
13348 OpenACCAsteriskSizeExpr *E) {
13349 if (getDerived().AlwaysRebuild())
13350 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
13351 // Nothing can ever change, so there is never anything to transform.
13352 return E;
13353}
13354
13355//===----------------------------------------------------------------------===//
13356// Expression transformation
13357//===----------------------------------------------------------------------===//
13358template<typename Derived>
13359ExprResult
13360TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
13361 return TransformExpr(E: E->getSubExpr());
13362}
13363
13364template <typename Derived>
13365ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
13366 SYCLUniqueStableNameExpr *E) {
13367 if (!E->isTypeDependent())
13368 return E;
13369
13370 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
13371
13372 if (!NewT)
13373 return ExprError();
13374
13375 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
13376 return E;
13377
13378 return getDerived().RebuildSYCLUniqueStableNameExpr(
13379 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
13380}
13381
13382template <typename Derived>
13383StmtResult TreeTransform<Derived>::TransformUnresolvedSYCLKernelCallStmt(
13384 UnresolvedSYCLKernelCallStmt *S) {
13385 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
13386 const auto *SKEPAttr = FD->template getAttr<SYCLKernelEntryPointAttr>();
13387 if (!SKEPAttr || SKEPAttr->isInvalidAttr())
13388 return StmtError();
13389
13390 ExprResult IdExpr = getDerived().TransformExpr(S->getKernelLaunchIdExpr());
13391 if (IdExpr.isInvalid())
13392 return StmtError();
13393
13394 StmtResult Body = getDerived().TransformStmt(S->getOriginalStmt());
13395 if (Body.isInvalid())
13396 return StmtError();
13397
13398 StmtResult SR = SemaRef.SYCL().BuildSYCLKernelCallStmt(
13399 FD: cast<FunctionDecl>(Val: SemaRef.CurContext), Body: cast<CompoundStmt>(Val: Body.get()),
13400 LaunchIdExpr: IdExpr.get());
13401 if (SR.isInvalid())
13402 return StmtError();
13403
13404 return SR;
13405}
13406
13407template <typename Derived>
13408ExprResult TreeTransform<Derived>::TransformCXXReflectExpr(CXXReflectExpr *E) {
13409 // TODO(reflection): Implement its transform
13410 assert(false && "not implemented yet");
13411 return ExprError();
13412}
13413
13414template<typename Derived>
13415ExprResult
13416TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
13417 if (!E->isTypeDependent())
13418 return E;
13419
13420 return getDerived().RebuildPredefinedExpr(E->getLocation(),
13421 E->getIdentKind());
13422}
13423
13424template<typename Derived>
13425ExprResult
13426TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
13427 NestedNameSpecifierLoc QualifierLoc;
13428 if (E->getQualifierLoc()) {
13429 QualifierLoc
13430 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13431 if (!QualifierLoc)
13432 return ExprError();
13433 }
13434
13435 ValueDecl *ND
13436 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
13437 E->getDecl()));
13438 if (!ND || ND->isInvalidDecl())
13439 return ExprError();
13440
13441 NamedDecl *Found = ND;
13442 if (E->getFoundDecl() != E->getDecl()) {
13443 Found = cast_or_null<NamedDecl>(
13444 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
13445 if (!Found)
13446 return ExprError();
13447 }
13448
13449 DeclarationNameInfo NameInfo = E->getNameInfo();
13450 if (NameInfo.getName()) {
13451 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
13452 if (!NameInfo.getName())
13453 return ExprError();
13454 }
13455
13456 if (!getDerived().AlwaysRebuild() &&
13457 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
13458 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
13459 Found == E->getFoundDecl() &&
13460 NameInfo.getName() == E->getDecl()->getDeclName() &&
13461 !E->hasExplicitTemplateArgs()) {
13462
13463 // Mark it referenced in the new context regardless.
13464 // FIXME: this is a bit instantiation-specific.
13465 SemaRef.MarkDeclRefReferenced(E);
13466
13467 return E;
13468 }
13469
13470 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
13471 if (E->hasExplicitTemplateArgs()) {
13472 TemplateArgs = &TransArgs;
13473 TransArgs.setLAngleLoc(E->getLAngleLoc());
13474 TransArgs.setRAngleLoc(E->getRAngleLoc());
13475 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13476 E->getNumTemplateArgs(),
13477 TransArgs))
13478 return ExprError();
13479 }
13480
13481 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
13482 Found, TemplateArgs);
13483}
13484
13485template<typename Derived>
13486ExprResult
13487TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
13488 return E;
13489}
13490
13491template <typename Derived>
13492ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
13493 FixedPointLiteral *E) {
13494 return E;
13495}
13496
13497template<typename Derived>
13498ExprResult
13499TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
13500 return E;
13501}
13502
13503template<typename Derived>
13504ExprResult
13505TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
13506 return E;
13507}
13508
13509template<typename Derived>
13510ExprResult
13511TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
13512 return E;
13513}
13514
13515template<typename Derived>
13516ExprResult
13517TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
13518 return E;
13519}
13520
13521template<typename Derived>
13522ExprResult
13523TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
13524 return getDerived().TransformCallExpr(E);
13525}
13526
13527template<typename Derived>
13528ExprResult
13529TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
13530 ExprResult ControllingExpr;
13531 TypeSourceInfo *ControllingType = nullptr;
13532 if (E->isExprPredicate())
13533 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
13534 else
13535 ControllingType = getDerived().TransformType(E->getControllingType());
13536
13537 if (ControllingExpr.isInvalid() && !ControllingType)
13538 return ExprError();
13539
13540 SmallVector<Expr *, 4> AssocExprs;
13541 SmallVector<TypeSourceInfo *, 4> AssocTypes;
13542 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
13543 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
13544 if (TSI) {
13545 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
13546 if (!AssocType)
13547 return ExprError();
13548 AssocTypes.push_back(Elt: AssocType);
13549 } else {
13550 AssocTypes.push_back(Elt: nullptr);
13551 }
13552
13553 ExprResult AssocExpr =
13554 getDerived().TransformExpr(Assoc.getAssociationExpr());
13555 if (AssocExpr.isInvalid())
13556 return ExprError();
13557 AssocExprs.push_back(Elt: AssocExpr.get());
13558 }
13559
13560 if (!ControllingType)
13561 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13562 E->getDefaultLoc(),
13563 E->getRParenLoc(),
13564 ControllingExpr.get(),
13565 AssocTypes,
13566 AssocExprs);
13567 return getDerived().RebuildGenericSelectionExpr(
13568 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13569 ControllingType, AssocTypes, AssocExprs);
13570}
13571
13572template<typename Derived>
13573ExprResult
13574TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13575 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13576 if (SubExpr.isInvalid())
13577 return ExprError();
13578
13579 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13580 return E;
13581
13582 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13583 E->getRParen());
13584}
13585
13586/// The operand of a unary address-of operator has special rules: it's
13587/// allowed to refer to a non-static member of a class even if there's no 'this'
13588/// object available.
13589template<typename Derived>
13590ExprResult
13591TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13592 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13593 return getDerived().TransformDependentScopeDeclRefExpr(
13594 DRE, /*IsAddressOfOperand=*/true, nullptr);
13595 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13596 return getDerived().TransformUnresolvedLookupExpr(
13597 ULE, /*IsAddressOfOperand=*/true);
13598 else
13599 return getDerived().TransformExpr(E);
13600}
13601
13602template<typename Derived>
13603ExprResult
13604TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13605 ExprResult SubExpr;
13606 if (E->getOpcode() == UO_AddrOf)
13607 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13608 else
13609 SubExpr = TransformExpr(E: E->getSubExpr());
13610 if (SubExpr.isInvalid())
13611 return ExprError();
13612
13613 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13614 return E;
13615
13616 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13617 E->getOpcode(),
13618 SubExpr.get());
13619}
13620
13621template<typename Derived>
13622ExprResult
13623TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13624 // Transform the type.
13625 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13626 if (!Type)
13627 return ExprError();
13628
13629 // Transform all of the components into a Designation similar to what the
13630 // parser builds.
13631 // FIXME: It would be slightly more efficient in the non-dependent case to
13632 // just map FieldDecls, rather than requiring the rebuilder to look for
13633 // the fields again. However, __builtin_offsetof is rare enough in
13634 // template code that we don't care.
13635 bool ExprChanged = false;
13636 Designation Desig;
13637 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13638 const OffsetOfNode &ON = E->getComponent(Idx: I);
13639 switch (ON.getKind()) {
13640 case OffsetOfNode::Array: {
13641 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13642 ExprResult Index = getDerived().TransformExpr(FromIndex);
13643 if (Index.isInvalid())
13644 return ExprError();
13645
13646 ExprChanged = ExprChanged || Index.get() != FromIndex;
13647 Designator AD =
13648 Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: ON.getBeginLoc());
13649 AD.setRBracketLoc(ON.getEndLoc());
13650 Desig.AddDesignator(D: AD);
13651 break;
13652 }
13653
13654 case OffsetOfNode::Field:
13655 case OffsetOfNode::Identifier: {
13656 const IdentifierInfo *Name = ON.getFieldName();
13657 if (!Name)
13658 continue;
13659 // The leading designator has no '.'; subsequent ones do.
13660 SourceLocation DotLoc =
13661 Desig.empty() ? SourceLocation() : ON.getBeginLoc();
13662 Desig.AddDesignator(
13663 D: Designator::CreateFieldDesignator(FieldName: Name, DotLoc, FieldLoc: ON.getEndLoc()));
13664 break;
13665 }
13666
13667 case OffsetOfNode::Base:
13668 // Will be recomputed during the rebuild.
13669 continue;
13670 }
13671 }
13672
13673 // If nothing changed, retain the existing expression.
13674 if (!getDerived().AlwaysRebuild() &&
13675 Type == E->getTypeSourceInfo() &&
13676 !ExprChanged)
13677 return E;
13678
13679 // Build a new offsetof expression.
13680 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type, Desig,
13681 E->getRParenLoc());
13682}
13683
13684template<typename Derived>
13685ExprResult
13686TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13687 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13688 "opaque value expression requires transformation");
13689 return E;
13690}
13691
13692template <typename Derived>
13693ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13694 llvm::SmallVector<Expr *, 8> Children;
13695 bool Changed = false;
13696 for (Expr *C : E->subExpressions()) {
13697 ExprResult NewC = getDerived().TransformExpr(C);
13698 if (NewC.isInvalid())
13699 return ExprError();
13700 Children.push_back(Elt: NewC.get());
13701
13702 Changed |= NewC.get() != C;
13703 }
13704 if (!getDerived().AlwaysRebuild() && !Changed)
13705 return E;
13706 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13707 Children, E->getType());
13708}
13709
13710template<typename Derived>
13711ExprResult
13712TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13713 // Rebuild the syntactic form. The original syntactic form has
13714 // opaque-value expressions in it, so strip those away and rebuild
13715 // the result. This is a really awful way of doing this, but the
13716 // better solution (rebuilding the semantic expressions and
13717 // rebinding OVEs as necessary) doesn't work; we'd need
13718 // TreeTransform to not strip away implicit conversions.
13719 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13720 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13721 if (result.isInvalid()) return ExprError();
13722
13723 // If that gives us a pseudo-object result back, the pseudo-object
13724 // expression must have been an lvalue-to-rvalue conversion which we
13725 // should reapply.
13726 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13727 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13728
13729 return result;
13730}
13731
13732template<typename Derived>
13733ExprResult
13734TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13735 UnaryExprOrTypeTraitExpr *E) {
13736 if (E->isArgumentType()) {
13737 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13738
13739 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13740 if (!NewT)
13741 return ExprError();
13742
13743 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13744 return E;
13745
13746 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13747 E->getKind(),
13748 E->getSourceRange());
13749 }
13750
13751 // C++0x [expr.sizeof]p1:
13752 // The operand is either an expression, which is an unevaluated operand
13753 // [...]
13754 EnterExpressionEvaluationContext Unevaluated(
13755 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13756 Sema::ReuseLambdaContextDecl);
13757
13758 // Try to recover if we have something like sizeof(T::X) where X is a type.
13759 // Notably, there must be *exactly* one set of parens if X is a type.
13760 TypeSourceInfo *RecoveryTSI = nullptr;
13761 ExprResult SubExpr;
13762 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13763 if (auto *DRE =
13764 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13765 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13766 PE, DRE, false, &RecoveryTSI);
13767 else
13768 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13769
13770 if (RecoveryTSI) {
13771 return getDerived().RebuildUnaryExprOrTypeTrait(
13772 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13773 } else if (SubExpr.isInvalid())
13774 return ExprError();
13775
13776 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13777 return E;
13778
13779 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13780 E->getOperatorLoc(),
13781 E->getKind(),
13782 E->getSourceRange());
13783}
13784
13785template<typename Derived>
13786ExprResult
13787TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13788 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13789 if (LHS.isInvalid())
13790 return ExprError();
13791
13792 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13793 if (RHS.isInvalid())
13794 return ExprError();
13795
13796
13797 if (!getDerived().AlwaysRebuild() &&
13798 LHS.get() == E->getLHS() &&
13799 RHS.get() == E->getRHS())
13800 return E;
13801
13802 return getDerived().RebuildArraySubscriptExpr(
13803 LHS.get(),
13804 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13805}
13806
13807template <typename Derived>
13808ExprResult TreeTransform<Derived>::TransformMatrixSingleSubscriptExpr(
13809 MatrixSingleSubscriptExpr *E) {
13810 ExprResult Base = getDerived().TransformExpr(E->getBase());
13811 if (Base.isInvalid())
13812 return ExprError();
13813
13814 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13815 if (RowIdx.isInvalid())
13816 return ExprError();
13817
13818 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13819 RowIdx.get() == E->getRowIdx())
13820 return E;
13821
13822 return getDerived().RebuildMatrixSingleSubscriptExpr(Base.get(), RowIdx.get(),
13823 E->getRBracketLoc());
13824}
13825
13826template <typename Derived>
13827ExprResult
13828TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13829 ExprResult Base = getDerived().TransformExpr(E->getBase());
13830 if (Base.isInvalid())
13831 return ExprError();
13832
13833 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13834 if (RowIdx.isInvalid())
13835 return ExprError();
13836
13837 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13838 if (ColumnIdx.isInvalid())
13839 return ExprError();
13840
13841 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13842 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13843 return E;
13844
13845 return getDerived().RebuildMatrixSubscriptExpr(
13846 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13847}
13848
13849template <typename Derived>
13850ExprResult
13851TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13852 ExprResult Base = getDerived().TransformExpr(E->getBase());
13853 if (Base.isInvalid())
13854 return ExprError();
13855
13856 ExprResult LowerBound;
13857 if (E->getLowerBound()) {
13858 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13859 if (LowerBound.isInvalid())
13860 return ExprError();
13861 }
13862
13863 ExprResult Length;
13864 if (E->getLength()) {
13865 Length = getDerived().TransformExpr(E->getLength());
13866 if (Length.isInvalid())
13867 return ExprError();
13868 }
13869
13870 ExprResult Stride;
13871 if (E->isOMPArraySection()) {
13872 if (Expr *Str = E->getStride()) {
13873 Stride = getDerived().TransformExpr(Str);
13874 if (Stride.isInvalid())
13875 return ExprError();
13876 }
13877 }
13878
13879 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13880 LowerBound.get() == E->getLowerBound() &&
13881 Length.get() == E->getLength() &&
13882 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13883 return E;
13884
13885 return getDerived().RebuildArraySectionExpr(
13886 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13887 LowerBound.get(), E->getColonLocFirst(),
13888 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13889 Length.get(), Stride.get(), E->getRBracketLoc());
13890}
13891
13892template <typename Derived>
13893ExprResult
13894TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13895 ExprResult Base = getDerived().TransformExpr(E->getBase());
13896 if (Base.isInvalid())
13897 return ExprError();
13898
13899 SmallVector<Expr *, 4> Dims;
13900 bool ErrorFound = false;
13901 for (Expr *Dim : E->getDimensions()) {
13902 ExprResult DimRes = getDerived().TransformExpr(Dim);
13903 if (DimRes.isInvalid()) {
13904 ErrorFound = true;
13905 continue;
13906 }
13907 Dims.push_back(Elt: DimRes.get());
13908 }
13909
13910 if (ErrorFound)
13911 return ExprError();
13912 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13913 E->getRParenLoc(), Dims,
13914 E->getBracketsRanges());
13915}
13916
13917template <typename Derived>
13918ExprResult
13919TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13920 unsigned NumIterators = E->numOfIterators();
13921 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13922
13923 bool ErrorFound = false;
13924 bool NeedToRebuild = getDerived().AlwaysRebuild();
13925 for (unsigned I = 0; I < NumIterators; ++I) {
13926 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13927 Data[I].DeclIdent = D->getIdentifier();
13928 Data[I].DeclIdentLoc = D->getLocation();
13929 if (D->getLocation() == D->getBeginLoc()) {
13930 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13931 "Implicit type must be int.");
13932 } else {
13933 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13934 QualType DeclTy = getDerived().TransformType(D->getType());
13935 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13936 }
13937 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13938 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13939 ExprResult End = getDerived().TransformExpr(Range.End);
13940 ExprResult Step = getDerived().TransformExpr(Range.Step);
13941 ErrorFound = ErrorFound ||
13942 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13943 !Data[I].Type.get().isNull())) ||
13944 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13945 if (ErrorFound)
13946 continue;
13947 Data[I].Range.Begin = Begin.get();
13948 Data[I].Range.End = End.get();
13949 Data[I].Range.Step = Step.get();
13950 Data[I].AssignLoc = E->getAssignLoc(I);
13951 Data[I].ColonLoc = E->getColonLoc(I);
13952 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13953 NeedToRebuild =
13954 NeedToRebuild ||
13955 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13956 D->getType().getTypePtrOrNull()) ||
13957 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13958 Range.Step != Data[I].Range.Step;
13959 }
13960 if (ErrorFound)
13961 return ExprError();
13962 if (!NeedToRebuild)
13963 return E;
13964
13965 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13966 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13967 if (!Res.isUsable())
13968 return Res;
13969 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13970 for (unsigned I = 0; I < NumIterators; ++I)
13971 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13972 IE->getIteratorDecl(I));
13973 return Res;
13974}
13975
13976template<typename Derived>
13977ExprResult
13978TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13979 // Transform the callee.
13980 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13981 if (Callee.isInvalid())
13982 return ExprError();
13983
13984 // Transform arguments.
13985 bool ArgChanged = false;
13986 SmallVector<Expr*, 8> Args;
13987 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13988 &ArgChanged))
13989 return ExprError();
13990
13991 if (!getDerived().AlwaysRebuild() &&
13992 Callee.get() == E->getCallee() &&
13993 !ArgChanged)
13994 return SemaRef.MaybeBindToTemporary(E);
13995
13996 // FIXME: Wrong source location information for the '('.
13997 SourceLocation FakeLParenLoc
13998 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13999
14000 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14001 if (E->hasStoredFPFeatures()) {
14002 FPOptionsOverride NewOverrides = E->getFPFeatures();
14003 getSema().CurFPFeatures =
14004 NewOverrides.applyOverrides(getSema().getLangOpts());
14005 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14006 }
14007
14008 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14009 Args,
14010 E->getRParenLoc());
14011}
14012
14013template<typename Derived>
14014ExprResult
14015TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
14016 ExprResult Base = getDerived().TransformExpr(E->getBase());
14017 if (Base.isInvalid())
14018 return ExprError();
14019
14020 NestedNameSpecifierLoc QualifierLoc;
14021 if (E->hasQualifier()) {
14022 QualifierLoc
14023 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
14024
14025 if (!QualifierLoc)
14026 return ExprError();
14027 }
14028 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
14029
14030 ValueDecl *Member
14031 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
14032 E->getMemberDecl()));
14033 if (!Member)
14034 return ExprError();
14035
14036 NamedDecl *FoundDecl = E->getFoundDecl();
14037 if (FoundDecl == E->getMemberDecl()) {
14038 FoundDecl = Member;
14039 } else {
14040 FoundDecl = cast_or_null<NamedDecl>(
14041 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
14042 if (!FoundDecl)
14043 return ExprError();
14044 }
14045
14046 if (!getDerived().AlwaysRebuild() &&
14047 Base.get() == E->getBase() &&
14048 QualifierLoc == E->getQualifierLoc() &&
14049 Member == E->getMemberDecl() &&
14050 FoundDecl == E->getFoundDecl() &&
14051 !E->hasExplicitTemplateArgs()) {
14052
14053 // Skip for member expression of (this->f), rebuilt thisi->f is needed
14054 // for Openmp where the field need to be privatizized in the case.
14055 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
14056 getSema().OpenMP().isOpenMPRebuildMemberExpr(
14057 cast<ValueDecl>(Val: Member)))) {
14058 // Mark it referenced in the new context regardless.
14059 // FIXME: this is a bit instantiation-specific.
14060 SemaRef.MarkMemberReferenced(E);
14061 return E;
14062 }
14063 }
14064
14065 TemplateArgumentListInfo TransArgs;
14066 if (E->hasExplicitTemplateArgs()) {
14067 TransArgs.setLAngleLoc(E->getLAngleLoc());
14068 TransArgs.setRAngleLoc(E->getRAngleLoc());
14069 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
14070 E->getNumTemplateArgs(),
14071 TransArgs))
14072 return ExprError();
14073 }
14074
14075 // FIXME: Bogus source location for the operator
14076 SourceLocation FakeOperatorLoc =
14077 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
14078
14079 // FIXME: to do this check properly, we will need to preserve the
14080 // first-qualifier-in-scope here, just in case we had a dependent
14081 // base (and therefore couldn't do the check) and a
14082 // nested-name-qualifier (and therefore could do the lookup).
14083 NamedDecl *FirstQualifierInScope = nullptr;
14084 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
14085 if (MemberNameInfo.getName()) {
14086 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
14087 if (!MemberNameInfo.getName())
14088 return ExprError();
14089 }
14090
14091 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
14092 E->isArrow(),
14093 QualifierLoc,
14094 TemplateKWLoc,
14095 MemberNameInfo,
14096 Member,
14097 FoundDecl,
14098 (E->hasExplicitTemplateArgs()
14099 ? &TransArgs : nullptr),
14100 FirstQualifierInScope);
14101}
14102
14103template<typename Derived>
14104ExprResult
14105TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
14106 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14107 if (LHS.isInvalid())
14108 return ExprError();
14109
14110 ExprResult RHS =
14111 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
14112 if (RHS.isInvalid())
14113 return ExprError();
14114
14115 if (!getDerived().AlwaysRebuild() &&
14116 LHS.get() == E->getLHS() &&
14117 RHS.get() == E->getRHS())
14118 return E;
14119
14120 if (E->isCompoundAssignmentOp())
14121 // FPFeatures has already been established from trailing storage
14122 return getDerived().RebuildBinaryOperator(
14123 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
14124 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14125 FPOptionsOverride NewOverrides(E->getFPFeatures());
14126 getSema().CurFPFeatures =
14127 NewOverrides.applyOverrides(getSema().getLangOpts());
14128 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14129 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
14130 LHS.get(), RHS.get());
14131}
14132
14133template <typename Derived>
14134ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
14135 CXXRewrittenBinaryOperator *E) {
14136 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
14137
14138 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
14139 if (LHS.isInvalid())
14140 return ExprError();
14141
14142 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
14143 if (RHS.isInvalid())
14144 return ExprError();
14145
14146 // Extract the already-resolved callee declarations so that we can restrict
14147 // ourselves to using them as the unqualified lookup results when rebuilding.
14148 UnresolvedSet<2> UnqualLookups;
14149 bool ChangedAnyLookups = false;
14150 Expr *PossibleBinOps[] = {E->getSemanticForm(),
14151 const_cast<Expr *>(Decomp.InnerBinOp)};
14152 for (Expr *PossibleBinOp : PossibleBinOps) {
14153 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
14154 if (!Op)
14155 continue;
14156 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
14157 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
14158 continue;
14159
14160 // Transform the callee in case we built a call to a local extern
14161 // declaration.
14162 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
14163 E->getOperatorLoc(), Callee->getFoundDecl()));
14164 if (!Found)
14165 return ExprError();
14166 if (Found != Callee->getFoundDecl())
14167 ChangedAnyLookups = true;
14168 UnqualLookups.addDecl(D: Found);
14169 }
14170
14171 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
14172 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
14173 // Mark all functions used in the rewrite as referenced. Note that when
14174 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
14175 // function calls, and/or there might be a user-defined conversion sequence
14176 // applied to the operands of the <.
14177 // FIXME: this is a bit instantiation-specific.
14178 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
14179 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
14180 return E;
14181 }
14182
14183 return getDerived().RebuildCXXRewrittenBinaryOperator(
14184 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
14185}
14186
14187template<typename Derived>
14188ExprResult
14189TreeTransform<Derived>::TransformCompoundAssignOperator(
14190 CompoundAssignOperator *E) {
14191 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14192 FPOptionsOverride NewOverrides(E->getFPFeatures());
14193 getSema().CurFPFeatures =
14194 NewOverrides.applyOverrides(getSema().getLangOpts());
14195 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14196 return getDerived().TransformBinaryOperator(E);
14197}
14198
14199template<typename Derived>
14200ExprResult TreeTransform<Derived>::
14201TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
14202 // Just rebuild the common and RHS expressions and see whether we
14203 // get any changes.
14204
14205 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
14206 if (commonExpr.isInvalid())
14207 return ExprError();
14208
14209 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
14210 if (rhs.isInvalid())
14211 return ExprError();
14212
14213 if (!getDerived().AlwaysRebuild() &&
14214 commonExpr.get() == e->getCommon() &&
14215 rhs.get() == e->getFalseExpr())
14216 return e;
14217
14218 return getDerived().RebuildConditionalOperator(commonExpr.get(),
14219 e->getQuestionLoc(),
14220 nullptr,
14221 e->getColonLoc(),
14222 rhs.get());
14223}
14224
14225template<typename Derived>
14226ExprResult
14227TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
14228 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14229 if (Cond.isInvalid())
14230 return ExprError();
14231
14232 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14233 if (LHS.isInvalid())
14234 return ExprError();
14235
14236 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14237 if (RHS.isInvalid())
14238 return ExprError();
14239
14240 if (!getDerived().AlwaysRebuild() &&
14241 Cond.get() == E->getCond() &&
14242 LHS.get() == E->getLHS() &&
14243 RHS.get() == E->getRHS())
14244 return E;
14245
14246 return getDerived().RebuildConditionalOperator(Cond.get(),
14247 E->getQuestionLoc(),
14248 LHS.get(),
14249 E->getColonLoc(),
14250 RHS.get());
14251}
14252
14253template<typename Derived>
14254ExprResult
14255TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
14256 // Implicit casts are eliminated during transformation, since they
14257 // will be recomputed by semantic analysis after transformation.
14258 return getDerived().TransformExpr(E->getSubExprAsWritten());
14259}
14260
14261template<typename Derived>
14262ExprResult
14263TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
14264 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14265 if (!Type)
14266 return ExprError();
14267
14268 ExprResult SubExpr
14269 = getDerived().TransformExpr(E->getSubExprAsWritten());
14270 if (SubExpr.isInvalid())
14271 return ExprError();
14272
14273 if (!getDerived().AlwaysRebuild() &&
14274 Type == E->getTypeInfoAsWritten() &&
14275 SubExpr.get() == E->getSubExpr())
14276 return E;
14277
14278 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
14279 Type,
14280 E->getRParenLoc(),
14281 SubExpr.get());
14282}
14283
14284template<typename Derived>
14285ExprResult
14286TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
14287 TypeSourceInfo *OldT = E->getTypeSourceInfo();
14288 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
14289 if (!NewT)
14290 return ExprError();
14291
14292 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
14293 if (Init.isInvalid())
14294 return ExprError();
14295
14296 if (!getDerived().AlwaysRebuild() &&
14297 OldT == NewT &&
14298 Init.get() == E->getInitializer())
14299 return SemaRef.MaybeBindToTemporary(E);
14300
14301 // Note: the expression type doesn't necessarily match the
14302 // type-as-written, but that's okay, because it should always be
14303 // derivable from the initializer.
14304
14305 return getDerived().RebuildCompoundLiteralExpr(
14306 E->getLParenLoc(), NewT,
14307 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
14308}
14309
14310template<typename Derived>
14311ExprResult
14312TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
14313 ExprResult Base = getDerived().TransformExpr(E->getBase());
14314 if (Base.isInvalid())
14315 return ExprError();
14316
14317 if (!getDerived().AlwaysRebuild() &&
14318 Base.get() == E->getBase())
14319 return E;
14320
14321 // FIXME: Bad source location
14322 SourceLocation FakeOperatorLoc =
14323 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14324 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14325 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
14326 E->getAccessor());
14327}
14328
14329template <typename Derived>
14330ExprResult
14331TreeTransform<Derived>::TransformMatrixElementExpr(MatrixElementExpr *E) {
14332 ExprResult Base = getDerived().TransformExpr(E->getBase());
14333 if (Base.isInvalid())
14334 return ExprError();
14335
14336 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase())
14337 return E;
14338
14339 // FIXME: Bad source location
14340 SourceLocation FakeOperatorLoc =
14341 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
14342 return getDerived().RebuildExtVectorOrMatrixElementExpr(
14343 Base.get(), FakeOperatorLoc, /*isArrow*/ false, E->getAccessorLoc(),
14344 E->getAccessor());
14345}
14346
14347template<typename Derived>
14348ExprResult
14349TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
14350 if (InitListExpr *Syntactic = E->getSyntacticForm())
14351 E = Syntactic;
14352
14353 bool InitChanged = false;
14354
14355 EnterExpressionEvaluationContext Context(
14356 getSema(), EnterExpressionEvaluationContext::InitList);
14357
14358 SmallVector<Expr*, 4> Inits;
14359 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
14360 Inits, &InitChanged))
14361 return ExprError();
14362
14363 if (!getDerived().AlwaysRebuild() && !InitChanged) {
14364 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
14365 // in some cases. We can't reuse it in general, because the syntactic and
14366 // semantic forms are linked, and we can't know that semantic form will
14367 // match even if the syntactic form does.
14368 }
14369
14370 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
14371 E->getRBraceLoc(), E->isExplicit());
14372}
14373
14374template<typename Derived>
14375ExprResult
14376TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
14377 Designation Desig;
14378
14379 // transform the initializer value
14380 ExprResult Init = getDerived().TransformExpr(E->getInit());
14381 if (Init.isInvalid())
14382 return ExprError();
14383
14384 // transform the designators.
14385 SmallVector<Expr*, 4> ArrayExprs;
14386 bool ExprChanged = false;
14387 for (const DesignatedInitExpr::Designator &D : E->designators()) {
14388 if (D.isFieldDesignator()) {
14389 if (D.getFieldDecl()) {
14390 FieldDecl *Field = cast_or_null<FieldDecl>(
14391 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
14392 if (Field != D.getFieldDecl())
14393 // Rebuild the expression when the transformed FieldDecl is
14394 // different to the already assigned FieldDecl.
14395 ExprChanged = true;
14396 if (Field->isAnonymousStructOrUnion())
14397 continue;
14398 } else {
14399 // Ensure that the designator expression is rebuilt when there isn't
14400 // a resolved FieldDecl in the designator as we don't want to assign
14401 // a FieldDecl to a pattern designator that will be instantiated again.
14402 ExprChanged = true;
14403 }
14404 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
14405 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
14406 continue;
14407 }
14408
14409 if (D.isArrayDesignator()) {
14410 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
14411 if (Index.isInvalid())
14412 return ExprError();
14413
14414 Desig.AddDesignator(
14415 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
14416
14417 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
14418 ArrayExprs.push_back(Elt: Index.get());
14419 continue;
14420 }
14421
14422 assert(D.isArrayRangeDesignator() && "New kind of designator?");
14423 ExprResult Start
14424 = getDerived().TransformExpr(E->getArrayRangeStart(D));
14425 if (Start.isInvalid())
14426 return ExprError();
14427
14428 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
14429 if (End.isInvalid())
14430 return ExprError();
14431
14432 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
14433 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
14434
14435 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
14436 End.get() != E->getArrayRangeEnd(D);
14437
14438 ArrayExprs.push_back(Elt: Start.get());
14439 ArrayExprs.push_back(Elt: End.get());
14440 }
14441
14442 if (!getDerived().AlwaysRebuild() &&
14443 Init.get() == E->getInit() &&
14444 !ExprChanged)
14445 return E;
14446
14447 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
14448 E->getEqualOrColonLoc(),
14449 E->usesGNUSyntax(), Init.get());
14450}
14451
14452// Seems that if TransformInitListExpr() only works on the syntactic form of an
14453// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
14454template<typename Derived>
14455ExprResult
14456TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
14457 DesignatedInitUpdateExpr *E) {
14458 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
14459 "initializer");
14460 return ExprError();
14461}
14462
14463template<typename Derived>
14464ExprResult
14465TreeTransform<Derived>::TransformNoInitExpr(
14466 NoInitExpr *E) {
14467 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
14468 return ExprError();
14469}
14470
14471template<typename Derived>
14472ExprResult
14473TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
14474 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
14475 return ExprError();
14476}
14477
14478template<typename Derived>
14479ExprResult
14480TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
14481 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
14482 return ExprError();
14483}
14484
14485template<typename Derived>
14486ExprResult
14487TreeTransform<Derived>::TransformImplicitValueInitExpr(
14488 ImplicitValueInitExpr *E) {
14489 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
14490
14491 // FIXME: Will we ever have proper type location here? Will we actually
14492 // need to transform the type?
14493 QualType T = getDerived().TransformType(E->getType());
14494 if (T.isNull())
14495 return ExprError();
14496
14497 if (!getDerived().AlwaysRebuild() &&
14498 T == E->getType())
14499 return E;
14500
14501 return getDerived().RebuildImplicitValueInitExpr(T);
14502}
14503
14504template<typename Derived>
14505ExprResult
14506TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
14507 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
14508 if (!TInfo)
14509 return ExprError();
14510
14511 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14512 if (SubExpr.isInvalid())
14513 return ExprError();
14514
14515 if (!getDerived().AlwaysRebuild() &&
14516 TInfo == E->getWrittenTypeInfo() &&
14517 SubExpr.get() == E->getSubExpr())
14518 return E;
14519
14520 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
14521 TInfo, E->getRParenLoc());
14522}
14523
14524template<typename Derived>
14525ExprResult
14526TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
14527 bool ArgumentChanged = false;
14528 SmallVector<Expr*, 4> Inits;
14529 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
14530 ArgChanged: &ArgumentChanged))
14531 return ExprError();
14532
14533 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
14534 Inits,
14535 E->getRParenLoc());
14536}
14537
14538/// Transform an address-of-label expression.
14539///
14540/// By default, the transformation of an address-of-label expression always
14541/// rebuilds the expression, so that the label identifier can be resolved to
14542/// the corresponding label statement by semantic analysis.
14543template<typename Derived>
14544ExprResult
14545TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
14546 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
14547 E->getLabel());
14548 if (!LD)
14549 return ExprError();
14550
14551 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
14552 cast<LabelDecl>(Val: LD));
14553}
14554
14555template<typename Derived>
14556ExprResult
14557TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
14558 SemaRef.ActOnStartStmtExpr();
14559 StmtResult SubStmt
14560 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
14561 if (SubStmt.isInvalid()) {
14562 SemaRef.ActOnStmtExprError();
14563 return ExprError();
14564 }
14565
14566 unsigned OldDepth = E->getTemplateDepth();
14567 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
14568
14569 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
14570 SubStmt.get() == E->getSubStmt()) {
14571 // Calling this an 'error' is unintuitive, but it does the right thing.
14572 SemaRef.ActOnStmtExprError();
14573 return SemaRef.MaybeBindToTemporary(E);
14574 }
14575
14576 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
14577 E->getRParenLoc(), NewDepth);
14578}
14579
14580template<typename Derived>
14581ExprResult
14582TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
14583 ExprResult Cond = getDerived().TransformExpr(E->getCond());
14584 if (Cond.isInvalid())
14585 return ExprError();
14586
14587 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
14588 if (LHS.isInvalid())
14589 return ExprError();
14590
14591 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
14592 if (RHS.isInvalid())
14593 return ExprError();
14594
14595 if (!getDerived().AlwaysRebuild() &&
14596 Cond.get() == E->getCond() &&
14597 LHS.get() == E->getLHS() &&
14598 RHS.get() == E->getRHS())
14599 return E;
14600
14601 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14602 Cond.get(), LHS.get(), RHS.get(),
14603 E->getRParenLoc());
14604}
14605
14606template<typename Derived>
14607ExprResult
14608TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14609 return E;
14610}
14611
14612template<typename Derived>
14613ExprResult
14614TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14615 switch (E->getOperator()) {
14616 case OO_New:
14617 case OO_Delete:
14618 case OO_Array_New:
14619 case OO_Array_Delete:
14620 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14621
14622 case OO_Subscript:
14623 case OO_Call: {
14624 // This is a call to an object's operator().
14625 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14626
14627 // Transform the object itself.
14628 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14629 if (Object.isInvalid())
14630 return ExprError();
14631
14632 // FIXME: Poor location information. Also, if the location for the end of
14633 // the token is within a macro expansion, getLocForEndOfToken() will return
14634 // an invalid source location. If that happens and we have an otherwise
14635 // valid end location, use the valid one instead of the invalid one.
14636 SourceLocation EndLoc = static_cast<Expr *>(Object.get())->getEndLoc();
14637 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(Loc: EndLoc);
14638 if (FakeLParenLoc.isInvalid() && EndLoc.isValid())
14639 FakeLParenLoc = EndLoc;
14640
14641 // Transform the call arguments.
14642 SmallVector<Expr*, 8> Args;
14643 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14644 Args))
14645 return ExprError();
14646
14647 if (E->getOperator() == OO_Subscript)
14648 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14649 Args, E->getEndLoc());
14650
14651 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14652 E->getEndLoc());
14653 }
14654
14655#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14656 case OO_##Name: \
14657 break;
14658
14659#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14660#include "clang/Basic/OperatorKinds.def"
14661
14662 case OO_Conditional:
14663 llvm_unreachable("conditional operator is not actually overloadable");
14664
14665 case OO_None:
14666 case NUM_OVERLOADED_OPERATORS:
14667 llvm_unreachable("not an overloaded operator?");
14668 }
14669
14670 ExprResult First;
14671 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14672 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14673 else
14674 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14675 if (First.isInvalid())
14676 return ExprError();
14677
14678 ExprResult Second;
14679 if (E->getNumArgs() == 2) {
14680 Second =
14681 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14682 if (Second.isInvalid())
14683 return ExprError();
14684 }
14685
14686 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14687 FPOptionsOverride NewOverrides(E->getFPFeatures());
14688 getSema().CurFPFeatures =
14689 NewOverrides.applyOverrides(getSema().getLangOpts());
14690 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14691
14692 Expr *Callee = E->getCallee();
14693 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14694 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14695 Sema::LookupOrdinaryName);
14696 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14697 return ExprError();
14698
14699 return getDerived().RebuildCXXOperatorCallExpr(
14700 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14701 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14702 }
14703
14704 UnresolvedSet<1> Functions;
14705 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14706 Callee = ICE->getSubExprAsWritten();
14707 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14708 ValueDecl *VD = cast_or_null<ValueDecl>(
14709 getDerived().TransformDecl(DR->getLocation(), DR));
14710 if (!VD)
14711 return ExprError();
14712
14713 if (!isa<CXXMethodDecl>(Val: VD))
14714 Functions.addDecl(D: VD);
14715
14716 return getDerived().RebuildCXXOperatorCallExpr(
14717 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14718 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14719}
14720
14721template<typename Derived>
14722ExprResult
14723TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14724 return getDerived().TransformCallExpr(E);
14725}
14726
14727template <typename Derived>
14728ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14729 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14730 getSema().CurContext != E->getParentContext();
14731
14732 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14733 return E;
14734
14735 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14736 E->getBeginLoc(), E->getEndLoc(),
14737 getSema().CurContext);
14738}
14739
14740template <typename Derived>
14741ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14742 return E;
14743}
14744
14745template<typename Derived>
14746ExprResult
14747TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14748 // Transform the callee.
14749 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14750 if (Callee.isInvalid())
14751 return ExprError();
14752
14753 // Transform exec config.
14754 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14755 if (EC.isInvalid())
14756 return ExprError();
14757
14758 // Transform arguments.
14759 bool ArgChanged = false;
14760 SmallVector<Expr*, 8> Args;
14761 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14762 &ArgChanged))
14763 return ExprError();
14764
14765 if (!getDerived().AlwaysRebuild() &&
14766 Callee.get() == E->getCallee() &&
14767 !ArgChanged)
14768 return SemaRef.MaybeBindToTemporary(E);
14769
14770 // FIXME: Wrong source location information for the '('.
14771 SourceLocation FakeLParenLoc
14772 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14773 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14774 Args,
14775 E->getRParenLoc(), EC.get());
14776}
14777
14778template<typename Derived>
14779ExprResult
14780TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14781 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14782 if (!Type)
14783 return ExprError();
14784
14785 ExprResult SubExpr
14786 = getDerived().TransformExpr(E->getSubExprAsWritten());
14787 if (SubExpr.isInvalid())
14788 return ExprError();
14789
14790 if (!getDerived().AlwaysRebuild() &&
14791 Type == E->getTypeInfoAsWritten() &&
14792 SubExpr.get() == E->getSubExpr())
14793 return E;
14794 return getDerived().RebuildCXXNamedCastExpr(
14795 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14796 Type, E->getAngleBrackets().getEnd(),
14797 // FIXME. this should be '(' location
14798 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14799}
14800
14801template<typename Derived>
14802ExprResult
14803TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14804 TypeSourceInfo *TSI =
14805 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14806 if (!TSI)
14807 return ExprError();
14808
14809 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14810 if (Sub.isInvalid())
14811 return ExprError();
14812
14813 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14814 Sub.get(), BCE->getEndLoc());
14815}
14816
14817template<typename Derived>
14818ExprResult
14819TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14820 return getDerived().TransformCXXNamedCastExpr(E);
14821}
14822
14823template<typename Derived>
14824ExprResult
14825TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14826 return getDerived().TransformCXXNamedCastExpr(E);
14827}
14828
14829template<typename Derived>
14830ExprResult
14831TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14832 CXXReinterpretCastExpr *E) {
14833 return getDerived().TransformCXXNamedCastExpr(E);
14834}
14835
14836template<typename Derived>
14837ExprResult
14838TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14839 return getDerived().TransformCXXNamedCastExpr(E);
14840}
14841
14842template<typename Derived>
14843ExprResult
14844TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14845 return getDerived().TransformCXXNamedCastExpr(E);
14846}
14847
14848template<typename Derived>
14849ExprResult
14850TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14851 CXXFunctionalCastExpr *E) {
14852 TypeSourceInfo *Type =
14853 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14854 if (!Type)
14855 return ExprError();
14856
14857 ExprResult SubExpr
14858 = getDerived().TransformExpr(E->getSubExprAsWritten());
14859 if (SubExpr.isInvalid())
14860 return ExprError();
14861
14862 if (!getDerived().AlwaysRebuild() &&
14863 Type == E->getTypeInfoAsWritten() &&
14864 SubExpr.get() == E->getSubExpr())
14865 return E;
14866
14867 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14868 E->getLParenLoc(),
14869 SubExpr.get(),
14870 E->getRParenLoc(),
14871 E->isListInitialization());
14872}
14873
14874template<typename Derived>
14875ExprResult
14876TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14877 if (E->isTypeOperand()) {
14878 TypeSourceInfo *TInfo
14879 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14880 if (!TInfo)
14881 return ExprError();
14882
14883 if (!getDerived().AlwaysRebuild() &&
14884 TInfo == E->getTypeOperandSourceInfo())
14885 return E;
14886
14887 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14888 TInfo, E->getEndLoc());
14889 }
14890
14891 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14892 // type. We must not unilaterally enter unevaluated context here, as then
14893 // semantic processing can re-transform an already transformed operand.
14894 Expr *Op = E->getExprOperand();
14895 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14896 if (E->isGLValue()) {
14897 QualType OpType = Op->getType();
14898 if (auto *RD = OpType->getAsCXXRecordDecl()) {
14899 if (SemaRef.RequireCompleteType(Loc: E->getBeginLoc(), T: OpType,
14900 DiagID: diag::err_incomplete_typeid))
14901 return ExprError();
14902
14903 if (RD->isPolymorphic())
14904 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14905 }
14906 }
14907
14908 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14909 Sema::ReuseLambdaContextDecl);
14910
14911 ExprResult SubExpr = getDerived().TransformExpr(Op);
14912 if (SubExpr.isInvalid())
14913 return ExprError();
14914
14915 if (!getDerived().AlwaysRebuild() &&
14916 SubExpr.get() == E->getExprOperand())
14917 return E;
14918
14919 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14920 SubExpr.get(), E->getEndLoc());
14921}
14922
14923template<typename Derived>
14924ExprResult
14925TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14926 if (E->isTypeOperand()) {
14927 TypeSourceInfo *TInfo
14928 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14929 if (!TInfo)
14930 return ExprError();
14931
14932 if (!getDerived().AlwaysRebuild() &&
14933 TInfo == E->getTypeOperandSourceInfo())
14934 return E;
14935
14936 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14937 TInfo, E->getEndLoc());
14938 }
14939
14940 EnterExpressionEvaluationContext Unevaluated(
14941 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14942
14943 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14944 if (SubExpr.isInvalid())
14945 return ExprError();
14946
14947 if (!getDerived().AlwaysRebuild() &&
14948 SubExpr.get() == E->getExprOperand())
14949 return E;
14950
14951 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14952 SubExpr.get(), E->getEndLoc());
14953}
14954
14955template<typename Derived>
14956ExprResult
14957TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14958 return E;
14959}
14960
14961template<typename Derived>
14962ExprResult
14963TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14964 CXXNullPtrLiteralExpr *E) {
14965 return E;
14966}
14967
14968template<typename Derived>
14969ExprResult
14970TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14971
14972 // In lambdas, the qualifiers of the type depends of where in
14973 // the call operator `this` appear, and we do not have a good way to
14974 // rebuild this information, so we transform the type.
14975 //
14976 // In other contexts, the type of `this` may be overrided
14977 // for type deduction, so we need to recompute it.
14978 //
14979 // Always recompute the type if we're in the body of a lambda, and
14980 // 'this' is dependent on a lambda's explicit object parameter; we
14981 // also need to always rebuild the expression in this case to clear
14982 // the flag.
14983 QualType T = [&]() {
14984 auto &S = getSema();
14985 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14986 return S.getCurrentThisType();
14987 if (S.getCurLambda())
14988 return getDerived().TransformType(E->getType());
14989 return S.getCurrentThisType();
14990 }();
14991
14992 if (!getDerived().AlwaysRebuild() && T == E->getType() &&
14993 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter()) {
14994 // Mark it referenced in the new context regardless.
14995 // FIXME: this is a bit instantiation-specific.
14996 getSema().MarkThisReferenced(E);
14997 return E;
14998 }
14999
15000 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
15001}
15002
15003template<typename Derived>
15004ExprResult
15005TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
15006 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
15007 if (SubExpr.isInvalid())
15008 return ExprError();
15009
15010 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
15011
15012 if (!getDerived().AlwaysRebuild() &&
15013 SubExpr.get() == E->getSubExpr())
15014 return E;
15015
15016 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
15017 E->isThrownVariableInScope());
15018}
15019
15020template<typename Derived>
15021ExprResult
15022TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
15023 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
15024 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
15025 if (!Param)
15026 return ExprError();
15027
15028 ExprResult InitRes;
15029 if (E->hasRewrittenInit()) {
15030 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
15031 if (InitRes.isInvalid())
15032 return ExprError();
15033 }
15034
15035 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
15036 E->getUsedContext() == SemaRef.CurContext &&
15037 InitRes.get() == E->getRewrittenExpr())
15038 return E;
15039
15040 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
15041 InitRes.get());
15042}
15043
15044template<typename Derived>
15045ExprResult
15046TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
15047 FieldDecl *Field = cast_or_null<FieldDecl>(
15048 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
15049 if (!Field)
15050 return ExprError();
15051
15052 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
15053 E->getUsedContext() == SemaRef.CurContext)
15054 return E;
15055
15056 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
15057}
15058
15059template<typename Derived>
15060ExprResult
15061TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
15062 CXXScalarValueInitExpr *E) {
15063 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
15064 if (!T)
15065 return ExprError();
15066
15067 if (!getDerived().AlwaysRebuild() &&
15068 T == E->getTypeSourceInfo())
15069 return E;
15070
15071 return getDerived().RebuildCXXScalarValueInitExpr(T,
15072 /*FIXME:*/T->getTypeLoc().getEndLoc(),
15073 E->getRParenLoc());
15074}
15075
15076template<typename Derived>
15077ExprResult
15078TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
15079 // Transform the type that we're allocating
15080 TypeSourceInfo *AllocTypeInfo =
15081 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
15082 if (!AllocTypeInfo)
15083 return ExprError();
15084
15085 // Transform the size of the array we're allocating (if any).
15086 std::optional<Expr *> ArraySize;
15087 if (E->isArray()) {
15088 ExprResult NewArraySize;
15089 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
15090 NewArraySize = getDerived().TransformExpr(*OldArraySize);
15091 if (NewArraySize.isInvalid())
15092 return ExprError();
15093 }
15094 ArraySize = NewArraySize.get();
15095 }
15096
15097 // Transform the placement arguments (if any).
15098 bool ArgumentChanged = false;
15099 SmallVector<Expr*, 8> PlacementArgs;
15100 if (getDerived().TransformExprs(E->getPlacementArgs(),
15101 E->getNumPlacementArgs(), true,
15102 PlacementArgs, &ArgumentChanged))
15103 return ExprError();
15104
15105 // Transform the initializer (if any).
15106 Expr *OldInit = E->getInitializer();
15107 ExprResult NewInit;
15108 if (OldInit)
15109 NewInit = getDerived().TransformInitializer(OldInit, true);
15110 if (NewInit.isInvalid())
15111 return ExprError();
15112
15113 // Transform new operator and delete operator.
15114 FunctionDecl *OperatorNew = nullptr;
15115 if (E->getOperatorNew()) {
15116 OperatorNew = cast_or_null<FunctionDecl>(
15117 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
15118 if (!OperatorNew)
15119 return ExprError();
15120 }
15121
15122 FunctionDecl *OperatorDelete = nullptr;
15123 if (E->getOperatorDelete()) {
15124 OperatorDelete = cast_or_null<FunctionDecl>(
15125 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15126 if (!OperatorDelete)
15127 return ExprError();
15128 }
15129
15130 if (!getDerived().AlwaysRebuild() &&
15131 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
15132 ArraySize == E->getArraySize() &&
15133 NewInit.get() == OldInit &&
15134 OperatorNew == E->getOperatorNew() &&
15135 OperatorDelete == E->getOperatorDelete() &&
15136 !ArgumentChanged) {
15137 // Mark any declarations we need as referenced.
15138 // FIXME: instantiation-specific.
15139 if (OperatorNew)
15140 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
15141 if (OperatorDelete)
15142 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15143
15144 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
15145 QualType ElementType
15146 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
15147 if (CXXRecordDecl *Record = ElementType->getAsCXXRecordDecl()) {
15148 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record))
15149 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
15150 }
15151 }
15152
15153 return E;
15154 }
15155
15156 QualType AllocType = AllocTypeInfo->getType();
15157 if (!ArraySize) {
15158 // If no array size was specified, but the new expression was
15159 // instantiated with an array type (e.g., "new T" where T is
15160 // instantiated with "int[4]"), extract the outer bound from the
15161 // array type as our array size. We do this with constant and
15162 // dependently-sized array types.
15163 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
15164 if (!ArrayT) {
15165 // Do nothing
15166 } else if (const ConstantArrayType *ConsArrayT
15167 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
15168 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
15169 type: SemaRef.Context.getSizeType(),
15170 /*FIXME:*/ l: E->getBeginLoc());
15171 AllocType = ConsArrayT->getElementType();
15172 } else if (const DependentSizedArrayType *DepArrayT
15173 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
15174 if (DepArrayT->getSizeExpr()) {
15175 ArraySize = DepArrayT->getSizeExpr();
15176 AllocType = DepArrayT->getElementType();
15177 }
15178 }
15179 }
15180
15181 return getDerived().RebuildCXXNewExpr(
15182 E->getBeginLoc(), E->isGlobalNew(),
15183 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
15184 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
15185 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
15186}
15187
15188template<typename Derived>
15189ExprResult
15190TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
15191 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
15192 if (Operand.isInvalid())
15193 return ExprError();
15194
15195 // Transform the delete operator, if known.
15196 FunctionDecl *OperatorDelete = nullptr;
15197 if (E->getOperatorDelete()) {
15198 OperatorDelete = cast_or_null<FunctionDecl>(
15199 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
15200 if (!OperatorDelete)
15201 return ExprError();
15202 }
15203
15204 if (!getDerived().AlwaysRebuild() &&
15205 Operand.get() == E->getArgument() &&
15206 OperatorDelete == E->getOperatorDelete()) {
15207 // Mark any declarations we need as referenced.
15208 // FIXME: instantiation-specific.
15209 if (OperatorDelete)
15210 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
15211
15212 if (!E->getArgument()->isTypeDependent()) {
15213 QualType Destroyed = SemaRef.Context.getBaseElementType(
15214 QT: E->getDestroyedType());
15215 if (auto *Record = Destroyed->getAsCXXRecordDecl())
15216 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15217 Func: SemaRef.LookupDestructor(Class: Record));
15218 }
15219
15220 return E;
15221 }
15222
15223 return getDerived().RebuildCXXDeleteExpr(
15224 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
15225}
15226
15227template<typename Derived>
15228ExprResult
15229TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
15230 CXXPseudoDestructorExpr *E) {
15231 ExprResult Base = getDerived().TransformExpr(E->getBase());
15232 if (Base.isInvalid())
15233 return ExprError();
15234
15235 ParsedType ObjectTypePtr;
15236 bool MayBePseudoDestructor = false;
15237 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15238 OpLoc: E->getOperatorLoc(),
15239 OpKind: E->isArrow()? tok::arrow : tok::period,
15240 ObjectType&: ObjectTypePtr,
15241 MayBePseudoDestructor);
15242 if (Base.isInvalid())
15243 return ExprError();
15244
15245 QualType ObjectType = ObjectTypePtr.get();
15246 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
15247 if (QualifierLoc) {
15248 QualifierLoc
15249 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
15250 if (!QualifierLoc)
15251 return ExprError();
15252 }
15253 CXXScopeSpec SS;
15254 SS.Adopt(Other: QualifierLoc);
15255
15256 PseudoDestructorTypeStorage Destroyed;
15257 if (E->getDestroyedTypeInfo()) {
15258 TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
15259 E->getDestroyedTypeInfo(), ObjectType,
15260 /*FirstQualifierInScope=*/nullptr);
15261 if (!DestroyedTypeInfo)
15262 return ExprError();
15263 Destroyed = DestroyedTypeInfo;
15264 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
15265 // We aren't likely to be able to resolve the identifier down to a type
15266 // now anyway, so just retain the identifier.
15267 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
15268 E->getDestroyedTypeLoc());
15269 } else {
15270 // Look for a destructor known with the given name.
15271 ParsedType T = SemaRef.getDestructorName(
15272 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
15273 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
15274 if (!T)
15275 return ExprError();
15276
15277 Destroyed
15278 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
15279 Loc: E->getDestroyedTypeLoc());
15280 }
15281
15282 TypeSourceInfo *ScopeTypeInfo = nullptr;
15283 if (E->getScopeTypeInfo()) {
15284 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
15285 E->getScopeTypeInfo(), ObjectType, nullptr);
15286 if (!ScopeTypeInfo)
15287 return ExprError();
15288 }
15289
15290 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
15291 E->getOperatorLoc(),
15292 E->isArrow(),
15293 SS,
15294 ScopeTypeInfo,
15295 E->getColonColonLoc(),
15296 E->getTildeLoc(),
15297 Destroyed);
15298}
15299
15300template <typename Derived>
15301bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
15302 bool RequiresADL,
15303 LookupResult &R) {
15304 // Transform all the decls.
15305 bool AllEmptyPacks = true;
15306 for (auto *OldD : Old->decls()) {
15307 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
15308 if (!InstD) {
15309 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
15310 // This can happen because of dependent hiding.
15311 if (isa<UsingShadowDecl>(Val: OldD))
15312 continue;
15313 else {
15314 R.clear();
15315 return true;
15316 }
15317 }
15318
15319 // Expand using pack declarations.
15320 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
15321 ArrayRef<NamedDecl*> Decls = SingleDecl;
15322 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
15323 Decls = UPD->expansions();
15324
15325 // Expand using declarations.
15326 for (auto *D : Decls) {
15327 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
15328 for (auto *SD : UD->shadows())
15329 R.addDecl(D: SD);
15330 } else {
15331 R.addDecl(D);
15332 }
15333 }
15334
15335 AllEmptyPacks &= Decls.empty();
15336 }
15337
15338 // C++ [temp.res]/8.4.2:
15339 // The program is ill-formed, no diagnostic required, if [...] lookup for
15340 // a name in the template definition found a using-declaration, but the
15341 // lookup in the corresponding scope in the instantiation odoes not find
15342 // any declarations because the using-declaration was a pack expansion and
15343 // the corresponding pack is empty
15344 if (AllEmptyPacks && !RequiresADL) {
15345 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
15346 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
15347 return true;
15348 }
15349
15350 // Resolve a kind, but don't do any further analysis. If it's
15351 // ambiguous, the callee needs to deal with it.
15352 R.resolveKind();
15353
15354 if (Old->hasTemplateKeyword() && !R.empty()) {
15355 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
15356 getSema().FilterAcceptableTemplateNames(R,
15357 /*AllowFunctionTemplates=*/true,
15358 /*AllowDependent=*/true);
15359 if (R.empty()) {
15360 // If a 'template' keyword was used, a lookup that finds only non-template
15361 // names is an error.
15362 getSema().Diag(R.getNameLoc(),
15363 diag::err_template_kw_refers_to_non_template)
15364 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
15365 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
15366 getSema().Diag(FoundDecl->getLocation(),
15367 diag::note_template_kw_refers_to_non_template)
15368 << R.getLookupName();
15369 return true;
15370 }
15371 }
15372
15373 return false;
15374}
15375
15376template <typename Derived>
15377ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
15378 UnresolvedLookupExpr *Old) {
15379 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
15380}
15381
15382template <typename Derived>
15383ExprResult
15384TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
15385 bool IsAddressOfOperand) {
15386 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
15387 Sema::LookupOrdinaryName);
15388
15389 // Transform the declaration set.
15390 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
15391 return ExprError();
15392
15393 // Rebuild the nested-name qualifier, if present.
15394 CXXScopeSpec SS;
15395 if (Old->getQualifierLoc()) {
15396 NestedNameSpecifierLoc QualifierLoc
15397 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
15398 if (!QualifierLoc)
15399 return ExprError();
15400
15401 SS.Adopt(Other: QualifierLoc);
15402 }
15403
15404 if (Old->getNamingClass()) {
15405 CXXRecordDecl *NamingClass
15406 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
15407 Old->getNameLoc(),
15408 Old->getNamingClass()));
15409 if (!NamingClass) {
15410 R.clear();
15411 return ExprError();
15412 }
15413
15414 R.setNamingClass(NamingClass);
15415 }
15416
15417 // Rebuild the template arguments, if any.
15418 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
15419 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
15420 if (Old->hasExplicitTemplateArgs() &&
15421 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15422 Old->getNumTemplateArgs(),
15423 TransArgs)) {
15424 R.clear();
15425 return ExprError();
15426 }
15427
15428 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
15429 // a non-static data member is named in an unevaluated operand, or when
15430 // a member is named in a dependent class scope function template explicit
15431 // specialization that is neither declared static nor with an explicit object
15432 // parameter.
15433 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
15434 return SemaRef.BuildPossibleImplicitMemberExpr(
15435 SS, TemplateKWLoc, R,
15436 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
15437 /*S=*/S: nullptr);
15438
15439 // If we have neither explicit template arguments, nor the template keyword,
15440 // it's a normal declaration name or member reference.
15441 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
15442 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
15443
15444 // If we have template arguments, then rebuild the template-id expression.
15445 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
15446 Old->requiresADL(), &TransArgs);
15447}
15448
15449template<typename Derived>
15450ExprResult
15451TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
15452 bool ArgChanged = false;
15453 SmallVector<TypeSourceInfo *, 4> Args;
15454 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
15455 TypeSourceInfo *From = E->getArg(I);
15456 TypeLoc FromTL = From->getTypeLoc();
15457 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
15458 TypeLocBuilder TLB;
15459 TLB.reserve(Requested: FromTL.getFullDataSize());
15460 QualType To = getDerived().TransformType(TLB, FromTL);
15461 if (To.isNull())
15462 return ExprError();
15463
15464 if (To == From->getType())
15465 Args.push_back(Elt: From);
15466 else {
15467 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15468 ArgChanged = true;
15469 }
15470 continue;
15471 }
15472
15473 ArgChanged = true;
15474
15475 // We have a pack expansion. Instantiate it.
15476 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
15477 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
15478 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15479 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
15480
15481 // Determine whether the set of unexpanded parameter packs can and should
15482 // be expanded.
15483 bool Expand = true;
15484 bool RetainExpansion = false;
15485 UnsignedOrNone OrigNumExpansions =
15486 ExpansionTL.getTypePtr()->getNumExpansions();
15487 UnsignedOrNone NumExpansions = OrigNumExpansions;
15488 if (getDerived().TryExpandParameterPacks(
15489 ExpansionTL.getEllipsisLoc(), PatternTL.getSourceRange(),
15490 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
15491 RetainExpansion, NumExpansions))
15492 return ExprError();
15493
15494 if (!Expand) {
15495 // The transform has determined that we should perform a simple
15496 // transformation on the pack expansion, producing another pack
15497 // expansion.
15498 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
15499
15500 TypeLocBuilder TLB;
15501 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15502
15503 QualType To = getDerived().TransformType(TLB, PatternTL);
15504 if (To.isNull())
15505 return ExprError();
15506
15507 To = getDerived().RebuildPackExpansionType(To,
15508 PatternTL.getSourceRange(),
15509 ExpansionTL.getEllipsisLoc(),
15510 NumExpansions);
15511 if (To.isNull())
15512 return ExprError();
15513
15514 PackExpansionTypeLoc ToExpansionTL
15515 = TLB.push<PackExpansionTypeLoc>(T: To);
15516 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15517 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15518 continue;
15519 }
15520
15521 // Expand the pack expansion by substituting for each argument in the
15522 // pack(s).
15523 for (unsigned I = 0; I != *NumExpansions; ++I) {
15524 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
15525 TypeLocBuilder TLB;
15526 TLB.reserve(Requested: PatternTL.getFullDataSize());
15527 QualType To = getDerived().TransformType(TLB, PatternTL);
15528 if (To.isNull())
15529 return ExprError();
15530
15531 if (To->containsUnexpandedParameterPack()) {
15532 To = getDerived().RebuildPackExpansionType(To,
15533 PatternTL.getSourceRange(),
15534 ExpansionTL.getEllipsisLoc(),
15535 NumExpansions);
15536 if (To.isNull())
15537 return ExprError();
15538
15539 PackExpansionTypeLoc ToExpansionTL
15540 = TLB.push<PackExpansionTypeLoc>(T: To);
15541 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15542 }
15543
15544 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15545 }
15546
15547 if (!RetainExpansion)
15548 continue;
15549
15550 // If we're supposed to retain a pack expansion, do so by temporarily
15551 // forgetting the partially-substituted parameter pack.
15552 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
15553
15554 TypeLocBuilder TLB;
15555 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
15556
15557 QualType To = getDerived().TransformType(TLB, PatternTL);
15558 if (To.isNull())
15559 return ExprError();
15560
15561 To = getDerived().RebuildPackExpansionType(To,
15562 PatternTL.getSourceRange(),
15563 ExpansionTL.getEllipsisLoc(),
15564 NumExpansions);
15565 if (To.isNull())
15566 return ExprError();
15567
15568 PackExpansionTypeLoc ToExpansionTL
15569 = TLB.push<PackExpansionTypeLoc>(T: To);
15570 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
15571 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
15572 }
15573
15574 if (!getDerived().AlwaysRebuild() && !ArgChanged)
15575 return E;
15576
15577 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
15578 E->getEndLoc());
15579}
15580
15581template<typename Derived>
15582ExprResult
15583TreeTransform<Derived>::TransformConceptSpecializationExpr(
15584 ConceptSpecializationExpr *E) {
15585 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
15586 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
15587 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
15588 Old->NumTemplateArgs, TransArgs))
15589 return ExprError();
15590
15591 return getDerived().RebuildConceptSpecializationExpr(
15592 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
15593 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
15594 &TransArgs);
15595}
15596
15597template<typename Derived>
15598ExprResult
15599TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
15600 SmallVector<ParmVarDecl*, 4> TransParams;
15601 SmallVector<QualType, 4> TransParamTypes;
15602 Sema::ExtParameterInfoBuilder ExtParamInfos;
15603
15604 // C++2a [expr.prim.req]p2
15605 // Expressions appearing within a requirement-body are unevaluated operands.
15606 EnterExpressionEvaluationContext Ctx(
15607 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15608 Sema::ReuseLambdaContextDecl);
15609
15610 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15611 C&: getSema().Context, DC: getSema().CurContext,
15612 StartLoc: E->getBody()->getBeginLoc());
15613
15614 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15615
15616 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15617 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15618 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15619
15620 for (ParmVarDecl *Param : TransParams)
15621 if (Param)
15622 Param->setDeclContext(Body);
15623
15624 // On failure to transform, TransformRequiresTypeParams returns an expression
15625 // in the event that the transformation of the type params failed in some way.
15626 // It is expected that this will result in a 'not satisfied' Requires clause
15627 // when instantiating.
15628 if (!TypeParamResult.isUnset())
15629 return TypeParamResult;
15630
15631 SmallVector<concepts::Requirement *, 4> TransReqs;
15632 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15633 TransReqs))
15634 return ExprError();
15635
15636 for (concepts::Requirement *Req : TransReqs) {
15637 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15638 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15639 ER->getReturnTypeRequirement()
15640 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15641 ->setDeclContext(Body);
15642 }
15643 }
15644 }
15645
15646 return getDerived().RebuildRequiresExpr(
15647 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15648 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15649}
15650
15651template<typename Derived>
15652bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15653 ArrayRef<concepts::Requirement *> Reqs,
15654 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15655 for (concepts::Requirement *Req : Reqs) {
15656 concepts::Requirement *TransReq = nullptr;
15657 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15658 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15659 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15660 TransReq = getDerived().TransformExprRequirement(ExprReq);
15661 else
15662 TransReq = getDerived().TransformNestedRequirement(
15663 cast<concepts::NestedRequirement>(Val: Req));
15664 if (!TransReq)
15665 return true;
15666 Transformed.push_back(Elt: TransReq);
15667 }
15668 return false;
15669}
15670
15671template<typename Derived>
15672concepts::TypeRequirement *
15673TreeTransform<Derived>::TransformTypeRequirement(
15674 concepts::TypeRequirement *Req) {
15675 if (Req->isSubstitutionFailure()) {
15676 if (getDerived().AlwaysRebuild())
15677 return getDerived().RebuildTypeRequirement(
15678 Req->getSubstitutionDiagnostic());
15679 return Req;
15680 }
15681 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15682 if (!TransType)
15683 return nullptr;
15684 return getDerived().RebuildTypeRequirement(TransType);
15685}
15686
15687template<typename Derived>
15688concepts::ExprRequirement *
15689TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15690 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15691 if (Req->isExprSubstitutionFailure())
15692 TransExpr = Req->getExprSubstitutionDiagnostic();
15693 else {
15694 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15695 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15696 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15697 if (TransExprRes.isInvalid())
15698 return nullptr;
15699 TransExpr = TransExprRes.get();
15700 }
15701
15702 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15703 const auto &RetReq = Req->getReturnTypeRequirement();
15704 if (RetReq.isEmpty())
15705 TransRetReq.emplace();
15706 else if (RetReq.isSubstitutionFailure())
15707 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15708 else if (RetReq.isTypeConstraint()) {
15709 TemplateParameterList *OrigTPL =
15710 RetReq.getTypeConstraintTemplateParameterList();
15711 TemplateParameterList *TPL =
15712 getDerived().TransformTemplateParameterList(OrigTPL);
15713 if (!TPL)
15714 return nullptr;
15715 TransRetReq.emplace(args&: TPL);
15716 }
15717 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15718 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15719 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15720 Req->getNoexceptLoc(),
15721 std::move(*TransRetReq));
15722 return getDerived().RebuildExprRequirement(
15723 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15724 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15725}
15726
15727template<typename Derived>
15728concepts::NestedRequirement *
15729TreeTransform<Derived>::TransformNestedRequirement(
15730 concepts::NestedRequirement *Req) {
15731 if (Req->hasInvalidConstraint()) {
15732 if (getDerived().AlwaysRebuild())
15733 return getDerived().RebuildNestedRequirement(
15734 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15735 return Req;
15736 }
15737 ExprResult TransConstraint =
15738 getDerived().TransformExpr(Req->getConstraintExpr());
15739 if (TransConstraint.isInvalid())
15740 return nullptr;
15741 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15742}
15743
15744template<typename Derived>
15745ExprResult
15746TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15747 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15748 if (!T)
15749 return ExprError();
15750
15751 if (!getDerived().AlwaysRebuild() &&
15752 T == E->getQueriedTypeSourceInfo())
15753 return E;
15754
15755 ExprResult SubExpr;
15756 {
15757 EnterExpressionEvaluationContext Unevaluated(
15758 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15759 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15760 if (SubExpr.isInvalid())
15761 return ExprError();
15762 }
15763
15764 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15765 SubExpr.get(), E->getEndLoc());
15766}
15767
15768template<typename Derived>
15769ExprResult
15770TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15771 ExprResult SubExpr;
15772 {
15773 EnterExpressionEvaluationContext Unevaluated(
15774 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15775 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15776 if (SubExpr.isInvalid())
15777 return ExprError();
15778
15779 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15780 return E;
15781 }
15782
15783 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15784 SubExpr.get(), E->getEndLoc());
15785}
15786
15787template <typename Derived>
15788ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15789 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15790 TypeSourceInfo **RecoveryTSI) {
15791 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15792 DRE, AddrTaken, RecoveryTSI);
15793
15794 // Propagate both errors and recovered types, which return ExprEmpty.
15795 if (!NewDRE.isUsable())
15796 return NewDRE;
15797
15798 // We got an expr, wrap it up in parens.
15799 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15800 return PE;
15801 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15802 PE->getRParen());
15803}
15804
15805template <typename Derived>
15806ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15807 DependentScopeDeclRefExpr *E) {
15808 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15809 nullptr);
15810}
15811
15812template <typename Derived>
15813ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15814 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15815 TypeSourceInfo **RecoveryTSI) {
15816 assert(E->getQualifierLoc());
15817 NestedNameSpecifierLoc QualifierLoc =
15818 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15819 if (!QualifierLoc)
15820 return ExprError();
15821 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15822
15823 // TODO: If this is a conversion-function-id, verify that the
15824 // destination type name (if present) resolves the same way after
15825 // instantiation as it did in the local scope.
15826
15827 DeclarationNameInfo NameInfo =
15828 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15829 if (!NameInfo.getName())
15830 return ExprError();
15831
15832 if (!E->hasExplicitTemplateArgs()) {
15833 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15834 // Note: it is sufficient to compare the Name component of NameInfo:
15835 // if name has not changed, DNLoc has not changed either.
15836 NameInfo.getName() == E->getDeclName())
15837 return E;
15838
15839 return getDerived().RebuildDependentScopeDeclRefExpr(
15840 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15841 IsAddressOfOperand, RecoveryTSI);
15842 }
15843
15844 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15845 if (getDerived().TransformTemplateArguments(
15846 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15847 return ExprError();
15848
15849 return getDerived().RebuildDependentScopeDeclRefExpr(
15850 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15851 RecoveryTSI);
15852}
15853
15854template<typename Derived>
15855ExprResult
15856TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15857 // CXXConstructExprs other than for list-initialization and
15858 // CXXTemporaryObjectExpr are always implicit, so when we have
15859 // a 1-argument construction we just transform that argument.
15860 if (getDerived().AllowSkippingCXXConstructExpr() &&
15861 ((E->getNumArgs() == 1 ||
15862 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15863 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15864 !E->isListInitialization()))
15865 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15866 /*DirectInit*/ false);
15867
15868 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15869
15870 QualType T = getDerived().TransformType(E->getType());
15871 if (T.isNull())
15872 return ExprError();
15873
15874 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15875 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15876 if (!Constructor)
15877 return ExprError();
15878
15879 bool ArgumentChanged = false;
15880 SmallVector<Expr*, 8> Args;
15881 {
15882 EnterExpressionEvaluationContext Context(
15883 getSema(), EnterExpressionEvaluationContext::InitList,
15884 E->isListInitialization());
15885 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15886 &ArgumentChanged))
15887 return ExprError();
15888 }
15889
15890 if (!getDerived().AlwaysRebuild() &&
15891 T == E->getType() &&
15892 Constructor == E->getConstructor() &&
15893 !ArgumentChanged) {
15894 // Mark the constructor as referenced.
15895 // FIXME: Instantiation-specific
15896 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15897 return E;
15898 }
15899
15900 return getDerived().RebuildCXXConstructExpr(
15901 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15902 E->hadMultipleCandidates(), E->isListInitialization(),
15903 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15904 E->getConstructionKind(), E->getParenOrBraceRange());
15905}
15906
15907template<typename Derived>
15908ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15909 CXXInheritedCtorInitExpr *E) {
15910 QualType T = getDerived().TransformType(E->getType());
15911 if (T.isNull())
15912 return ExprError();
15913
15914 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15915 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15916 if (!Constructor)
15917 return ExprError();
15918
15919 if (!getDerived().AlwaysRebuild() &&
15920 T == E->getType() &&
15921 Constructor == E->getConstructor()) {
15922 // Mark the constructor as referenced.
15923 // FIXME: Instantiation-specific
15924 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15925 return E;
15926 }
15927
15928 return getDerived().RebuildCXXInheritedCtorInitExpr(
15929 T, E->getLocation(), Constructor,
15930 E->constructsVBase(), E->inheritedFromVBase());
15931}
15932
15933/// Transform a C++ temporary-binding expression.
15934///
15935/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15936/// transform the subexpression and return that.
15937template<typename Derived>
15938ExprResult
15939TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15940 if (auto *Dtor = E->getTemporary()->getDestructor())
15941 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15942 Func: const_cast<CXXDestructorDecl *>(Dtor));
15943 return getDerived().TransformExpr(E->getSubExpr());
15944}
15945
15946/// Transform a C++ expression that contains cleanups that should
15947/// be run after the expression is evaluated.
15948///
15949/// Since ExprWithCleanups nodes are implicitly generated, we
15950/// just transform the subexpression and return that.
15951template<typename Derived>
15952ExprResult
15953TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15954 return getDerived().TransformExpr(E->getSubExpr());
15955}
15956
15957template<typename Derived>
15958ExprResult
15959TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15960 CXXTemporaryObjectExpr *E) {
15961 TypeSourceInfo *T =
15962 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15963 if (!T)
15964 return ExprError();
15965
15966 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15967 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15968 if (!Constructor)
15969 return ExprError();
15970
15971 bool ArgumentChanged = false;
15972 SmallVector<Expr*, 8> Args;
15973 Args.reserve(N: E->getNumArgs());
15974 {
15975 EnterExpressionEvaluationContext Context(
15976 getSema(), EnterExpressionEvaluationContext::InitList,
15977 E->isListInitialization());
15978 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15979 ArgChanged: &ArgumentChanged))
15980 return ExprError();
15981
15982 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15983 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc(),
15984 /*IsExplicit=*/IsExplicit: true);
15985 if (Res.isInvalid())
15986 return ExprError();
15987 Args = {Res.get()};
15988 }
15989 }
15990
15991 if (!getDerived().AlwaysRebuild() &&
15992 T == E->getTypeSourceInfo() &&
15993 Constructor == E->getConstructor() &&
15994 !ArgumentChanged) {
15995 // FIXME: Instantiation-specific
15996 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15997 return SemaRef.MaybeBindToTemporary(E);
15998 }
15999
16000 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
16001 return getDerived().RebuildCXXTemporaryObjectExpr(
16002 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
16003}
16004
16005template<typename Derived>
16006ExprResult
16007TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
16008 // Transform any init-capture expressions before entering the scope of the
16009 // lambda body, because they are not semantically within that scope.
16010 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
16011 struct TransformedInitCapture {
16012 // The location of the ... if the result is retaining a pack expansion.
16013 SourceLocation EllipsisLoc;
16014 // Zero or more expansions of the init-capture.
16015 SmallVector<InitCaptureInfoTy, 4> Expansions;
16016 };
16017 SmallVector<TransformedInitCapture, 4> InitCaptures;
16018 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
16019 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16020 CEnd = E->capture_end();
16021 C != CEnd; ++C) {
16022 if (!E->isInitCapture(Capture: C))
16023 continue;
16024
16025 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
16026 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16027
16028 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
16029 UnsignedOrNone NumExpansions) {
16030 ExprResult NewExprInitResult = getDerived().TransformInitializer(
16031 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
16032
16033 if (NewExprInitResult.isInvalid()) {
16034 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
16035 return;
16036 }
16037 Expr *NewExprInit = NewExprInitResult.get();
16038
16039 QualType NewInitCaptureType =
16040 getSema().buildLambdaInitCaptureInitialization(
16041 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
16042 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
16043 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
16044 VarDecl::CInit,
16045 NewExprInit);
16046 Result.Expansions.push_back(
16047 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
16048 };
16049
16050 // If this is an init-capture pack, consider expanding the pack now.
16051 if (OldVD->isParameterPack()) {
16052 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
16053 ->getTypeLoc()
16054 .castAs<PackExpansionTypeLoc>();
16055 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16056 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
16057
16058 // Determine whether the set of unexpanded parameter packs can and should
16059 // be expanded.
16060 bool Expand = true;
16061 bool RetainExpansion = false;
16062 UnsignedOrNone OrigNumExpansions =
16063 ExpansionTL.getTypePtr()->getNumExpansions();
16064 UnsignedOrNone NumExpansions = OrigNumExpansions;
16065 if (getDerived().TryExpandParameterPacks(
16066 ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
16067 Unexpanded, /*FailOnPackProducingTemplates=*/true, Expand,
16068 RetainExpansion, NumExpansions))
16069 return ExprError();
16070 assert(!RetainExpansion && "Should not need to retain expansion after a "
16071 "capture since it cannot be extended");
16072 if (Expand) {
16073 for (unsigned I = 0; I != *NumExpansions; ++I) {
16074 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16075 SubstInitCapture(SourceLocation(), std::nullopt);
16076 }
16077 } else {
16078 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
16079 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
16080 }
16081 } else {
16082 SubstInitCapture(SourceLocation(), std::nullopt);
16083 }
16084 }
16085
16086 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
16087 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
16088
16089 // Create the local class that will describe the lambda.
16090
16091 // FIXME: DependencyKind below is wrong when substituting inside a templated
16092 // context that isn't a DeclContext (such as a variable template), or when
16093 // substituting an unevaluated lambda inside of a function's parameter's type
16094 // - as parameter types are not instantiated from within a function's DC. We
16095 // use evaluation contexts to distinguish the function parameter case.
16096 CXXRecordDecl::LambdaDependencyKind DependencyKind =
16097 CXXRecordDecl::LDK_Unknown;
16098 DeclContext *DC = getSema().CurContext;
16099 // A RequiresExprBodyDecl is not interesting for dependencies.
16100 // For the following case,
16101 //
16102 // template <typename>
16103 // concept C = requires { [] {}; };
16104 //
16105 // template <class F>
16106 // struct Widget;
16107 //
16108 // template <C F>
16109 // struct Widget<F> {};
16110 //
16111 // While we are substituting Widget<F>, the parent of DC would be
16112 // the template specialization itself. Thus, the lambda expression
16113 // will be deemed as dependent even if there are no dependent template
16114 // arguments.
16115 // (A ClassTemplateSpecializationDecl is always a dependent context.)
16116 while (DC->isRequiresExprBody() || isa<CXXExpansionStmtDecl>(Val: DC))
16117 DC = DC->getParent();
16118 if ((getSema().isUnevaluatedContext() ||
16119 getSema().isConstantEvaluatedContext()) &&
16120 !(dyn_cast_or_null<CXXRecordDecl>(Val: DC->getParent()) &&
16121 cast<CXXRecordDecl>(Val: DC->getParent())->isGenericLambda()) &&
16122 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
16123 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
16124
16125 CXXRecordDecl *OldClass = E->getLambdaClass();
16126 CXXRecordDecl *Class = getSema().createLambdaClosureType(
16127 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
16128 E->getCaptureDefault());
16129 getDerived().transformedLocalDecl(OldClass, {Class});
16130
16131 CXXMethodDecl *NewCallOperator =
16132 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
16133
16134 // Enter the scope of the lambda.
16135 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
16136 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
16137 E->hasExplicitParameters(), E->isMutable());
16138
16139 // Introduce the context of the call operator.
16140 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
16141 /*NewThisContext*/false);
16142
16143 bool Invalid = false;
16144
16145 // Transform captures.
16146 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16147 CEnd = E->capture_end();
16148 C != CEnd; ++C) {
16149 // When we hit the first implicit capture, tell Sema that we've finished
16150 // the list of explicit captures.
16151 if (C->isImplicit())
16152 break;
16153
16154 // Capturing 'this' is trivial.
16155 if (C->capturesThis()) {
16156 // If this is a lambda that is part of a default member initialiser
16157 // and which we're instantiating outside the class that 'this' is
16158 // supposed to refer to, adjust the type of 'this' accordingly.
16159 //
16160 // Otherwise, leave the type of 'this' as-is.
16161 Sema::CXXThisScopeRAII ThisScope(
16162 getSema(),
16163 dyn_cast_if_present<CXXRecordDecl>(
16164 getSema().getFunctionLevelDeclContext()),
16165 Qualifiers());
16166 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16167 /*BuildAndDiagnose*/ true, nullptr,
16168 C->getCaptureKind() == LCK_StarThis);
16169 continue;
16170 }
16171 // Captured expression will be recaptured during captured variables
16172 // rebuilding.
16173 if (C->capturesVLAType())
16174 continue;
16175
16176 // Rebuild init-captures, including the implied field declaration.
16177 if (E->isInitCapture(Capture: C)) {
16178 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
16179
16180 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
16181 llvm::SmallVector<Decl*, 4> NewVDs;
16182
16183 for (InitCaptureInfoTy &Info : NewC.Expansions) {
16184 ExprResult Init = Info.first;
16185 QualType InitQualType = Info.second;
16186 if (Init.isInvalid() || InitQualType.isNull()) {
16187 Invalid = true;
16188 break;
16189 }
16190 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
16191 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
16192 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
16193 getSema().CurContext);
16194 if (!NewVD) {
16195 Invalid = true;
16196 break;
16197 }
16198 NewVDs.push_back(Elt: NewVD);
16199 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
16200 // Cases we want to tackle:
16201 // ([C(Pack)] {}, ...)
16202 // But rule out cases e.g.
16203 // [...C = Pack()] {}
16204 if (NewC.EllipsisLoc.isInvalid())
16205 LSI->ContainsUnexpandedParameterPack |=
16206 Init.get()->containsUnexpandedParameterPack();
16207 }
16208
16209 if (Invalid)
16210 break;
16211
16212 getDerived().transformedLocalDecl(OldVD, NewVDs);
16213 continue;
16214 }
16215
16216 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16217
16218 // Determine the capture kind for Sema.
16219 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
16220 : C->getCaptureKind() == LCK_ByCopy
16221 ? TryCaptureKind::ExplicitByVal
16222 : TryCaptureKind::ExplicitByRef;
16223 SourceLocation EllipsisLoc;
16224 if (C->isPackExpansion()) {
16225 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
16226 bool ShouldExpand = false;
16227 bool RetainExpansion = false;
16228 UnsignedOrNone NumExpansions = std::nullopt;
16229 if (getDerived().TryExpandParameterPacks(
16230 C->getEllipsisLoc(), C->getLocation(), Unexpanded,
16231 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16232 RetainExpansion, NumExpansions)) {
16233 Invalid = true;
16234 continue;
16235 }
16236
16237 if (ShouldExpand) {
16238 // The transform has determined that we should perform an expansion;
16239 // transform and capture each of the arguments.
16240 // expansion of the pattern. Do so.
16241 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
16242 for (unsigned I = 0; I != *NumExpansions; ++I) {
16243 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16244 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
16245 getDerived().TransformDecl(C->getLocation(), Pack));
16246 if (!CapturedVar) {
16247 Invalid = true;
16248 continue;
16249 }
16250
16251 // Capture the transformed variable.
16252 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
16253 }
16254
16255 // FIXME: Retain a pack expansion if RetainExpansion is true.
16256
16257 continue;
16258 }
16259
16260 EllipsisLoc = C->getEllipsisLoc();
16261 }
16262
16263 // Transform the captured variable.
16264 auto *CapturedVar = cast_or_null<ValueDecl>(
16265 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16266 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
16267 Invalid = true;
16268 continue;
16269 }
16270
16271 // This is not an init-capture; however it contains an unexpanded pack e.g.
16272 // ([Pack] {}(), ...)
16273 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
16274 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
16275
16276 // Capture the transformed variable.
16277 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
16278 EllipsisLoc);
16279 }
16280 getSema().finishLambdaExplicitCaptures(LSI);
16281
16282 // Transform the template parameters, and add them to the current
16283 // instantiation scope. The null case is handled correctly.
16284 auto TPL = getDerived().TransformTemplateParameterList(
16285 E->getTemplateParameterList());
16286 LSI->GLTemplateParameterList = TPL;
16287 if (TPL) {
16288 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
16289 TPL);
16290 LSI->ContainsUnexpandedParameterPack |=
16291 TPL->containsUnexpandedParameterPack();
16292 }
16293
16294 TypeLocBuilder NewCallOpTLBuilder;
16295 TypeLoc OldCallOpTypeLoc =
16296 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
16297 QualType NewCallOpType =
16298 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
16299 if (NewCallOpType.isNull())
16300 return ExprError();
16301 LSI->ContainsUnexpandedParameterPack |=
16302 NewCallOpType->containsUnexpandedParameterPack();
16303 TypeSourceInfo *NewCallOpTSI =
16304 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
16305
16306 // The type may be an AttributedType or some other kind of sugar;
16307 // get the actual underlying FunctionProtoType.
16308 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
16309 assert(FPTL && "Not a FunctionProtoType?");
16310
16311 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
16312 if (TRC) {
16313 ExprResult E = getDerived().TransformLambdaConstraint(
16314 const_cast<Expr *>(TRC.ConstraintExpr));
16315 if (E.isInvalid())
16316 return E;
16317 TRC.ConstraintExpr = E.get();
16318 }
16319
16320 getSema().CompleteLambdaCallOperator(
16321 NewCallOperator, E->getCallOperator()->getLocation(),
16322 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
16323 E->getCallOperator()->getConstexprKind(),
16324 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
16325 E->hasExplicitResultType());
16326
16327 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
16328 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
16329
16330 {
16331 // Number the lambda for linkage purposes if necessary.
16332 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
16333
16334 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
16335 if (getDerived().ReplacingOriginal()) {
16336 Numbering = OldClass->getLambdaNumbering();
16337 }
16338
16339 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
16340 }
16341
16342 // FIXME: Sema's lambda-building mechanism expects us to push an expression
16343 // evaluation context even if we're not transforming the function body.
16344 getSema().PushExpressionEvaluationContextForFunction(
16345 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
16346 E->getCallOperator());
16347
16348 StmtResult Body;
16349 {
16350 Sema::NonSFINAEContext _(getSema());
16351 Sema::CodeSynthesisContext C;
16352 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
16353 C.PointOfInstantiation = E->getBody()->getBeginLoc();
16354 getSema().pushCodeSynthesisContext(C);
16355
16356 // Instantiate the body of the lambda expression.
16357 Body = Invalid ? StmtError()
16358 : getDerived().TransformLambdaBody(E, E->getBody());
16359
16360 getSema().popCodeSynthesisContext();
16361 }
16362
16363 // ActOnLambda* will pop the function scope for us.
16364 FuncScopeCleanup.disable();
16365
16366 if (Body.isInvalid()) {
16367 SavedContext.pop();
16368 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
16369 /*IsInstantiation=*/true);
16370 return ExprError();
16371 }
16372
16373 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
16374 /*IsInstantiation=*/true,
16375 /*RetainFunctionScopeInfo=*/true);
16376 SavedContext.pop();
16377
16378 // Recompute the dependency of the lambda so that we can defer the lambda call
16379 // construction until after we have all the necessary template arguments. For
16380 // example, given
16381 //
16382 // template <class> struct S {
16383 // template <class U>
16384 // using Type = decltype([](U){}(42.0));
16385 // };
16386 // void foo() {
16387 // using T = S<int>::Type<float>;
16388 // ^~~~~~
16389 // }
16390 //
16391 // We would end up here from instantiating S<int> when ensuring its
16392 // completeness. That would transform the lambda call expression regardless of
16393 // the absence of the corresponding argument for U.
16394 //
16395 // Going ahead with unsubstituted type U makes things worse: we would soon
16396 // compare the argument type (which is float) against the parameter U
16397 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
16398 // error suggesting unmatched types 'U' and 'float'!
16399 //
16400 // That said, everything will be fine if we defer that semantic checking.
16401 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
16402 // dependent. Since the CallExpr's dependency boils down to the lambda's
16403 // dependency in this case, we can harness that by recomputing the dependency
16404 // from the instantiation arguments.
16405 //
16406 // FIXME: Creating the type of a lambda requires us to have a dependency
16407 // value, which happens before its substitution. We update its dependency
16408 // *after* the substitution in case we can't decide the dependency
16409 // so early, e.g. because we want to see if any of the *substituted*
16410 // parameters are dependent.
16411 DependencyKind = getDerived().ComputeLambdaDependency(LSI);
16412 Class->setLambdaDependencyKind(DependencyKind);
16413
16414 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
16415 Body.get()->getEndLoc(), LSI);
16416}
16417
16418template<typename Derived>
16419StmtResult
16420TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
16421 return TransformStmt(S);
16422}
16423
16424template<typename Derived>
16425StmtResult
16426TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
16427 // Transform captures.
16428 for (LambdaExpr::capture_iterator C = E->capture_begin(),
16429 CEnd = E->capture_end();
16430 C != CEnd; ++C) {
16431 // When we hit the first implicit capture, tell Sema that we've finished
16432 // the list of explicit captures.
16433 if (!C->isImplicit())
16434 continue;
16435
16436 // Capturing 'this' is trivial.
16437 if (C->capturesThis()) {
16438 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
16439 /*BuildAndDiagnose*/ true, nullptr,
16440 C->getCaptureKind() == LCK_StarThis);
16441 continue;
16442 }
16443 // Captured expression will be recaptured during captured variables
16444 // rebuilding.
16445 if (C->capturesVLAType())
16446 continue;
16447
16448 assert(C->capturesVariable() && "unexpected kind of lambda capture");
16449 assert(!E->isInitCapture(C) && "implicit init-capture?");
16450
16451 // Transform the captured variable.
16452 VarDecl *CapturedVar = cast_or_null<VarDecl>(
16453 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
16454 if (!CapturedVar || CapturedVar->isInvalidDecl())
16455 return StmtError();
16456
16457 // Capture the transformed variable.
16458 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
16459 }
16460
16461 return S;
16462}
16463
16464template<typename Derived>
16465ExprResult
16466TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
16467 CXXUnresolvedConstructExpr *E) {
16468 TypeSourceInfo *T =
16469 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
16470 if (!T)
16471 return ExprError();
16472
16473 bool ArgumentChanged = false;
16474 SmallVector<Expr*, 8> Args;
16475 Args.reserve(N: E->getNumArgs());
16476 {
16477 EnterExpressionEvaluationContext Context(
16478 getSema(), EnterExpressionEvaluationContext::InitList,
16479 E->isListInitialization());
16480 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
16481 &ArgumentChanged))
16482 return ExprError();
16483 }
16484
16485 if (!getDerived().AlwaysRebuild() &&
16486 T == E->getTypeSourceInfo() &&
16487 !ArgumentChanged)
16488 return E;
16489
16490 // FIXME: we're faking the locations of the commas
16491 return getDerived().RebuildCXXUnresolvedConstructExpr(
16492 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
16493}
16494
16495template<typename Derived>
16496ExprResult
16497TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
16498 CXXDependentScopeMemberExpr *E) {
16499 // Transform the base of the expression.
16500 ExprResult Base((Expr*) nullptr);
16501 Expr *OldBase;
16502 QualType BaseType;
16503 QualType ObjectType;
16504 if (!E->isImplicitAccess()) {
16505 OldBase = E->getBase();
16506 Base = getDerived().TransformExpr(OldBase);
16507 if (Base.isInvalid())
16508 return ExprError();
16509
16510 // Start the member reference and compute the object's type.
16511 ParsedType ObjectTy;
16512 bool MayBePseudoDestructor = false;
16513 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
16514 OpLoc: E->getOperatorLoc(),
16515 OpKind: E->isArrow()? tok::arrow : tok::period,
16516 ObjectType&: ObjectTy,
16517 MayBePseudoDestructor);
16518 if (Base.isInvalid())
16519 return ExprError();
16520
16521 ObjectType = ObjectTy.get();
16522 BaseType = ((Expr*) Base.get())->getType();
16523 } else {
16524 OldBase = nullptr;
16525 BaseType = getDerived().TransformType(E->getBaseType());
16526 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
16527 }
16528
16529 // Transform the first part of the nested-name-specifier that qualifies
16530 // the member name.
16531 NamedDecl *FirstQualifierInScope
16532 = getDerived().TransformFirstQualifierInScope(
16533 E->getFirstQualifierFoundInScope(),
16534 E->getQualifierLoc().getBeginLoc());
16535
16536 NestedNameSpecifierLoc QualifierLoc;
16537 if (E->getQualifier()) {
16538 QualifierLoc
16539 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
16540 ObjectType,
16541 FirstQualifierInScope);
16542 if (!QualifierLoc)
16543 return ExprError();
16544 }
16545
16546 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
16547
16548 // TODO: If this is a conversion-function-id, verify that the
16549 // destination type name (if present) resolves the same way after
16550 // instantiation as it did in the local scope.
16551
16552 DeclarationNameInfo NameInfo
16553 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
16554 if (!NameInfo.getName())
16555 return ExprError();
16556
16557 if (!E->hasExplicitTemplateArgs()) {
16558 // This is a reference to a member without an explicitly-specified
16559 // template argument list. Optimize for this common case.
16560 if (!getDerived().AlwaysRebuild() &&
16561 Base.get() == OldBase &&
16562 BaseType == E->getBaseType() &&
16563 QualifierLoc == E->getQualifierLoc() &&
16564 NameInfo.getName() == E->getMember() &&
16565 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
16566 return E;
16567
16568 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16569 BaseType,
16570 E->isArrow(),
16571 E->getOperatorLoc(),
16572 QualifierLoc,
16573 TemplateKWLoc,
16574 FirstQualifierInScope,
16575 NameInfo,
16576 /*TemplateArgs*/nullptr);
16577 }
16578
16579 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
16580 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
16581 E->getNumTemplateArgs(),
16582 TransArgs))
16583 return ExprError();
16584
16585 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
16586 BaseType,
16587 E->isArrow(),
16588 E->getOperatorLoc(),
16589 QualifierLoc,
16590 TemplateKWLoc,
16591 FirstQualifierInScope,
16592 NameInfo,
16593 &TransArgs);
16594}
16595
16596template <typename Derived>
16597ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
16598 UnresolvedMemberExpr *Old) {
16599 // Transform the base of the expression.
16600 ExprResult Base((Expr *)nullptr);
16601 QualType BaseType;
16602 if (!Old->isImplicitAccess()) {
16603 Base = getDerived().TransformExpr(Old->getBase());
16604 if (Base.isInvalid())
16605 return ExprError();
16606 Base =
16607 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16608 if (Base.isInvalid())
16609 return ExprError();
16610 BaseType = Base.get()->getType();
16611 } else {
16612 BaseType = getDerived().TransformType(Old->getBaseType());
16613 }
16614
16615 NestedNameSpecifierLoc QualifierLoc;
16616 if (Old->getQualifierLoc()) {
16617 QualifierLoc =
16618 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16619 if (!QualifierLoc)
16620 return ExprError();
16621 }
16622
16623 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16624
16625 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16626
16627 // Transform the declaration set.
16628 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16629 return ExprError();
16630
16631 // Determine the naming class.
16632 if (Old->getNamingClass()) {
16633 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16634 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16635 if (!NamingClass)
16636 return ExprError();
16637
16638 R.setNamingClass(NamingClass);
16639 }
16640
16641 TemplateArgumentListInfo TransArgs;
16642 if (Old->hasExplicitTemplateArgs()) {
16643 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16644 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16645 if (getDerived().TransformTemplateArguments(
16646 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16647 return ExprError();
16648 }
16649
16650 // FIXME: to do this check properly, we will need to preserve the
16651 // first-qualifier-in-scope here, just in case we had a dependent
16652 // base (and therefore couldn't do the check) and a
16653 // nested-name-qualifier (and therefore could do the lookup).
16654 NamedDecl *FirstQualifierInScope = nullptr;
16655
16656 return getDerived().RebuildUnresolvedMemberExpr(
16657 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16658 TemplateKWLoc, FirstQualifierInScope, R,
16659 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16660}
16661
16662template<typename Derived>
16663ExprResult
16664TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16665 EnterExpressionEvaluationContext Unevaluated(
16666 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16667 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16668 if (SubExpr.isInvalid())
16669 return ExprError();
16670
16671 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16672 return E;
16673
16674 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16675}
16676
16677template<typename Derived>
16678ExprResult
16679TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16680 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16681 if (Pattern.isInvalid())
16682 return ExprError();
16683
16684 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16685 return E;
16686
16687 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16688 E->getNumExpansions());
16689}
16690
16691template <typename Derived>
16692UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16693 ArrayRef<TemplateArgument> PackArgs) {
16694 UnsignedOrNone Result = 0u;
16695 for (const TemplateArgument &Arg : PackArgs) {
16696 if (!Arg.isPackExpansion()) {
16697 Result = *Result + 1;
16698 continue;
16699 }
16700
16701 TemplateArgumentLoc ArgLoc;
16702 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16703
16704 // Find the pattern of the pack expansion.
16705 SourceLocation Ellipsis;
16706 UnsignedOrNone OrigNumExpansions = std::nullopt;
16707 TemplateArgumentLoc Pattern =
16708 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16709 OrigNumExpansions);
16710
16711 // Substitute under the pack expansion. Do not expand the pack (yet).
16712 TemplateArgumentLoc OutPattern;
16713 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16714 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16715 /*Uneval*/ true))
16716 return 1u;
16717
16718 // See if we can determine the number of arguments from the result.
16719 UnsignedOrNone NumExpansions =
16720 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16721 if (!NumExpansions) {
16722 // No: we must be in an alias template expansion, and we're going to
16723 // need to actually expand the packs.
16724 Result = std::nullopt;
16725 break;
16726 }
16727
16728 Result = *Result + *NumExpansions;
16729 }
16730 return Result;
16731}
16732
16733template<typename Derived>
16734ExprResult
16735TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16736 // If E is not value-dependent, then nothing will change when we transform it.
16737 // Note: This is an instantiation-centric view.
16738 if (!E->isValueDependent())
16739 return E;
16740
16741 EnterExpressionEvaluationContext Unevaluated(
16742 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16743
16744 ArrayRef<TemplateArgument> PackArgs;
16745 TemplateArgument ArgStorage;
16746
16747 // Find the argument list to transform.
16748 if (E->isPartiallySubstituted()) {
16749 PackArgs = E->getPartialArguments();
16750 } else if (E->isValueDependent()) {
16751 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16752 bool ShouldExpand = false;
16753 bool RetainExpansion = false;
16754 UnsignedOrNone NumExpansions = std::nullopt;
16755 if (getDerived().TryExpandParameterPacks(
16756 E->getOperatorLoc(), E->getPackLoc(), Unexpanded,
16757 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16758 RetainExpansion, NumExpansions))
16759 return ExprError();
16760
16761 // If we need to expand the pack, build a template argument from it and
16762 // expand that.
16763 if (ShouldExpand) {
16764 auto *Pack = E->getPack();
16765 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16766 ArgStorage = getSema().Context.getPackExpansionType(
16767 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16768 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16769 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16770 } else {
16771 auto *VD = cast<ValueDecl>(Val: Pack);
16772 ExprResult DRE = getSema().BuildDeclRefExpr(
16773 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16774 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16775 E->getPackLoc());
16776 if (DRE.isInvalid())
16777 return ExprError();
16778 ArgStorage = TemplateArgument(
16779 new (getSema().Context)
16780 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16781 /*IsCanonical=*/false);
16782 }
16783 PackArgs = ArgStorage;
16784 }
16785 }
16786
16787 // If we're not expanding the pack, just transform the decl.
16788 if (!PackArgs.size()) {
16789 auto *Pack = cast_or_null<NamedDecl>(
16790 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16791 if (!Pack)
16792 return ExprError();
16793 return getDerived().RebuildSizeOfPackExpr(
16794 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16795 std::nullopt, {});
16796 }
16797
16798 // Try to compute the result without performing a partial substitution.
16799 UnsignedOrNone Result =
16800 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16801
16802 // Common case: we could determine the number of expansions without
16803 // substituting.
16804 if (Result)
16805 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16806 E->getPackLoc(),
16807 E->getRParenLoc(), *Result, {});
16808
16809 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16810 E->getPackLoc());
16811 {
16812 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16813 typedef TemplateArgumentLocInventIterator<
16814 Derived, const TemplateArgument*> PackLocIterator;
16815 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16816 PackLocIterator(*this, PackArgs.end()),
16817 TransformedPackArgs, /*Uneval*/true))
16818 return ExprError();
16819 }
16820
16821 // Check whether we managed to fully-expand the pack.
16822 // FIXME: Is it possible for us to do so and not hit the early exit path?
16823 SmallVector<TemplateArgument, 8> Args;
16824 bool PartialSubstitution = false;
16825 for (auto &Loc : TransformedPackArgs.arguments()) {
16826 Args.push_back(Elt: Loc.getArgument());
16827 if (Loc.getArgument().isPackExpansion())
16828 PartialSubstitution = true;
16829 }
16830
16831 if (PartialSubstitution)
16832 return getDerived().RebuildSizeOfPackExpr(
16833 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16834 std::nullopt, Args);
16835
16836 return getDerived().RebuildSizeOfPackExpr(
16837 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16838 /*Length=*/static_cast<unsigned>(Args.size()),
16839 /*PartialArgs=*/{});
16840}
16841
16842template <typename Derived>
16843ExprResult
16844TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16845 if (!E->isValueDependent())
16846 return E;
16847
16848 // Transform the index
16849 ExprResult IndexExpr;
16850 {
16851 EnterExpressionEvaluationContext ConstantContext(
16852 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16853 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16854 if (IndexExpr.isInvalid())
16855 return ExprError();
16856 }
16857
16858 SmallVector<Expr *, 5> ExpandedExprs;
16859 bool FullySubstituted = true;
16860 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16861 Expr *Pattern = E->getPackIdExpression();
16862 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16863 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16864 Unexpanded);
16865 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16866
16867 // Determine whether the set of unexpanded parameter packs can and should
16868 // be expanded.
16869 bool ShouldExpand = true;
16870 bool RetainExpansion = false;
16871 UnsignedOrNone OrigNumExpansions = std::nullopt,
16872 NumExpansions = std::nullopt;
16873 if (getDerived().TryExpandParameterPacks(
16874 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16875 /*FailOnPackProducingTemplates=*/true, ShouldExpand,
16876 RetainExpansion, NumExpansions))
16877 return true;
16878 if (!ShouldExpand) {
16879 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16880 ExprResult Pack = getDerived().TransformExpr(Pattern);
16881 if (Pack.isInvalid())
16882 return ExprError();
16883 return getDerived().RebuildPackIndexingExpr(
16884 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16885 {}, /*FullySubstituted=*/false);
16886 }
16887 for (unsigned I = 0; I != *NumExpansions; ++I) {
16888 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16889 ExprResult Out = getDerived().TransformExpr(Pattern);
16890 if (Out.isInvalid())
16891 return true;
16892 if (Out.get()->containsUnexpandedParameterPack()) {
16893 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16894 OrigNumExpansions);
16895 if (Out.isInvalid())
16896 return true;
16897 FullySubstituted = false;
16898 }
16899 ExpandedExprs.push_back(Elt: Out.get());
16900 }
16901 // If we're supposed to retain a pack expansion, do so by temporarily
16902 // forgetting the partially-substituted parameter pack.
16903 if (RetainExpansion) {
16904 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16905
16906 ExprResult Out = getDerived().TransformExpr(Pattern);
16907 if (Out.isInvalid())
16908 return true;
16909
16910 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16911 OrigNumExpansions);
16912 if (Out.isInvalid())
16913 return true;
16914 FullySubstituted = false;
16915 ExpandedExprs.push_back(Elt: Out.get());
16916 }
16917 } else if (!E->expandsToEmptyPack()) {
16918 if (getDerived().TransformExprs(E->getExpressions().data(),
16919 E->getExpressions().size(), false,
16920 ExpandedExprs))
16921 return ExprError();
16922 }
16923
16924 return getDerived().RebuildPackIndexingExpr(
16925 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16926 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16927}
16928
16929template <typename Derived>
16930ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16931 SubstNonTypeTemplateParmPackExpr *E) {
16932 if (!getSema().ArgPackSubstIndex)
16933 // We aren't expanding the parameter pack, so just return ourselves.
16934 return E;
16935
16936 TemplateArgument Pack = E->getArgumentPack();
16937 TemplateArgument Arg = SemaRef.getPackSubstitutedTemplateArgument(Arg: Pack);
16938 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
16939 E->getAssociatedDecl(), E->getParameterPack()->getPosition(),
16940 E->getParameterPack()->getType(), E->getParameterPackLocation(), Arg,
16941 SemaRef.getPackIndex(Pack), E->getFinal());
16942}
16943
16944template <typename Derived>
16945ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16946 SubstNonTypeTemplateParmExpr *E) {
16947 Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
16948
16949 // Insert a constant-evaluated context for the transform.
16950 // Otherwise, when a normalized constraint places the replacement inside
16951 // an unevaluated operand (e.g. decltype), entities it refers to are not
16952 // odr-used, and the constant evaluation performed by CheckTemplateArgument
16953 // below can spuriously fail for otherwise valid replacements,
16954 // e.g. when a call materializes a function parameter of class type whose
16955 // special members were never instantiated.
16956 EnterExpressionEvaluationContext ConstantEvaluated(
16957 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
16958 Sema::ReuseLambdaContextDecl,
16959 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
16960
16961 ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
16962 if (Replacement.isInvalid())
16963 return true;
16964
16965 Decl *AssociatedDecl =
16966 getDerived().TransformDecl(E->getNameLoc(), E->getAssociatedDecl());
16967 if (!AssociatedDecl)
16968 return true;
16969
16970 QualType ParamType = TransformType(E->getParameterType());
16971 if (ParamType.isNull())
16972 return true;
16973
16974 if (Replacement.get() == OrigReplacement &&
16975 AssociatedDecl == E->getAssociatedDecl() &&
16976 ParamType == E->getParameterType())
16977 return E;
16978
16979 if (Replacement.get() != OrigReplacement ||
16980 ParamType != E->getParameterType()) {
16981 auto *Param = cast<NonTypeTemplateParmDecl>(Val: std::get<0>(
16982 t: getReplacedTemplateParameter(D: AssociatedDecl, Index: E->getIndex())));
16983 // When transforming the replacement expression previously, all Sema
16984 // specific annotations, such as implicit casts, are discarded. Calling the
16985 // corresponding sema action is necessary to recover those. Otherwise,
16986 // equivalency of the result would be lost.
16987 TemplateArgument SugaredConverted, CanonicalConverted;
16988 Replacement = SemaRef.CheckTemplateArgument(
16989 Param, InstantiatedParamType: ParamType, Arg: Replacement.get(), SugaredConverted,
16990 CanonicalConverted,
16991 /*StrictCheck=*/StrictCheck: false, CTAK: Sema::CTAK_Specified);
16992 if (Replacement.isInvalid())
16993 return true;
16994 } else {
16995 // Otherwise, the same expression would have been produced.
16996 Replacement = E->getReplacement();
16997 }
16998
16999 return getDerived().RebuildSubstNonTypeTemplateParmExpr(
17000 AssociatedDecl, E->getIndex(), ParamType, E->getNameLoc(),
17001 TemplateArgument(Replacement.get(), /*IsCanonical=*/false),
17002 E->getPackIndex(), E->getFinal());
17003}
17004
17005template<typename Derived>
17006ExprResult
17007TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
17008 // Default behavior is to do nothing with this transformation.
17009 return E;
17010}
17011
17012template<typename Derived>
17013ExprResult
17014TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
17015 MaterializeTemporaryExpr *E) {
17016 return getDerived().TransformExpr(E->getSubExpr());
17017}
17018
17019template<typename Derived>
17020ExprResult
17021TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
17022 UnresolvedLookupExpr *Callee = nullptr;
17023 if (Expr *OldCallee = E->getCallee()) {
17024 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
17025 if (CalleeResult.isInvalid())
17026 return ExprError();
17027 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
17028 }
17029
17030 Expr *Pattern = E->getPattern();
17031
17032 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17033 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
17034 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17035
17036 // Determine whether the set of unexpanded parameter packs can and should
17037 // be expanded.
17038 bool Expand = true;
17039 bool RetainExpansion = false;
17040 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
17041 NumExpansions = OrigNumExpansions;
17042 if (getDerived().TryExpandParameterPacks(
17043 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
17044 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17045 NumExpansions))
17046 return true;
17047
17048 if (!Expand) {
17049 // Do not expand any packs here, just transform and rebuild a fold
17050 // expression.
17051 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17052
17053 ExprResult LHS =
17054 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
17055 if (LHS.isInvalid())
17056 return true;
17057
17058 ExprResult RHS =
17059 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
17060 if (RHS.isInvalid())
17061 return true;
17062
17063 if (!getDerived().AlwaysRebuild() &&
17064 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
17065 return E;
17066
17067 return getDerived().RebuildCXXFoldExpr(
17068 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
17069 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
17070 }
17071
17072 // Formally a fold expression expands to nested parenthesized expressions.
17073 // Enforce this limit to avoid creating trees so deep we can't safely traverse
17074 // them.
17075 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
17076 SemaRef.Diag(Loc: E->getEllipsisLoc(),
17077 DiagID: clang::diag::err_fold_expression_limit_exceeded)
17078 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
17079 << E->getSourceRange();
17080 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
17081 return ExprError();
17082 }
17083
17084 // The transform has determined that we should perform an elementwise
17085 // expansion of the pattern. Do so.
17086 ExprResult Result = getDerived().TransformExpr(E->getInit());
17087 if (Result.isInvalid())
17088 return true;
17089 bool LeftFold = E->isLeftFold();
17090
17091 // If we're retaining an expansion for a right fold, it is the innermost
17092 // component and takes the init (if any).
17093 if (!LeftFold && RetainExpansion) {
17094 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17095
17096 ExprResult Out = getDerived().TransformExpr(Pattern);
17097 if (Out.isInvalid())
17098 return true;
17099
17100 Result = getDerived().RebuildCXXFoldExpr(
17101 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
17102 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
17103 if (Result.isInvalid())
17104 return true;
17105 }
17106
17107 bool WarnedOnComparison = false;
17108 for (unsigned I = 0; I != *NumExpansions; ++I) {
17109 Sema::ArgPackSubstIndexRAII SubstIndex(
17110 getSema(), LeftFold ? I : *NumExpansions - I - 1);
17111 ExprResult Out = getDerived().TransformExpr(Pattern);
17112 if (Out.isInvalid())
17113 return true;
17114
17115 if (Out.get()->containsUnexpandedParameterPack()) {
17116 // We still have a pack; retain a pack expansion for this slice.
17117 Result = getDerived().RebuildCXXFoldExpr(
17118 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
17119 E->getOperator(), E->getEllipsisLoc(),
17120 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
17121 OrigNumExpansions);
17122 } else if (Result.isUsable()) {
17123 // We've got down to a single element; build a binary operator.
17124 Expr *LHS = LeftFold ? Result.get() : Out.get();
17125 Expr *RHS = LeftFold ? Out.get() : Result.get();
17126 if (Callee) {
17127 UnresolvedSet<16> Functions;
17128 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
17129 Result = getDerived().RebuildCXXOperatorCallExpr(
17130 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
17131 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
17132 Functions, LHS, RHS);
17133 } else {
17134 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
17135 E->getOperator(), LHS, RHS,
17136 /*ForFoldExpresion=*/true);
17137 if (!WarnedOnComparison && Result.isUsable()) {
17138 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
17139 BO && BO->isComparisonOp()) {
17140 WarnedOnComparison = true;
17141 SemaRef.Diag(Loc: BO->getBeginLoc(),
17142 DiagID: diag::warn_comparison_in_fold_expression)
17143 << BO->getOpcodeStr();
17144 }
17145 }
17146 }
17147 } else
17148 Result = Out;
17149
17150 if (Result.isInvalid())
17151 return true;
17152 }
17153
17154 // If we're retaining an expansion for a left fold, it is the outermost
17155 // component and takes the complete expansion so far as its init (if any).
17156 if (LeftFold && RetainExpansion) {
17157 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
17158
17159 ExprResult Out = getDerived().TransformExpr(Pattern);
17160 if (Out.isInvalid())
17161 return true;
17162
17163 Result = getDerived().RebuildCXXFoldExpr(
17164 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
17165 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
17166 if (Result.isInvalid())
17167 return true;
17168 }
17169
17170 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
17171 PE->setIsProducedByFoldExpansion();
17172
17173 // If we had no init and an empty pack, and we're not retaining an expansion,
17174 // then produce a fallback value or error.
17175 if (Result.isUnset())
17176 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
17177 E->getOperator());
17178 return Result;
17179}
17180
17181template <typename Derived>
17182ExprResult
17183TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
17184 SmallVector<Expr *, 4> TransformedInits;
17185 ArrayRef<Expr *> InitExprs = E->getInitExprs();
17186
17187 QualType T = getDerived().TransformType(E->getType());
17188
17189 bool ArgChanged = false;
17190
17191 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
17192 TransformedInits, &ArgChanged))
17193 return ExprError();
17194
17195 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
17196 return E;
17197
17198 return getDerived().RebuildCXXParenListInitExpr(
17199 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
17200 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
17201}
17202
17203template<typename Derived>
17204ExprResult
17205TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
17206 CXXStdInitializerListExpr *E) {
17207 return getDerived().TransformExpr(E->getSubExpr());
17208}
17209
17210template<typename Derived>
17211ExprResult
17212TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
17213 return SemaRef.MaybeBindToTemporary(E);
17214}
17215
17216template<typename Derived>
17217ExprResult
17218TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
17219 return E;
17220}
17221
17222template<typename Derived>
17223ExprResult
17224TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
17225 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
17226 if (SubExpr.isInvalid())
17227 return ExprError();
17228
17229 if (!getDerived().AlwaysRebuild() &&
17230 SubExpr.get() == E->getSubExpr())
17231 return E;
17232
17233 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
17234}
17235
17236template<typename Derived>
17237ExprResult
17238TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
17239 // Transform each of the elements.
17240 SmallVector<Expr *, 8> Elements;
17241 bool ArgChanged = false;
17242 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
17243 /*IsCall=*/false, Elements, &ArgChanged))
17244 return ExprError();
17245
17246 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17247 return SemaRef.MaybeBindToTemporary(E);
17248
17249 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
17250 Elements.data(),
17251 Elements.size());
17252}
17253
17254template<typename Derived>
17255ExprResult
17256TreeTransform<Derived>::TransformObjCDictionaryLiteral(
17257 ObjCDictionaryLiteral *E) {
17258 // Transform each of the elements.
17259 SmallVector<ObjCDictionaryElement, 8> Elements;
17260 bool ArgChanged = false;
17261 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
17262 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
17263
17264 if (OrigElement.isPackExpansion()) {
17265 // This key/value element is a pack expansion.
17266 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
17267 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
17268 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
17269 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
17270
17271 // Determine whether the set of unexpanded parameter packs can
17272 // and should be expanded.
17273 bool Expand = true;
17274 bool RetainExpansion = false;
17275 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
17276 UnsignedOrNone NumExpansions = OrigNumExpansions;
17277 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
17278 OrigElement.Value->getEndLoc());
17279 if (getDerived().TryExpandParameterPacks(
17280 OrigElement.EllipsisLoc, PatternRange, Unexpanded,
17281 /*FailOnPackProducingTemplates=*/true, Expand, RetainExpansion,
17282 NumExpansions))
17283 return ExprError();
17284
17285 if (!Expand) {
17286 // The transform has determined that we should perform a simple
17287 // transformation on the pack expansion, producing another pack
17288 // expansion.
17289 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
17290 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17291 if (Key.isInvalid())
17292 return ExprError();
17293
17294 if (Key.get() != OrigElement.Key)
17295 ArgChanged = true;
17296
17297 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17298 if (Value.isInvalid())
17299 return ExprError();
17300
17301 if (Value.get() != OrigElement.Value)
17302 ArgChanged = true;
17303
17304 ObjCDictionaryElement Expansion = {
17305 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
17306 };
17307 Elements.push_back(Elt: Expansion);
17308 continue;
17309 }
17310
17311 // Record right away that the argument was changed. This needs
17312 // to happen even if the array expands to nothing.
17313 ArgChanged = true;
17314
17315 // The transform has determined that we should perform an elementwise
17316 // expansion of the pattern. Do so.
17317 for (unsigned I = 0; I != *NumExpansions; ++I) {
17318 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
17319 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17320 if (Key.isInvalid())
17321 return ExprError();
17322
17323 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
17324 if (Value.isInvalid())
17325 return ExprError();
17326
17327 ObjCDictionaryElement Element = {
17328 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
17329 };
17330
17331 // If any unexpanded parameter packs remain, we still have a
17332 // pack expansion.
17333 // FIXME: Can this really happen?
17334 if (Key.get()->containsUnexpandedParameterPack() ||
17335 Value.get()->containsUnexpandedParameterPack())
17336 Element.EllipsisLoc = OrigElement.EllipsisLoc;
17337
17338 Elements.push_back(Elt: Element);
17339 }
17340
17341 // FIXME: Retain a pack expansion if RetainExpansion is true.
17342
17343 // We've finished with this pack expansion.
17344 continue;
17345 }
17346
17347 // Transform and check key.
17348 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
17349 if (Key.isInvalid())
17350 return ExprError();
17351
17352 if (Key.get() != OrigElement.Key)
17353 ArgChanged = true;
17354
17355 // Transform and check value.
17356 ExprResult Value
17357 = getDerived().TransformExpr(OrigElement.Value);
17358 if (Value.isInvalid())
17359 return ExprError();
17360
17361 if (Value.get() != OrigElement.Value)
17362 ArgChanged = true;
17363
17364 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
17365 .NumExpansions: std::nullopt};
17366 Elements.push_back(Elt: Element);
17367 }
17368
17369 if (!getDerived().AlwaysRebuild() && !ArgChanged)
17370 return SemaRef.MaybeBindToTemporary(E);
17371
17372 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
17373 Elements);
17374}
17375
17376template<typename Derived>
17377ExprResult
17378TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
17379 TypeSourceInfo *EncodedTypeInfo
17380 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
17381 if (!EncodedTypeInfo)
17382 return ExprError();
17383
17384 if (!getDerived().AlwaysRebuild() &&
17385 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
17386 return E;
17387
17388 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
17389 EncodedTypeInfo,
17390 E->getRParenLoc());
17391}
17392
17393template<typename Derived>
17394ExprResult TreeTransform<Derived>::
17395TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
17396 // This is a kind of implicit conversion, and it needs to get dropped
17397 // and recomputed for the same general reasons that ImplicitCastExprs
17398 // do, as well a more specific one: this expression is only valid when
17399 // it appears *immediately* as an argument expression.
17400 return getDerived().TransformExpr(E->getSubExpr());
17401}
17402
17403template<typename Derived>
17404ExprResult TreeTransform<Derived>::
17405TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
17406 TypeSourceInfo *TSInfo
17407 = getDerived().TransformType(E->getTypeInfoAsWritten());
17408 if (!TSInfo)
17409 return ExprError();
17410
17411 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
17412 if (Result.isInvalid())
17413 return ExprError();
17414
17415 if (!getDerived().AlwaysRebuild() &&
17416 TSInfo == E->getTypeInfoAsWritten() &&
17417 Result.get() == E->getSubExpr())
17418 return E;
17419
17420 return SemaRef.ObjC().BuildObjCBridgedCast(
17421 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
17422 SubExpr: Result.get());
17423}
17424
17425template <typename Derived>
17426ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
17427 ObjCAvailabilityCheckExpr *E) {
17428 return E;
17429}
17430
17431template<typename Derived>
17432ExprResult
17433TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
17434 // Transform arguments.
17435 bool ArgChanged = false;
17436 SmallVector<Expr*, 8> Args;
17437 Args.reserve(N: E->getNumArgs());
17438 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
17439 &ArgChanged))
17440 return ExprError();
17441
17442 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
17443 // Class message: transform the receiver type.
17444 TypeSourceInfo *ReceiverTypeInfo
17445 = getDerived().TransformType(E->getClassReceiverTypeInfo());
17446 if (!ReceiverTypeInfo)
17447 return ExprError();
17448
17449 // If nothing changed, just retain the existing message send.
17450 if (!getDerived().AlwaysRebuild() &&
17451 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
17452 return SemaRef.MaybeBindToTemporary(E);
17453
17454 // Build a new class message send.
17455 SmallVector<SourceLocation, 16> SelLocs;
17456 E->getSelectorLocs(SelLocs);
17457 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
17458 E->getSelector(),
17459 SelLocs,
17460 E->getMethodDecl(),
17461 E->getLeftLoc(),
17462 Args,
17463 E->getRightLoc());
17464 }
17465 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
17466 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
17467 if (!E->getMethodDecl())
17468 return ExprError();
17469
17470 // Build a new class message send to 'super'.
17471 SmallVector<SourceLocation, 16> SelLocs;
17472 E->getSelectorLocs(SelLocs);
17473 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
17474 E->getSelector(),
17475 SelLocs,
17476 E->getReceiverType(),
17477 E->getMethodDecl(),
17478 E->getLeftLoc(),
17479 Args,
17480 E->getRightLoc());
17481 }
17482
17483 // Instance message: transform the receiver
17484 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
17485 "Only class and instance messages may be instantiated");
17486 ExprResult Receiver
17487 = getDerived().TransformExpr(E->getInstanceReceiver());
17488 if (Receiver.isInvalid())
17489 return ExprError();
17490
17491 // If nothing changed, just retain the existing message send.
17492 if (!getDerived().AlwaysRebuild() &&
17493 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
17494 return SemaRef.MaybeBindToTemporary(E);
17495
17496 // Build a new instance message send.
17497 SmallVector<SourceLocation, 16> SelLocs;
17498 E->getSelectorLocs(SelLocs);
17499 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
17500 E->getSelector(),
17501 SelLocs,
17502 E->getMethodDecl(),
17503 E->getLeftLoc(),
17504 Args,
17505 E->getRightLoc());
17506}
17507
17508template<typename Derived>
17509ExprResult
17510TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
17511 return E;
17512}
17513
17514template<typename Derived>
17515ExprResult
17516TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
17517 return E;
17518}
17519
17520template<typename Derived>
17521ExprResult
17522TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
17523 // Transform the base expression.
17524 ExprResult Base = getDerived().TransformExpr(E->getBase());
17525 if (Base.isInvalid())
17526 return ExprError();
17527
17528 // We don't need to transform the ivar; it will never change.
17529
17530 // If nothing changed, just retain the existing expression.
17531 if (!getDerived().AlwaysRebuild() &&
17532 Base.get() == E->getBase())
17533 return E;
17534
17535 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
17536 E->getLocation(),
17537 E->isArrow(), E->isFreeIvar());
17538}
17539
17540template<typename Derived>
17541ExprResult
17542TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
17543 // 'super' and types never change. Property never changes. Just
17544 // retain the existing expression.
17545 if (!E->isObjectReceiver())
17546 return E;
17547
17548 // Transform the base expression.
17549 ExprResult Base = getDerived().TransformExpr(E->getBase());
17550 if (Base.isInvalid())
17551 return ExprError();
17552
17553 // We don't need to transform the property; it will never change.
17554
17555 // If nothing changed, just retain the existing expression.
17556 if (!getDerived().AlwaysRebuild() &&
17557 Base.get() == E->getBase())
17558 return E;
17559
17560 if (E->isExplicitProperty())
17561 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17562 E->getExplicitProperty(),
17563 E->getLocation());
17564
17565 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
17566 SemaRef.Context.PseudoObjectTy,
17567 E->getImplicitPropertyGetter(),
17568 E->getImplicitPropertySetter(),
17569 E->getLocation());
17570}
17571
17572template<typename Derived>
17573ExprResult
17574TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
17575 // Transform the base expression.
17576 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
17577 if (Base.isInvalid())
17578 return ExprError();
17579
17580 // Transform the key expression.
17581 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
17582 if (Key.isInvalid())
17583 return ExprError();
17584
17585 // If nothing changed, just retain the existing expression.
17586 if (!getDerived().AlwaysRebuild() &&
17587 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
17588 return E;
17589
17590 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
17591 Base.get(), Key.get(),
17592 E->getAtIndexMethodDecl(),
17593 E->setAtIndexMethodDecl());
17594}
17595
17596template<typename Derived>
17597ExprResult
17598TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
17599 // Transform the base expression.
17600 ExprResult Base = getDerived().TransformExpr(E->getBase());
17601 if (Base.isInvalid())
17602 return ExprError();
17603
17604 // If nothing changed, just retain the existing expression.
17605 if (!getDerived().AlwaysRebuild() &&
17606 Base.get() == E->getBase())
17607 return E;
17608
17609 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
17610 E->getOpLoc(),
17611 E->isArrow());
17612}
17613
17614template<typename Derived>
17615ExprResult
17616TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
17617 bool ArgumentChanged = false;
17618 SmallVector<Expr*, 8> SubExprs;
17619 SubExprs.reserve(N: E->getNumSubExprs());
17620 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17621 SubExprs, &ArgumentChanged))
17622 return ExprError();
17623
17624 if (!getDerived().AlwaysRebuild() &&
17625 !ArgumentChanged)
17626 return E;
17627
17628 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
17629 SubExprs,
17630 E->getRParenLoc());
17631}
17632
17633template<typename Derived>
17634ExprResult
17635TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
17636 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17637 if (SrcExpr.isInvalid())
17638 return ExprError();
17639
17640 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
17641 if (!Type)
17642 return ExprError();
17643
17644 if (!getDerived().AlwaysRebuild() &&
17645 Type == E->getTypeSourceInfo() &&
17646 SrcExpr.get() == E->getSrcExpr())
17647 return E;
17648
17649 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
17650 SrcExpr.get(), Type,
17651 E->getRParenLoc());
17652}
17653
17654template<typename Derived>
17655ExprResult
17656TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
17657 BlockDecl *oldBlock = E->getBlockDecl();
17658
17659 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
17660 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
17661
17662 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
17663 blockScope->TheDecl->setBlockMissingReturnType(
17664 oldBlock->blockMissingReturnType());
17665
17666 SmallVector<ParmVarDecl*, 4> params;
17667 SmallVector<QualType, 4> paramTypes;
17668
17669 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17670
17671 // Parameter substitution.
17672 Sema::ExtParameterInfoBuilder extParamInfos;
17673 if (getDerived().TransformFunctionTypeParams(
17674 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17675 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17676 extParamInfos)) {
17677 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17678 return ExprError();
17679 }
17680
17681 QualType exprResultType =
17682 getDerived().TransformType(exprFunctionType->getReturnType());
17683
17684 auto epi = exprFunctionType->getExtProtoInfo();
17685 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17686
17687 QualType functionType =
17688 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17689 blockScope->FunctionType = functionType;
17690
17691 // Set the parameters on the block decl.
17692 if (!params.empty())
17693 blockScope->TheDecl->setParams(params);
17694
17695 if (!oldBlock->blockMissingReturnType()) {
17696 blockScope->HasImplicitReturnType = false;
17697 blockScope->ReturnType = exprResultType;
17698 }
17699
17700 // Transform the body
17701 StmtResult body = getDerived().TransformStmt(E->getBody());
17702 if (body.isInvalid()) {
17703 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17704 return ExprError();
17705 }
17706
17707#ifndef NDEBUG
17708 // In builds with assertions, make sure that we captured everything we
17709 // captured before.
17710 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17711 for (const auto &I : oldBlock->captures()) {
17712 VarDecl *oldCapture = I.getVariable();
17713
17714 // Ignore parameter packs.
17715 if (oldCapture->isParameterPack())
17716 continue;
17717
17718 VarDecl *newCapture =
17719 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17720 oldCapture));
17721 assert(blockScope->CaptureMap.count(newCapture));
17722 }
17723
17724 // The this pointer may not be captured by the instantiated block, even when
17725 // it's captured by the original block, if the expression causing the
17726 // capture is in the discarded branch of a constexpr if statement.
17727 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17728 "this pointer isn't captured in the old block");
17729 }
17730#endif
17731
17732 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17733 /*Scope=*/CurScope: nullptr);
17734}
17735
17736template<typename Derived>
17737ExprResult
17738TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17739 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17740 if (SrcExpr.isInvalid())
17741 return ExprError();
17742
17743 QualType Type = getDerived().TransformType(E->getType());
17744
17745 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17746 RParenLoc: E->getRParenLoc());
17747}
17748
17749template<typename Derived>
17750ExprResult
17751TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17752 bool ArgumentChanged = false;
17753 SmallVector<Expr*, 8> SubExprs;
17754 SubExprs.reserve(N: E->getNumSubExprs());
17755 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17756 SubExprs, &ArgumentChanged))
17757 return ExprError();
17758
17759 if (!getDerived().AlwaysRebuild() &&
17760 !ArgumentChanged)
17761 return E;
17762
17763 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17764 E->getOp(), E->getRParenLoc());
17765}
17766
17767//===----------------------------------------------------------------------===//
17768// Type reconstruction
17769//===----------------------------------------------------------------------===//
17770
17771template<typename Derived>
17772QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17773 SourceLocation Star) {
17774 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17775 Entity: getDerived().getBaseEntity());
17776}
17777
17778template<typename Derived>
17779QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17780 SourceLocation Star) {
17781 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17782 Entity: getDerived().getBaseEntity());
17783}
17784
17785template<typename Derived>
17786QualType
17787TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17788 bool WrittenAsLValue,
17789 SourceLocation Sigil) {
17790 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17791 Loc: Sigil, Entity: getDerived().getBaseEntity());
17792}
17793
17794template <typename Derived>
17795QualType TreeTransform<Derived>::RebuildMemberPointerType(
17796 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17797 SourceLocation Sigil) {
17798 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17799 Entity: getDerived().getBaseEntity());
17800}
17801
17802template<typename Derived>
17803QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17804 const ObjCTypeParamDecl *Decl,
17805 SourceLocation ProtocolLAngleLoc,
17806 ArrayRef<ObjCProtocolDecl *> Protocols,
17807 ArrayRef<SourceLocation> ProtocolLocs,
17808 SourceLocation ProtocolRAngleLoc) {
17809 return SemaRef.ObjC().BuildObjCTypeParamType(
17810 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17811 /*FailOnError=*/FailOnError: true);
17812}
17813
17814template<typename Derived>
17815QualType TreeTransform<Derived>::RebuildObjCObjectType(
17816 QualType BaseType,
17817 SourceLocation Loc,
17818 SourceLocation TypeArgsLAngleLoc,
17819 ArrayRef<TypeSourceInfo *> TypeArgs,
17820 SourceLocation TypeArgsRAngleLoc,
17821 SourceLocation ProtocolLAngleLoc,
17822 ArrayRef<ObjCProtocolDecl *> Protocols,
17823 ArrayRef<SourceLocation> ProtocolLocs,
17824 SourceLocation ProtocolRAngleLoc) {
17825 return SemaRef.ObjC().BuildObjCObjectType(
17826 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17827 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17828 /*FailOnError=*/FailOnError: true,
17829 /*Rebuilding=*/Rebuilding: true);
17830}
17831
17832template<typename Derived>
17833QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17834 QualType PointeeType,
17835 SourceLocation Star) {
17836 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17837}
17838
17839template <typename Derived>
17840QualType TreeTransform<Derived>::RebuildArrayType(
17841 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17842 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17843 if (SizeExpr || !Size)
17844 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17845 Quals: IndexTypeQuals, Brackets: BracketsRange,
17846 Entity: getDerived().getBaseEntity());
17847
17848 QualType Types[] = {
17849 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17850 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17851 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17852 };
17853 QualType SizeType;
17854 for (const auto &T : Types)
17855 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17856 SizeType = T;
17857 break;
17858 }
17859
17860 // Note that we can return a VariableArrayType here in the case where
17861 // the element type was a dependent VariableArrayType.
17862 IntegerLiteral *ArraySize
17863 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17864 /*FIXME*/l: BracketsRange.getBegin());
17865 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17866 Quals: IndexTypeQuals, Brackets: BracketsRange,
17867 Entity: getDerived().getBaseEntity());
17868}
17869
17870template <typename Derived>
17871QualType TreeTransform<Derived>::RebuildConstantArrayType(
17872 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17873 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17874 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17875 IndexTypeQuals, BracketsRange);
17876}
17877
17878template <typename Derived>
17879QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17880 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17881 SourceRange BracketsRange) {
17882 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17883 IndexTypeQuals, BracketsRange);
17884}
17885
17886template <typename Derived>
17887QualType TreeTransform<Derived>::RebuildVariableArrayType(
17888 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17889 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17890 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17891 SizeExpr,
17892 IndexTypeQuals, BracketsRange);
17893}
17894
17895template <typename Derived>
17896QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17897 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17898 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17899 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17900 SizeExpr,
17901 IndexTypeQuals, BracketsRange);
17902}
17903
17904template <typename Derived>
17905QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17906 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17907 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17908 AttrLoc: AttributeLoc);
17909}
17910
17911template <typename Derived>
17912QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17913 unsigned NumElements,
17914 VectorKind VecKind) {
17915 // FIXME: semantic checking!
17916 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17917}
17918
17919template <typename Derived>
17920QualType TreeTransform<Derived>::RebuildDependentVectorType(
17921 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17922 VectorKind VecKind) {
17923 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17924}
17925
17926template<typename Derived>
17927QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17928 unsigned NumElements,
17929 SourceLocation AttributeLoc) {
17930 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17931 NumElements, true);
17932 IntegerLiteral *VectorSize
17933 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17934 l: AttributeLoc);
17935 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17936}
17937
17938template<typename Derived>
17939QualType
17940TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17941 Expr *SizeExpr,
17942 SourceLocation AttributeLoc) {
17943 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17944}
17945
17946template <typename Derived>
17947QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17948 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17949 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17950 NumColumns);
17951}
17952
17953template <typename Derived>
17954QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17955 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17956 SourceLocation AttributeLoc) {
17957 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17958 AttrLoc: AttributeLoc);
17959}
17960
17961template <typename Derived>
17962QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17963 QualType T, MutableArrayRef<QualType> ParamTypes,
17964 const FunctionProtoType::ExtProtoInfo &EPI) {
17965 return SemaRef.BuildFunctionType(T, ParamTypes,
17966 Loc: getDerived().getBaseLocation(),
17967 Entity: getDerived().getBaseEntity(),
17968 EPI);
17969}
17970
17971template<typename Derived>
17972QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17973 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17974}
17975
17976template <typename Derived>
17977QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
17978 ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
17979 SourceLocation NameLoc, Decl *D) {
17980 assert(D && "no decl found");
17981 if (D->isInvalidDecl()) return QualType();
17982
17983 // FIXME: Doesn't account for ObjCInterfaceDecl!
17984 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17985 // A valid resolved using typename pack expansion decl can have multiple
17986 // UsingDecls, but they must each have exactly one type, and it must be
17987 // the same type in every case. But we must have at least one expansion!
17988 if (UPD->expansions().empty()) {
17989 getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
17990 << UPD->isCXXClassMember() << UPD;
17991 return QualType();
17992 }
17993
17994 // We might still have some unresolved types. Try to pick a resolved type
17995 // if we can. The final instantiation will check that the remaining
17996 // unresolved types instantiate to the type we pick.
17997 QualType FallbackT;
17998 QualType T;
17999 for (auto *E : UPD->expansions()) {
18000 QualType ThisT =
18001 RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, D: E);
18002 if (ThisT.isNull())
18003 continue;
18004 if (ThisT->getAs<UnresolvedUsingType>())
18005 FallbackT = ThisT;
18006 else if (T.isNull())
18007 T = ThisT;
18008 else
18009 assert(getSema().Context.hasSameType(ThisT, T) &&
18010 "mismatched resolved types in using pack expansion");
18011 }
18012 return T.isNull() ? FallbackT : T;
18013 }
18014 if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
18015 assert(Using->hasTypename() &&
18016 "UnresolvedUsingTypenameDecl transformed to non-typename using");
18017
18018 // A valid resolved using typename decl points to exactly one type decl.
18019 assert(++Using->shadow_begin() == Using->shadow_end());
18020
18021 UsingShadowDecl *Shadow = *Using->shadow_begin();
18022 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: NameLoc))
18023 return QualType();
18024 return SemaRef.Context.getUsingType(Keyword, Qualifier, D: Shadow);
18025 }
18026 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
18027 "UnresolvedUsingTypenameDecl transformed to non-using decl");
18028 return SemaRef.Context.getUnresolvedUsingType(
18029 Keyword, Qualifier, D: cast<UnresolvedUsingTypenameDecl>(Val: D));
18030}
18031
18032template <typename Derived>
18033QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
18034 TypeOfKind Kind) {
18035 return SemaRef.BuildTypeofExprType(E, Kind);
18036}
18037
18038template<typename Derived>
18039QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
18040 TypeOfKind Kind) {
18041 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
18042}
18043
18044template <typename Derived>
18045QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
18046 return SemaRef.BuildDecltypeType(E);
18047}
18048
18049template <typename Derived>
18050QualType TreeTransform<Derived>::RebuildPackIndexingType(
18051 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
18052 SourceLocation EllipsisLoc, bool FullySubstituted,
18053 ArrayRef<QualType> Expansions) {
18054 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
18055 FullySubstituted, Expansions);
18056}
18057
18058template<typename Derived>
18059QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
18060 UnaryTransformType::UTTKind UKind,
18061 SourceLocation Loc) {
18062 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
18063}
18064
18065template <typename Derived>
18066QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
18067 ElaboratedTypeKeyword Keyword, TemplateName Template,
18068 SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
18069 return SemaRef.CheckTemplateIdType(
18070 Keyword, Template, TemplateLoc: TemplateNameLoc, TemplateArgs,
18071 /*Scope=*/Scope: nullptr, /*ForNestedNameSpecifier=*/ForNestedNameSpecifier: false);
18072}
18073
18074template<typename Derived>
18075QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
18076 SourceLocation KWLoc) {
18077 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
18078}
18079
18080template<typename Derived>
18081QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
18082 SourceLocation KWLoc,
18083 bool isReadPipe) {
18084 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
18085 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
18086}
18087
18088template <typename Derived>
18089QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
18090 unsigned NumBits,
18091 SourceLocation Loc) {
18092 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
18093 NumBits, true);
18094 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
18095 type: SemaRef.Context.IntTy, l: Loc);
18096 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
18097}
18098
18099template <typename Derived>
18100QualType TreeTransform<Derived>::RebuildDependentBitIntType(
18101 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
18102 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
18103}
18104
18105template <typename Derived>
18106TemplateName TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18107 bool TemplateKW,
18108 TemplateName Name) {
18109 return SemaRef.Context.getQualifiedTemplateName(Qualifier: SS.getScopeRep(), TemplateKeyword: TemplateKW,
18110 Template: Name);
18111}
18112
18113template <typename Derived>
18114TemplateName TreeTransform<Derived>::RebuildTemplateName(
18115 CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
18116 SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
18117 UnqualifiedId TemplateName;
18118 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
18119 Sema::TemplateTy Template;
18120 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
18121 TemplateName, ParsedType::make(P: ObjectType),
18122 /*EnteringContext=*/false, Template,
18123 AllowInjectedClassName);
18124 return Template.get();
18125}
18126
18127template<typename Derived>
18128TemplateName
18129TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
18130 SourceLocation TemplateKWLoc,
18131 OverloadedOperatorKind Operator,
18132 SourceLocation NameLoc,
18133 QualType ObjectType,
18134 bool AllowInjectedClassName) {
18135 UnqualifiedId Name;
18136 // FIXME: Bogus location information.
18137 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
18138 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
18139 Sema::TemplateTy Template;
18140 getSema().ActOnTemplateName(
18141 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
18142 /*EnteringContext=*/false, Template, AllowInjectedClassName);
18143 return Template.get();
18144}
18145
18146template <typename Derived>
18147ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
18148 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
18149 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
18150 Expr *Second) {
18151 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
18152
18153 if (First->getObjectKind() == OK_ObjCProperty) {
18154 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18155 if (BinaryOperator::isAssignmentOp(Opc))
18156 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
18157 Opcode: Opc, LHS: First, RHS: Second);
18158 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
18159 if (Result.isInvalid())
18160 return ExprError();
18161 First = Result.get();
18162 }
18163
18164 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
18165 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
18166 if (Result.isInvalid())
18167 return ExprError();
18168 Second = Result.get();
18169 }
18170
18171 // Determine whether this should be a builtin operation.
18172 if (Op == OO_Subscript) {
18173 if (!First->getType()->isOverloadableType() &&
18174 !Second->getType()->isOverloadableType())
18175 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
18176 OpLoc);
18177 } else if (Op == OO_Arrow) {
18178 // It is possible that the type refers to a RecoveryExpr created earlier
18179 // in the tree transformation.
18180 if (First->getType()->isDependentType())
18181 return ExprError();
18182 // -> is never a builtin operation.
18183 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
18184 } else if (Second == nullptr || isPostIncDec) {
18185 if (!First->getType()->isOverloadableType() ||
18186 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
18187 // The argument is not of overloadable type, or this is an expression
18188 // of the form &Class::member, so try to create a built-in unary
18189 // operation.
18190 UnaryOperatorKind Opc
18191 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18192
18193 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
18194 }
18195 } else {
18196 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
18197 !First->getType()->isOverloadableType() &&
18198 !Second->getType()->isOverloadableType()) {
18199 // Neither of the arguments is type-dependent or has an overloadable
18200 // type, so try to create a built-in binary operation.
18201 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18202 ExprResult Result
18203 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
18204 if (Result.isInvalid())
18205 return ExprError();
18206
18207 return Result;
18208 }
18209 }
18210
18211 // Create the overloaded operator invocation for unary operators.
18212 if (!Second || isPostIncDec) {
18213 UnaryOperatorKind Opc
18214 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
18215 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
18216 RequiresADL);
18217 }
18218
18219 // Create the overloaded operator invocation for binary operators.
18220 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
18221 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
18222 LHS: First, RHS: Second, RequiresADL);
18223 if (Result.isInvalid())
18224 return ExprError();
18225
18226 return Result;
18227}
18228
18229template<typename Derived>
18230ExprResult
18231TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
18232 SourceLocation OperatorLoc,
18233 bool isArrow,
18234 CXXScopeSpec &SS,
18235 TypeSourceInfo *ScopeType,
18236 SourceLocation CCLoc,
18237 SourceLocation TildeLoc,
18238 PseudoDestructorTypeStorage Destroyed) {
18239 QualType CanonicalBaseType = Base->getType().getCanonicalType();
18240 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
18241 (!isArrow && !isa<RecordType>(Val: CanonicalBaseType)) ||
18242 (isArrow && isa<PointerType>(Val: CanonicalBaseType) &&
18243 !cast<PointerType>(Val&: CanonicalBaseType)
18244 ->getPointeeType()
18245 ->getAsCanonical<RecordType>())) {
18246 // This pseudo-destructor expression is still a pseudo-destructor.
18247 return SemaRef.BuildPseudoDestructorExpr(
18248 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
18249 CCLoc, TildeLoc, DestroyedType: Destroyed);
18250 }
18251
18252 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
18253 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
18254 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
18255 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
18256 NameInfo.setNamedTypeInfo(DestroyedType);
18257
18258 // The scope type is now known to be a valid nested name specifier
18259 // component. Tack it on to the nested name specifier.
18260 if (ScopeType) {
18261 if (!isa<TagType>(Val: ScopeType->getType().getCanonicalType())) {
18262 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
18263 diag::err_expected_class_or_namespace)
18264 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
18265 return ExprError();
18266 }
18267 SS.clear();
18268 SS.Make(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
18269 }
18270
18271 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
18272 return getSema().BuildMemberReferenceExpr(
18273 Base, Base->getType(), OperatorLoc, isArrow, SS, TemplateKWLoc,
18274 /*FIXME: FirstQualifier*/ nullptr, NameInfo,
18275 /*TemplateArgs*/ nullptr,
18276 /*S*/ nullptr);
18277}
18278
18279template<typename Derived>
18280StmtResult
18281TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
18282 SourceLocation Loc = S->getBeginLoc();
18283 CapturedDecl *CD = S->getCapturedDecl();
18284 unsigned NumParams = CD->getNumParams();
18285 unsigned ContextParamPos = CD->getContextParamPosition();
18286 SmallVector<Sema::CapturedParamNameType, 4> Params;
18287 for (unsigned I = 0; I < NumParams; ++I) {
18288 if (I != ContextParamPos) {
18289 Params.push_back(
18290 Elt: std::make_pair(
18291 CD->getParam(i: I)->getName(),
18292 getDerived().TransformType(CD->getParam(i: I)->getType())));
18293 } else {
18294 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
18295 }
18296 }
18297 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
18298 S->getCapturedRegionKind(), Params);
18299 StmtResult Body;
18300 {
18301 Sema::CompoundScopeRAII CompoundScope(getSema());
18302 Body = getDerived().TransformStmt(S->getCapturedStmt());
18303 }
18304
18305 if (Body.isInvalid()) {
18306 getSema().ActOnCapturedRegionError();
18307 return StmtError();
18308 }
18309
18310 return getSema().ActOnCapturedRegionEnd(Body.get());
18311}
18312
18313template <typename Derived>
18314StmtResult
18315TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
18316 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
18317 // function definition or instantiation of a function template specialization
18318 // and will therefore never appear in a dependent context.
18319 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
18320 "context");
18321}
18322
18323template <typename Derived>
18324ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
18325 // We can transform the base expression and allow argument resolution to fill
18326 // in the rest.
18327 return getDerived().TransformExpr(E->getArgLValue());
18328}
18329
18330} // end namespace clang
18331
18332#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
18333