1//===------- TreeTransform.h - Semantic Tree Transformation -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//===----------------------------------------------------------------------===//
7//
8// This file implements a semantic tree transformation that takes a given
9// AST and rebuilds it, possibly transforming some nodes in the process.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
14#define LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
15
16#include "CoroutineStmtBuilder.h"
17#include "TypeLocBuilder.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclObjC.h"
20#include "clang/AST/DeclTemplate.h"
21#include "clang/AST/Expr.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/ExprConcepts.h"
24#include "clang/AST/ExprObjC.h"
25#include "clang/AST/ExprOpenMP.h"
26#include "clang/AST/OpenMPClause.h"
27#include "clang/AST/Stmt.h"
28#include "clang/AST/StmtCXX.h"
29#include "clang/AST/StmtObjC.h"
30#include "clang/AST/StmtOpenACC.h"
31#include "clang/AST/StmtOpenMP.h"
32#include "clang/AST/StmtSYCL.h"
33#include "clang/Basic/DiagnosticParse.h"
34#include "clang/Basic/OpenMPKinds.h"
35#include "clang/Sema/Designator.h"
36#include "clang/Sema/EnterExpressionEvaluationContext.h"
37#include "clang/Sema/Lookup.h"
38#include "clang/Sema/Ownership.h"
39#include "clang/Sema/ParsedTemplate.h"
40#include "clang/Sema/ScopeInfo.h"
41#include "clang/Sema/SemaDiagnostic.h"
42#include "clang/Sema/SemaInternal.h"
43#include "clang/Sema/SemaObjC.h"
44#include "clang/Sema/SemaOpenACC.h"
45#include "clang/Sema/SemaOpenMP.h"
46#include "clang/Sema/SemaPseudoObject.h"
47#include "clang/Sema/SemaSYCL.h"
48#include "llvm/ADT/ArrayRef.h"
49#include "llvm/Support/ErrorHandling.h"
50#include <algorithm>
51#include <optional>
52
53using namespace llvm::omp;
54
55namespace clang {
56using namespace sema;
57
58/// A semantic tree transformation that allows one to transform one
59/// abstract syntax tree into another.
60///
61/// A new tree transformation is defined by creating a new subclass \c X of
62/// \c TreeTransform<X> and then overriding certain operations to provide
63/// behavior specific to that transformation. For example, template
64/// instantiation is implemented as a tree transformation where the
65/// transformation of TemplateTypeParmType nodes involves substituting the
66/// template arguments for their corresponding template parameters; a similar
67/// transformation is performed for non-type template parameters and
68/// template template parameters.
69///
70/// This tree-transformation template uses static polymorphism to allow
71/// subclasses to customize any of its operations. Thus, a subclass can
72/// override any of the transformation or rebuild operators by providing an
73/// operation with the same signature as the default implementation. The
74/// overriding function should not be virtual.
75///
76/// Semantic tree transformations are split into two stages, either of which
77/// can be replaced by a subclass. The "transform" step transforms an AST node
78/// or the parts of an AST node using the various transformation functions,
79/// then passes the pieces on to the "rebuild" step, which constructs a new AST
80/// node of the appropriate kind from the pieces. The default transformation
81/// routines recursively transform the operands to composite AST nodes (e.g.,
82/// the pointee type of a PointerType node) and, if any of those operand nodes
83/// were changed by the transformation, invokes the rebuild operation to create
84/// a new AST node.
85///
86/// Subclasses can customize the transformation at various levels. The
87/// most coarse-grained transformations involve replacing TransformType(),
88/// TransformExpr(), TransformDecl(), TransformNestedNameSpecifierLoc(),
89/// TransformTemplateName(), or TransformTemplateArgument() with entirely
90/// new implementations.
91///
92/// For more fine-grained transformations, subclasses can replace any of the
93/// \c TransformXXX functions (where XXX is the name of an AST node, e.g.,
94/// PointerType, StmtExpr) to alter the transformation. As mentioned previously,
95/// replacing TransformTemplateTypeParmType() allows template instantiation
96/// to substitute template arguments for their corresponding template
97/// parameters. Additionally, subclasses can override the \c RebuildXXX
98/// functions to control how AST nodes are rebuilt when their operands change.
99/// By default, \c TreeTransform will invoke semantic analysis to rebuild
100/// AST nodes. However, certain other tree transformations (e.g, cloning) may
101/// be able to use more efficient rebuild steps.
102///
103/// There are a handful of other functions that can be overridden, allowing one
104/// to avoid traversing nodes that don't need any transformation
105/// (\c AlreadyTransformed()), force rebuilding AST nodes even when their
106/// operands have not changed (\c AlwaysRebuild()), and customize the
107/// default locations and entity names used for type-checking
108/// (\c getBaseLocation(), \c getBaseEntity()).
109template<typename Derived>
110class TreeTransform {
111 /// Private RAII object that helps us forget and then re-remember
112 /// the template argument corresponding to a partially-substituted parameter
113 /// pack.
114 class ForgetPartiallySubstitutedPackRAII {
115 Derived &Self;
116 TemplateArgument Old;
117 // Set the pack expansion index to -1 to avoid pack substitution and
118 // indicate that parameter packs should be instantiated as themselves.
119 Sema::ArgPackSubstIndexRAII ResetPackSubstIndex;
120
121 public:
122 ForgetPartiallySubstitutedPackRAII(Derived &Self)
123 : Self(Self), ResetPackSubstIndex(Self.getSema(), std::nullopt) {
124 Old = Self.ForgetPartiallySubstitutedPack();
125 }
126
127 ~ForgetPartiallySubstitutedPackRAII() {
128 Self.RememberPartiallySubstitutedPack(Old);
129 }
130 };
131
132protected:
133 Sema &SemaRef;
134
135 /// The set of local declarations that have been transformed, for
136 /// cases where we are forced to build new declarations within the transformer
137 /// rather than in the subclass (e.g., lambda closure types).
138 llvm::DenseMap<Decl *, Decl *> TransformedLocalDecls;
139
140public:
141 /// Initializes a new tree transformer.
142 TreeTransform(Sema &SemaRef) : SemaRef(SemaRef) { }
143
144 /// Retrieves a reference to the derived class.
145 Derived &getDerived() { return static_cast<Derived&>(*this); }
146
147 /// Retrieves a reference to the derived class.
148 const Derived &getDerived() const {
149 return static_cast<const Derived&>(*this);
150 }
151
152 static inline ExprResult Owned(Expr *E) { return E; }
153 static inline StmtResult Owned(Stmt *S) { return S; }
154
155 /// Retrieves a reference to the semantic analysis object used for
156 /// this tree transform.
157 Sema &getSema() const { return SemaRef; }
158
159 /// Whether the transformation should always rebuild AST nodes, even
160 /// if none of the children have changed.
161 ///
162 /// Subclasses may override this function to specify when the transformation
163 /// should rebuild all AST nodes.
164 ///
165 /// We must always rebuild all AST nodes when performing variadic template
166 /// pack expansion, in order to avoid violating the AST invariant that each
167 /// statement node appears at most once in its containing declaration.
168 bool AlwaysRebuild() { return static_cast<bool>(SemaRef.ArgPackSubstIndex); }
169
170 /// Whether the transformation is forming an expression or statement that
171 /// replaces the original. In this case, we'll reuse mangling numbers from
172 /// existing lambdas.
173 bool ReplacingOriginal() { return false; }
174
175 /// Wether CXXConstructExpr can be skipped when they are implicit.
176 /// They will be reconstructed when used if needed.
177 /// This is useful when the user that cause rebuilding of the
178 /// CXXConstructExpr is outside of the expression at which the TreeTransform
179 /// started.
180 bool AllowSkippingCXXConstructExpr() { return true; }
181
182 /// Returns the location of the entity being transformed, if that
183 /// information was not available elsewhere in the AST.
184 ///
185 /// By default, returns no source-location information. Subclasses can
186 /// provide an alternative implementation that provides better location
187 /// information.
188 SourceLocation getBaseLocation() { return SourceLocation(); }
189
190 /// Returns the name of the entity being transformed, if that
191 /// information was not available elsewhere in the AST.
192 ///
193 /// By default, returns an empty name. Subclasses can provide an alternative
194 /// implementation with a more precise name.
195 DeclarationName getBaseEntity() { return DeclarationName(); }
196
197 /// Sets the "base" location and entity when that
198 /// information is known based on another transformation.
199 ///
200 /// By default, the source location and entity are ignored. Subclasses can
201 /// override this function to provide a customized implementation.
202 void setBase(SourceLocation Loc, DeclarationName Entity) { }
203
204 /// RAII object that temporarily sets the base location and entity
205 /// used for reporting diagnostics in types.
206 class TemporaryBase {
207 TreeTransform &Self;
208 SourceLocation OldLocation;
209 DeclarationName OldEntity;
210
211 public:
212 TemporaryBase(TreeTransform &Self, SourceLocation Location,
213 DeclarationName Entity) : Self(Self) {
214 OldLocation = Self.getDerived().getBaseLocation();
215 OldEntity = Self.getDerived().getBaseEntity();
216
217 if (Location.isValid())
218 Self.getDerived().setBase(Location, Entity);
219 }
220
221 ~TemporaryBase() {
222 Self.getDerived().setBase(OldLocation, OldEntity);
223 }
224 };
225
226 /// Determine whether the given type \p T has already been
227 /// transformed.
228 ///
229 /// Subclasses can provide an alternative implementation of this routine
230 /// to short-circuit evaluation when it is known that a given type will
231 /// not change. For example, template instantiation need not traverse
232 /// non-dependent types.
233 bool AlreadyTransformed(QualType T) {
234 return T.isNull();
235 }
236
237 /// Transform a template parameter depth level.
238 ///
239 /// During a transformation that transforms template parameters, this maps
240 /// an old template parameter depth to a new depth.
241 unsigned TransformTemplateDepth(unsigned Depth) {
242 return Depth;
243 }
244
245 /// Determine whether the given call argument should be dropped, e.g.,
246 /// because it is a default argument.
247 ///
248 /// Subclasses can provide an alternative implementation of this routine to
249 /// determine which kinds of call arguments get dropped. By default,
250 /// CXXDefaultArgument nodes are dropped (prior to transformation).
251 bool DropCallArgument(Expr *E) {
252 return E->isDefaultArgument();
253 }
254
255 /// Determine whether we should expand a pack expansion with the
256 /// given set of parameter packs into separate arguments by repeatedly
257 /// transforming the pattern.
258 ///
259 /// By default, the transformer never tries to expand pack expansions.
260 /// Subclasses can override this routine to provide different behavior.
261 ///
262 /// \param EllipsisLoc The location of the ellipsis that identifies the
263 /// pack expansion.
264 ///
265 /// \param PatternRange The source range that covers the entire pattern of
266 /// the pack expansion.
267 ///
268 /// \param Unexpanded The set of unexpanded parameter packs within the
269 /// pattern.
270 ///
271 /// \param ShouldExpand Will be set to \c true if the transformer should
272 /// expand the corresponding pack expansions into separate arguments. When
273 /// set, \c NumExpansions must also be set.
274 ///
275 /// \param RetainExpansion Whether the caller should add an unexpanded
276 /// pack expansion after all of the expanded arguments. This is used
277 /// when extending explicitly-specified template argument packs per
278 /// C++0x [temp.arg.explicit]p9.
279 ///
280 /// \param NumExpansions The number of separate arguments that will be in
281 /// the expanded form of the corresponding pack expansion. This is both an
282 /// input and an output parameter, which can be set by the caller if the
283 /// number of expansions is known a priori (e.g., due to a prior substitution)
284 /// and will be set by the callee when the number of expansions is known.
285 /// The callee must set this value when \c ShouldExpand is \c true; it may
286 /// set this value in other cases.
287 ///
288 /// \returns true if an error occurred (e.g., because the parameter packs
289 /// are to be instantiated with arguments of different lengths), false
290 /// otherwise. If false, \c ShouldExpand (and possibly \c NumExpansions)
291 /// must be set.
292 bool TryExpandParameterPacks(SourceLocation EllipsisLoc,
293 SourceRange PatternRange,
294 ArrayRef<UnexpandedParameterPack> Unexpanded,
295 bool &ShouldExpand, bool &RetainExpansion,
296 UnsignedOrNone &NumExpansions) {
297 ShouldExpand = false;
298 return false;
299 }
300
301 /// "Forget" about the partially-substituted pack template argument,
302 /// when performing an instantiation that must preserve the parameter pack
303 /// use.
304 ///
305 /// This routine is meant to be overridden by the template instantiator.
306 TemplateArgument ForgetPartiallySubstitutedPack() {
307 return TemplateArgument();
308 }
309
310 /// "Remember" the partially-substituted pack template argument
311 /// after performing an instantiation that must preserve the parameter pack
312 /// use.
313 ///
314 /// This routine is meant to be overridden by the template instantiator.
315 void RememberPartiallySubstitutedPack(TemplateArgument Arg) { }
316
317 /// Note to the derived class when a function parameter pack is
318 /// being expanded.
319 void ExpandingFunctionParameterPack(ParmVarDecl *Pack) { }
320
321 /// Transforms the given type into another type.
322 ///
323 /// By default, this routine transforms a type by creating a
324 /// TypeSourceInfo for it and delegating to the appropriate
325 /// function. This is expensive, but we don't mind, because
326 /// this method is deprecated anyway; all users should be
327 /// switched to storing TypeSourceInfos.
328 ///
329 /// \returns the transformed type.
330 QualType TransformType(QualType T);
331
332 /// Transforms the given type-with-location into a new
333 /// type-with-location.
334 ///
335 /// By default, this routine transforms a type by delegating to the
336 /// appropriate TransformXXXType to build a new type. Subclasses
337 /// may override this function (to take over all type
338 /// transformations) or some set of the TransformXXXType functions
339 /// to alter the transformation.
340 TypeSourceInfo *TransformType(TypeSourceInfo *DI);
341
342 /// Transform the given type-with-location into a new
343 /// type, collecting location information in the given builder
344 /// as necessary.
345 ///
346 QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
347
348 /// Transform a type that is permitted to produce a
349 /// DeducedTemplateSpecializationType.
350 ///
351 /// This is used in the (relatively rare) contexts where it is acceptable
352 /// for transformation to produce a class template type with deduced
353 /// template arguments.
354 /// @{
355 QualType TransformTypeWithDeducedTST(QualType T);
356 TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
357 /// @}
358
359 /// The reason why the value of a statement is not discarded, if any.
360 enum class StmtDiscardKind {
361 Discarded,
362 NotDiscarded,
363 StmtExprResult,
364 };
365
366 /// Transform the given statement.
367 ///
368 /// By default, this routine transforms a statement by delegating to the
369 /// appropriate TransformXXXStmt function to transform a specific kind of
370 /// statement or the TransformExpr() function to transform an expression.
371 /// Subclasses may override this function to transform statements using some
372 /// other mechanism.
373 ///
374 /// \returns the transformed statement.
375 StmtResult TransformStmt(Stmt *S,
376 StmtDiscardKind SDK = StmtDiscardKind::Discarded);
377
378 /// Transform the given statement.
379 ///
380 /// By default, this routine transforms a statement by delegating to the
381 /// appropriate TransformOMPXXXClause function to transform a specific kind
382 /// of clause. Subclasses may override this function to transform statements
383 /// using some other mechanism.
384 ///
385 /// \returns the transformed OpenMP clause.
386 OMPClause *TransformOMPClause(OMPClause *S);
387
388 /// Transform the given attribute.
389 ///
390 /// By default, this routine transforms a statement by delegating to the
391 /// appropriate TransformXXXAttr function to transform a specific kind
392 /// of attribute. Subclasses may override this function to transform
393 /// attributed statements/types using some other mechanism.
394 ///
395 /// \returns the transformed attribute
396 const Attr *TransformAttr(const Attr *S);
397
398 // Transform the given statement attribute.
399 //
400 // Delegates to the appropriate TransformXXXAttr function to transform a
401 // specific kind of statement attribute. Unlike the non-statement taking
402 // version of this, this implements all attributes, not just pragmas.
403 const Attr *TransformStmtAttr(const Stmt *OrigS, const Stmt *InstS,
404 const Attr *A);
405
406 // Transform the specified attribute.
407 //
408 // Subclasses should override the transformation of attributes with a pragma
409 // spelling to transform expressions stored within the attribute.
410 //
411 // \returns the transformed attribute.
412#define ATTR(X) \
413 const X##Attr *Transform##X##Attr(const X##Attr *R) { return R; }
414#include "clang/Basic/AttrList.inc"
415
416 // Transform the specified attribute.
417 //
418 // Subclasses should override the transformation of attributes to do
419 // transformation and checking of statement attributes. By default, this
420 // delegates to the non-statement taking version.
421 //
422 // \returns the transformed attribute.
423#define ATTR(X) \
424 const X##Attr *TransformStmt##X##Attr(const Stmt *, const Stmt *, \
425 const X##Attr *A) { \
426 return getDerived().Transform##X##Attr(A); \
427 }
428#include "clang/Basic/AttrList.inc"
429
430 /// Transform the given expression.
431 ///
432 /// By default, this routine transforms an expression by delegating to the
433 /// appropriate TransformXXXExpr function to build a new expression.
434 /// Subclasses may override this function to transform expressions using some
435 /// other mechanism.
436 ///
437 /// \returns the transformed expression.
438 ExprResult TransformExpr(Expr *E);
439
440 /// Transform the given initializer.
441 ///
442 /// By default, this routine transforms an initializer by stripping off the
443 /// semantic nodes added by initialization, then passing the result to
444 /// TransformExpr or TransformExprs.
445 ///
446 /// \returns the transformed initializer.
447 ExprResult TransformInitializer(Expr *Init, bool NotCopyInit);
448
449 /// Transform the given list of expressions.
450 ///
451 /// This routine transforms a list of expressions by invoking
452 /// \c TransformExpr() for each subexpression. However, it also provides
453 /// support for variadic templates by expanding any pack expansions (if the
454 /// derived class permits such expansion) along the way. When pack expansions
455 /// are present, the number of outputs may not equal the number of inputs.
456 ///
457 /// \param Inputs The set of expressions to be transformed.
458 ///
459 /// \param NumInputs The number of expressions in \c Inputs.
460 ///
461 /// \param IsCall If \c true, then this transform is being performed on
462 /// function-call arguments, and any arguments that should be dropped, will
463 /// be.
464 ///
465 /// \param Outputs The transformed input expressions will be added to this
466 /// vector.
467 ///
468 /// \param ArgChanged If non-NULL, will be set \c true if any argument changed
469 /// due to transformation.
470 ///
471 /// \returns true if an error occurred, false otherwise.
472 bool TransformExprs(Expr *const *Inputs, unsigned NumInputs, bool IsCall,
473 SmallVectorImpl<Expr *> &Outputs,
474 bool *ArgChanged = nullptr);
475
476 /// Transform the given declaration, which is referenced from a type
477 /// or expression.
478 ///
479 /// By default, acts as the identity function on declarations, unless the
480 /// transformer has had to transform the declaration itself. Subclasses
481 /// may override this function to provide alternate behavior.
482 Decl *TransformDecl(SourceLocation Loc, Decl *D) {
483 llvm::DenseMap<Decl *, Decl *>::iterator Known
484 = TransformedLocalDecls.find(Val: D);
485 if (Known != TransformedLocalDecls.end())
486 return Known->second;
487
488 return D;
489 }
490
491 /// Transform the specified condition.
492 ///
493 /// By default, this transforms the variable and expression and rebuilds
494 /// the condition.
495 Sema::ConditionResult TransformCondition(SourceLocation Loc, VarDecl *Var,
496 Expr *Expr,
497 Sema::ConditionKind Kind);
498
499 /// Transform the attributes associated with the given declaration and
500 /// place them on the new declaration.
501 ///
502 /// By default, this operation does nothing. Subclasses may override this
503 /// behavior to transform attributes.
504 void transformAttrs(Decl *Old, Decl *New) { }
505
506 /// Note that a local declaration has been transformed by this
507 /// transformer.
508 ///
509 /// Local declarations are typically transformed via a call to
510 /// TransformDefinition. However, in some cases (e.g., lambda expressions),
511 /// the transformer itself has to transform the declarations. This routine
512 /// can be overridden by a subclass that keeps track of such mappings.
513 void transformedLocalDecl(Decl *Old, ArrayRef<Decl *> New) {
514 assert(New.size() == 1 &&
515 "must override transformedLocalDecl if performing pack expansion");
516 TransformedLocalDecls[Old] = New.front();
517 }
518
519 /// Transform the definition of the given declaration.
520 ///
521 /// By default, invokes TransformDecl() to transform the declaration.
522 /// Subclasses may override this function to provide alternate behavior.
523 Decl *TransformDefinition(SourceLocation Loc, Decl *D) {
524 return getDerived().TransformDecl(Loc, D);
525 }
526
527 /// Transform the given declaration, which was the first part of a
528 /// nested-name-specifier in a member access expression.
529 ///
530 /// This specific declaration transformation only applies to the first
531 /// identifier in a nested-name-specifier of a member access expression, e.g.,
532 /// the \c T in \c x->T::member
533 ///
534 /// By default, invokes TransformDecl() to transform the declaration.
535 /// Subclasses may override this function to provide alternate behavior.
536 NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) {
537 return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D));
538 }
539
540 /// Transform the set of declarations in an OverloadExpr.
541 bool TransformOverloadExprDecls(OverloadExpr *Old, bool RequiresADL,
542 LookupResult &R);
543
544 /// Transform the given nested-name-specifier with source-location
545 /// information.
546 ///
547 /// By default, transforms all of the types and declarations within the
548 /// nested-name-specifier. Subclasses may override this function to provide
549 /// alternate behavior.
550 NestedNameSpecifierLoc
551 TransformNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
552 QualType ObjectType = QualType(),
553 NamedDecl *FirstQualifierInScope = nullptr);
554
555 /// Transform the given declaration name.
556 ///
557 /// By default, transforms the types of conversion function, constructor,
558 /// and destructor names and then (if needed) rebuilds the declaration name.
559 /// Identifiers and selectors are returned unmodified. Subclasses may
560 /// override this function to provide alternate behavior.
561 DeclarationNameInfo
562 TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo);
563
564 bool TransformRequiresExprRequirements(
565 ArrayRef<concepts::Requirement *> Reqs,
566 llvm::SmallVectorImpl<concepts::Requirement *> &Transformed);
567 concepts::TypeRequirement *
568 TransformTypeRequirement(concepts::TypeRequirement *Req);
569 concepts::ExprRequirement *
570 TransformExprRequirement(concepts::ExprRequirement *Req);
571 concepts::NestedRequirement *
572 TransformNestedRequirement(concepts::NestedRequirement *Req);
573
574 /// Transform the given template name.
575 ///
576 /// \param SS The nested-name-specifier that qualifies the template
577 /// name. This nested-name-specifier must already have been transformed.
578 ///
579 /// \param Name The template name to transform.
580 ///
581 /// \param NameLoc The source location of the template name.
582 ///
583 /// \param ObjectType If we're translating a template name within a member
584 /// access expression, this is the type of the object whose member template
585 /// is being referenced.
586 ///
587 /// \param FirstQualifierInScope If the first part of a nested-name-specifier
588 /// also refers to a name within the current (lexical) scope, this is the
589 /// declaration it refers to.
590 ///
591 /// By default, transforms the template name by transforming the declarations
592 /// and nested-name-specifiers that occur within the template name.
593 /// Subclasses may override this function to provide alternate behavior.
594 TemplateName
595 TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
596 SourceLocation NameLoc,
597 QualType ObjectType = QualType(),
598 NamedDecl *FirstQualifierInScope = nullptr,
599 bool AllowInjectedClassName = false);
600
601 /// Transform the given template argument.
602 ///
603 /// By default, this operation transforms the type, expression, or
604 /// declaration stored within the template argument and constructs a
605 /// new template argument from the transformed result. Subclasses may
606 /// override this function to provide alternate behavior.
607 ///
608 /// Returns true if there was an error.
609 bool TransformTemplateArgument(const TemplateArgumentLoc &Input,
610 TemplateArgumentLoc &Output,
611 bool Uneval = false);
612
613 /// Transform the given set of template arguments.
614 ///
615 /// By default, this operation transforms all of the template arguments
616 /// in the input set using \c TransformTemplateArgument(), and appends
617 /// the transformed arguments to the output list.
618 ///
619 /// Note that this overload of \c TransformTemplateArguments() is merely
620 /// a convenience function. Subclasses that wish to override this behavior
621 /// should override the iterator-based member template version.
622 ///
623 /// \param Inputs The set of template arguments to be transformed.
624 ///
625 /// \param NumInputs The number of template arguments in \p Inputs.
626 ///
627 /// \param Outputs The set of transformed template arguments output by this
628 /// routine.
629 ///
630 /// Returns true if an error occurred.
631 bool TransformTemplateArguments(const TemplateArgumentLoc *Inputs,
632 unsigned NumInputs,
633 TemplateArgumentListInfo &Outputs,
634 bool Uneval = false) {
635 return TransformTemplateArguments(Inputs, Inputs + NumInputs, Outputs,
636 Uneval);
637 }
638
639 /// Transform the given set of template arguments.
640 ///
641 /// By default, this operation transforms all of the template arguments
642 /// in the input set using \c TransformTemplateArgument(), and appends
643 /// the transformed arguments to the output list.
644 ///
645 /// \param First An iterator to the first template argument.
646 ///
647 /// \param Last An iterator one step past the last template argument.
648 ///
649 /// \param Outputs The set of transformed template arguments output by this
650 /// routine.
651 ///
652 /// Returns true if an error occurred.
653 template<typename InputIterator>
654 bool TransformTemplateArguments(InputIterator First,
655 InputIterator Last,
656 TemplateArgumentListInfo &Outputs,
657 bool Uneval = false);
658
659 /// Fakes up a TemplateArgumentLoc for a given TemplateArgument.
660 void InventTemplateArgumentLoc(const TemplateArgument &Arg,
661 TemplateArgumentLoc &ArgLoc);
662
663 /// Fakes up a TypeSourceInfo for a type.
664 TypeSourceInfo *InventTypeSourceInfo(QualType T) {
665 return SemaRef.Context.getTrivialTypeSourceInfo(T,
666 Loc: getDerived().getBaseLocation());
667 }
668
669#define ABSTRACT_TYPELOC(CLASS, PARENT)
670#define TYPELOC(CLASS, PARENT) \
671 QualType Transform##CLASS##Type(TypeLocBuilder &TLB, CLASS##TypeLoc T);
672#include "clang/AST/TypeLocNodes.def"
673
674 QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
675 TemplateTypeParmTypeLoc TL,
676 bool SuppressObjCLifetime);
677 QualType
678 TransformSubstTemplateTypeParmPackType(TypeLocBuilder &TLB,
679 SubstTemplateTypeParmPackTypeLoc TL,
680 bool SuppressObjCLifetime);
681
682 template<typename Fn>
683 QualType TransformFunctionProtoType(TypeLocBuilder &TLB,
684 FunctionProtoTypeLoc TL,
685 CXXRecordDecl *ThisContext,
686 Qualifiers ThisTypeQuals,
687 Fn TransformExceptionSpec);
688
689 bool TransformExceptionSpec(SourceLocation Loc,
690 FunctionProtoType::ExceptionSpecInfo &ESI,
691 SmallVectorImpl<QualType> &Exceptions,
692 bool &Changed);
693
694 StmtResult TransformSEHHandler(Stmt *Handler);
695
696 QualType
697 TransformTemplateSpecializationType(TypeLocBuilder &TLB,
698 TemplateSpecializationTypeLoc TL,
699 TemplateName Template);
700
701 QualType
702 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
703 DependentTemplateSpecializationTypeLoc TL,
704 TemplateName Template,
705 CXXScopeSpec &SS);
706
707 QualType TransformDependentTemplateSpecializationType(
708 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
709 CXXScopeSpec &SS);
710
711 /// Transforms the parameters of a function type into the
712 /// given vectors.
713 ///
714 /// The result vectors should be kept in sync; null entries in the
715 /// variables vector are acceptable.
716 ///
717 /// LastParamTransformed, if non-null, will be set to the index of the last
718 /// parameter on which transformation was started. In the event of an error,
719 /// this will contain the parameter which failed to instantiate.
720 ///
721 /// Return true on error.
722 bool TransformFunctionTypeParams(
723 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
724 const QualType *ParamTypes,
725 const FunctionProtoType::ExtParameterInfo *ParamInfos,
726 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
727 Sema::ExtParameterInfoBuilder &PInfos, unsigned *LastParamTransformed);
728
729 bool TransformFunctionTypeParams(
730 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
731 const QualType *ParamTypes,
732 const FunctionProtoType::ExtParameterInfo *ParamInfos,
733 SmallVectorImpl<QualType> &PTypes, SmallVectorImpl<ParmVarDecl *> *PVars,
734 Sema::ExtParameterInfoBuilder &PInfos) {
735 return getDerived().TransformFunctionTypeParams(
736 Loc, Params, ParamTypes, ParamInfos, PTypes, PVars, PInfos, nullptr);
737 }
738
739 /// Transforms the parameters of a requires expresison into the given vectors.
740 ///
741 /// The result vectors should be kept in sync; null entries in the
742 /// variables vector are acceptable.
743 ///
744 /// Returns an unset ExprResult on success. Returns an ExprResult the 'not
745 /// satisfied' RequiresExpr if subsitution failed, OR an ExprError, both of
746 /// which are cases where transformation shouldn't continue.
747 ExprResult TransformRequiresTypeParams(
748 SourceLocation KWLoc, SourceLocation RBraceLoc, const RequiresExpr *RE,
749 RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> Params,
750 SmallVectorImpl<QualType> &PTypes,
751 SmallVectorImpl<ParmVarDecl *> &TransParams,
752 Sema::ExtParameterInfoBuilder &PInfos) {
753 if (getDerived().TransformFunctionTypeParams(
754 KWLoc, Params, /*ParamTypes=*/nullptr,
755 /*ParamInfos=*/nullptr, PTypes, &TransParams, PInfos))
756 return ExprError();
757
758 return ExprResult{};
759 }
760
761 /// Transforms a single function-type parameter. Return null
762 /// on error.
763 ///
764 /// \param indexAdjustment - A number to add to the parameter's
765 /// scope index; can be negative
766 ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm,
767 int indexAdjustment,
768 UnsignedOrNone NumExpansions,
769 bool ExpectParameterPack);
770
771 /// Transform the body of a lambda-expression.
772 StmtResult TransformLambdaBody(LambdaExpr *E, Stmt *Body);
773 /// Alternative implementation of TransformLambdaBody that skips transforming
774 /// the body.
775 StmtResult SkipLambdaBody(LambdaExpr *E, Stmt *Body);
776
777 CXXRecordDecl::LambdaDependencyKind
778 ComputeLambdaDependency(LambdaScopeInfo *LSI) {
779 return static_cast<CXXRecordDecl::LambdaDependencyKind>(
780 LSI->Lambda->getLambdaDependencyKind());
781 }
782
783 QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
784
785 StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
786 ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
787
788 TemplateParameterList *TransformTemplateParameterList(
789 TemplateParameterList *TPL) {
790 return TPL;
791 }
792
793 ExprResult TransformAddressOfOperand(Expr *E);
794
795 ExprResult TransformDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E,
796 bool IsAddressOfOperand,
797 TypeSourceInfo **RecoveryTSI);
798
799 ExprResult TransformParenDependentScopeDeclRefExpr(
800 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool IsAddressOfOperand,
801 TypeSourceInfo **RecoveryTSI);
802
803 ExprResult TransformUnresolvedLookupExpr(UnresolvedLookupExpr *E,
804 bool IsAddressOfOperand);
805
806 StmtResult TransformOMPExecutableDirective(OMPExecutableDirective *S);
807
808 StmtResult TransformOMPInformationalDirective(OMPExecutableDirective *S);
809
810// FIXME: We use LLVM_ATTRIBUTE_NOINLINE because inlining causes a ridiculous
811// amount of stack usage with clang.
812#define STMT(Node, Parent) \
813 LLVM_ATTRIBUTE_NOINLINE \
814 StmtResult Transform##Node(Node *S);
815#define VALUESTMT(Node, Parent) \
816 LLVM_ATTRIBUTE_NOINLINE \
817 StmtResult Transform##Node(Node *S, StmtDiscardKind SDK);
818#define EXPR(Node, Parent) \
819 LLVM_ATTRIBUTE_NOINLINE \
820 ExprResult Transform##Node(Node *E);
821#define ABSTRACT_STMT(Stmt)
822#include "clang/AST/StmtNodes.inc"
823
824#define GEN_CLANG_CLAUSE_CLASS
825#define CLAUSE_CLASS(Enum, Str, Class) \
826 LLVM_ATTRIBUTE_NOINLINE \
827 OMPClause *Transform##Class(Class *S);
828#include "llvm/Frontend/OpenMP/OMP.inc"
829
830 /// Build a new qualified type given its unqualified type and type location.
831 ///
832 /// By default, this routine adds type qualifiers only to types that can
833 /// have qualifiers, and silently suppresses those qualifiers that are not
834 /// permitted. Subclasses may override this routine to provide different
835 /// behavior.
836 QualType RebuildQualifiedType(QualType T, QualifiedTypeLoc TL);
837
838 /// Build a new pointer type given its pointee type.
839 ///
840 /// By default, performs semantic analysis when building the pointer type.
841 /// Subclasses may override this routine to provide different behavior.
842 QualType RebuildPointerType(QualType PointeeType, SourceLocation Sigil);
843
844 /// Build a new block pointer type given its pointee type.
845 ///
846 /// By default, performs semantic analysis when building the block pointer
847 /// type. Subclasses may override this routine to provide different behavior.
848 QualType RebuildBlockPointerType(QualType PointeeType, SourceLocation Sigil);
849
850 /// Build a new reference type given the type it references.
851 ///
852 /// By default, performs semantic analysis when building the
853 /// reference type. Subclasses may override this routine to provide
854 /// different behavior.
855 ///
856 /// \param LValue whether the type was written with an lvalue sigil
857 /// or an rvalue sigil.
858 QualType RebuildReferenceType(QualType ReferentType,
859 bool LValue,
860 SourceLocation Sigil);
861
862 /// Build a new member pointer type given the pointee type and the
863 /// qualifier it refers into.
864 ///
865 /// By default, performs semantic analysis when building the member pointer
866 /// type. Subclasses may override this routine to provide different behavior.
867 QualType RebuildMemberPointerType(QualType PointeeType,
868 const CXXScopeSpec &SS, CXXRecordDecl *Cls,
869 SourceLocation Sigil);
870
871 QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
872 SourceLocation ProtocolLAngleLoc,
873 ArrayRef<ObjCProtocolDecl *> Protocols,
874 ArrayRef<SourceLocation> ProtocolLocs,
875 SourceLocation ProtocolRAngleLoc);
876
877 /// Build an Objective-C object type.
878 ///
879 /// By default, performs semantic analysis when building the object type.
880 /// Subclasses may override this routine to provide different behavior.
881 QualType RebuildObjCObjectType(QualType BaseType,
882 SourceLocation Loc,
883 SourceLocation TypeArgsLAngleLoc,
884 ArrayRef<TypeSourceInfo *> TypeArgs,
885 SourceLocation TypeArgsRAngleLoc,
886 SourceLocation ProtocolLAngleLoc,
887 ArrayRef<ObjCProtocolDecl *> Protocols,
888 ArrayRef<SourceLocation> ProtocolLocs,
889 SourceLocation ProtocolRAngleLoc);
890
891 /// Build a new Objective-C object pointer type given the pointee type.
892 ///
893 /// By default, directly builds the pointer type, with no additional semantic
894 /// analysis.
895 QualType RebuildObjCObjectPointerType(QualType PointeeType,
896 SourceLocation Star);
897
898 /// Build a new array type given the element type, size
899 /// modifier, size of the array (if known), size expression, and index type
900 /// qualifiers.
901 ///
902 /// By default, performs semantic analysis when building the array type.
903 /// Subclasses may override this routine to provide different behavior.
904 /// Also by default, all of the other Rebuild*Array
905 QualType RebuildArrayType(QualType ElementType, ArraySizeModifier SizeMod,
906 const llvm::APInt *Size, Expr *SizeExpr,
907 unsigned IndexTypeQuals, SourceRange BracketsRange);
908
909 /// Build a new constant array type given the element type, size
910 /// modifier, (known) size of the array, and index type qualifiers.
911 ///
912 /// By default, performs semantic analysis when building the array type.
913 /// Subclasses may override this routine to provide different behavior.
914 QualType RebuildConstantArrayType(QualType ElementType,
915 ArraySizeModifier SizeMod,
916 const llvm::APInt &Size, Expr *SizeExpr,
917 unsigned IndexTypeQuals,
918 SourceRange BracketsRange);
919
920 /// Build a new incomplete array type given the element type, size
921 /// modifier, and index type qualifiers.
922 ///
923 /// By default, performs semantic analysis when building the array type.
924 /// Subclasses may override this routine to provide different behavior.
925 QualType RebuildIncompleteArrayType(QualType ElementType,
926 ArraySizeModifier SizeMod,
927 unsigned IndexTypeQuals,
928 SourceRange BracketsRange);
929
930 /// Build a new variable-length array type given the element type,
931 /// size modifier, size expression, and index type qualifiers.
932 ///
933 /// By default, performs semantic analysis when building the array type.
934 /// Subclasses may override this routine to provide different behavior.
935 QualType RebuildVariableArrayType(QualType ElementType,
936 ArraySizeModifier SizeMod, Expr *SizeExpr,
937 unsigned IndexTypeQuals,
938 SourceRange BracketsRange);
939
940 /// Build a new dependent-sized array type given the element type,
941 /// size modifier, size expression, and index type qualifiers.
942 ///
943 /// By default, performs semantic analysis when building the array type.
944 /// Subclasses may override this routine to provide different behavior.
945 QualType RebuildDependentSizedArrayType(QualType ElementType,
946 ArraySizeModifier SizeMod,
947 Expr *SizeExpr,
948 unsigned IndexTypeQuals,
949 SourceRange BracketsRange);
950
951 /// Build a new vector type given the element type and
952 /// number of elements.
953 ///
954 /// By default, performs semantic analysis when building the vector type.
955 /// Subclasses may override this routine to provide different behavior.
956 QualType RebuildVectorType(QualType ElementType, unsigned NumElements,
957 VectorKind VecKind);
958
959 /// Build a new potentially dependently-sized extended vector type
960 /// given the element type and number of elements.
961 ///
962 /// By default, performs semantic analysis when building the vector type.
963 /// Subclasses may override this routine to provide different behavior.
964 QualType RebuildDependentVectorType(QualType ElementType, Expr *SizeExpr,
965 SourceLocation AttributeLoc, VectorKind);
966
967 /// Build a new extended vector type given the element type and
968 /// number of elements.
969 ///
970 /// By default, performs semantic analysis when building the vector type.
971 /// Subclasses may override this routine to provide different behavior.
972 QualType RebuildExtVectorType(QualType ElementType, unsigned NumElements,
973 SourceLocation AttributeLoc);
974
975 /// Build a new potentially dependently-sized extended vector type
976 /// given the element type and number of elements.
977 ///
978 /// By default, performs semantic analysis when building the vector type.
979 /// Subclasses may override this routine to provide different behavior.
980 QualType RebuildDependentSizedExtVectorType(QualType ElementType,
981 Expr *SizeExpr,
982 SourceLocation AttributeLoc);
983
984 /// Build a new matrix type given the element type and dimensions.
985 QualType RebuildConstantMatrixType(QualType ElementType, unsigned NumRows,
986 unsigned NumColumns);
987
988 /// Build a new matrix type given the type and dependently-defined
989 /// dimensions.
990 QualType RebuildDependentSizedMatrixType(QualType ElementType, Expr *RowExpr,
991 Expr *ColumnExpr,
992 SourceLocation AttributeLoc);
993
994 /// Build a new DependentAddressSpaceType or return the pointee
995 /// type variable with the correct address space (retrieved from
996 /// AddrSpaceExpr) applied to it. The former will be returned in cases
997 /// where the address space remains dependent.
998 ///
999 /// By default, performs semantic analysis when building the type with address
1000 /// space applied. Subclasses may override this routine to provide different
1001 /// behavior.
1002 QualType RebuildDependentAddressSpaceType(QualType PointeeType,
1003 Expr *AddrSpaceExpr,
1004 SourceLocation AttributeLoc);
1005
1006 /// Build a new function type.
1007 ///
1008 /// By default, performs semantic analysis when building the function type.
1009 /// Subclasses may override this routine to provide different behavior.
1010 QualType RebuildFunctionProtoType(QualType T,
1011 MutableArrayRef<QualType> ParamTypes,
1012 const FunctionProtoType::ExtProtoInfo &EPI);
1013
1014 /// Build a new unprototyped function type.
1015 QualType RebuildFunctionNoProtoType(QualType ResultType);
1016
1017 /// Rebuild an unresolved typename type, given the decl that
1018 /// the UnresolvedUsingTypenameDecl was transformed to.
1019 QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
1020
1021 /// Build a new type found via an alias.
1022 QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
1023 return SemaRef.Context.getUsingType(Found, Underlying);
1024 }
1025
1026 /// Build a new typedef type.
1027 QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
1028 return SemaRef.Context.getTypeDeclType(Decl: Typedef);
1029 }
1030
1031 /// Build a new MacroDefined type.
1032 QualType RebuildMacroQualifiedType(QualType T,
1033 const IdentifierInfo *MacroII) {
1034 return SemaRef.Context.getMacroQualifiedType(UnderlyingTy: T, MacroII);
1035 }
1036
1037 /// Build a new class/struct/union type.
1038 QualType RebuildRecordType(RecordDecl *Record) {
1039 return SemaRef.Context.getTypeDeclType(Decl: Record);
1040 }
1041
1042 /// Build a new Enum type.
1043 QualType RebuildEnumType(EnumDecl *Enum) {
1044 return SemaRef.Context.getTypeDeclType(Decl: Enum);
1045 }
1046
1047 /// Build a new typeof(expr) type.
1048 ///
1049 /// By default, performs semantic analysis when building the typeof type.
1050 /// Subclasses may override this routine to provide different behavior.
1051 QualType RebuildTypeOfExprType(Expr *Underlying, SourceLocation Loc,
1052 TypeOfKind Kind);
1053
1054 /// Build a new typeof(type) type.
1055 ///
1056 /// By default, builds a new TypeOfType with the given underlying type.
1057 QualType RebuildTypeOfType(QualType Underlying, TypeOfKind Kind);
1058
1059 /// Build a new unary transform type.
1060 QualType RebuildUnaryTransformType(QualType BaseType,
1061 UnaryTransformType::UTTKind UKind,
1062 SourceLocation Loc);
1063
1064 /// Build a new C++11 decltype type.
1065 ///
1066 /// By default, performs semantic analysis when building the decltype type.
1067 /// Subclasses may override this routine to provide different behavior.
1068 QualType RebuildDecltypeType(Expr *Underlying, SourceLocation Loc);
1069
1070 QualType RebuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
1071 SourceLocation Loc,
1072 SourceLocation EllipsisLoc,
1073 bool FullySubstituted,
1074 ArrayRef<QualType> Expansions = {});
1075
1076 /// Build a new C++11 auto type.
1077 ///
1078 /// By default, builds a new AutoType with the given deduced type.
1079 QualType RebuildAutoType(QualType Deduced, AutoTypeKeyword Keyword,
1080 ConceptDecl *TypeConstraintConcept,
1081 ArrayRef<TemplateArgument> TypeConstraintArgs) {
1082 // Note, IsDependent is always false here: we implicitly convert an 'auto'
1083 // which has been deduced to a dependent type into an undeduced 'auto', so
1084 // that we'll retry deduction after the transformation.
1085 return SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword,
1086 /*IsDependent*/ IsDependent: false, /*IsPack=*/IsPack: false,
1087 TypeConstraintConcept,
1088 TypeConstraintArgs);
1089 }
1090
1091 /// By default, builds a new DeducedTemplateSpecializationType with the given
1092 /// deduced type.
1093 QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
1094 QualType Deduced) {
1095 return SemaRef.Context.getDeducedTemplateSpecializationType(
1096 Template, DeducedType: Deduced, /*IsDependent*/ IsDependent: false);
1097 }
1098
1099 /// Build a new template specialization type.
1100 ///
1101 /// By default, performs semantic analysis when building the template
1102 /// specialization type. Subclasses may override this routine to provide
1103 /// different behavior.
1104 QualType RebuildTemplateSpecializationType(TemplateName Template,
1105 SourceLocation TemplateLoc,
1106 TemplateArgumentListInfo &Args);
1107
1108 /// Build a new parenthesized type.
1109 ///
1110 /// By default, builds a new ParenType type from the inner type.
1111 /// Subclasses may override this routine to provide different behavior.
1112 QualType RebuildParenType(QualType InnerType) {
1113 return SemaRef.BuildParenType(T: InnerType);
1114 }
1115
1116 /// Build a new qualified name type.
1117 ///
1118 /// By default, builds a new ElaboratedType type from the keyword,
1119 /// the nested-name-specifier and the named type.
1120 /// Subclasses may override this routine to provide different behavior.
1121 QualType RebuildElaboratedType(SourceLocation KeywordLoc,
1122 ElaboratedTypeKeyword Keyword,
1123 NestedNameSpecifierLoc QualifierLoc,
1124 QualType Named) {
1125 return SemaRef.Context.getElaboratedType(Keyword,
1126 NNS: QualifierLoc.getNestedNameSpecifier(),
1127 NamedType: Named);
1128 }
1129
1130 /// Build a new typename type that refers to a template-id.
1131 ///
1132 /// By default, builds a new DependentNameType type from the
1133 /// nested-name-specifier and the given type. Subclasses may override
1134 /// this routine to provide different behavior.
1135 QualType RebuildDependentTemplateSpecializationType(
1136 ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
1137 SourceLocation TemplateKWLoc, TemplateName Name, SourceLocation NameLoc,
1138 TemplateArgumentListInfo &Args, bool AllowInjectedClassName) {
1139 // If it's still dependent, make a dependent specialization.
1140 if (const DependentTemplateStorage *S = Name.getAsDependentTemplateName())
1141 return SemaRef.Context.getDependentTemplateSpecializationType(
1142 Keyword, Name: *S, Args: Args.arguments());
1143
1144 // Otherwise, make an elaborated type wrapping a non-dependent
1145 // specialization.
1146 QualType T =
1147 getDerived().RebuildTemplateSpecializationType(Name, NameLoc, Args);
1148 if (T.isNull())
1149 return QualType();
1150 return SemaRef.Context.getElaboratedType(Keyword, NNS, NamedType: T);
1151 }
1152
1153 /// Build a new typename type that refers to an identifier.
1154 ///
1155 /// By default, performs semantic analysis when building the typename type
1156 /// (or elaborated type). Subclasses may override this routine to provide
1157 /// different behavior.
1158 QualType RebuildDependentNameType(ElaboratedTypeKeyword Keyword,
1159 SourceLocation KeywordLoc,
1160 NestedNameSpecifierLoc QualifierLoc,
1161 const IdentifierInfo *Id,
1162 SourceLocation IdLoc,
1163 bool DeducedTSTContext) {
1164 CXXScopeSpec SS;
1165 SS.Adopt(Other: QualifierLoc);
1166
1167 if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
1168 // If the name is still dependent, just build a new dependent name type.
1169 if (!SemaRef.computeDeclContext(SS))
1170 return SemaRef.Context.getDependentNameType(Keyword,
1171 NNS: QualifierLoc.getNestedNameSpecifier(),
1172 Name: Id);
1173 }
1174
1175 if (Keyword == ElaboratedTypeKeyword::None ||
1176 Keyword == ElaboratedTypeKeyword::Typename) {
1177 return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
1178 II: *Id, IILoc: IdLoc, DeducedTSTContext);
1179 }
1180
1181 TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
1182
1183 // We had a dependent elaborated-type-specifier that has been transformed
1184 // into a non-dependent elaborated-type-specifier. Find the tag we're
1185 // referring to.
1186 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1187 DeclContext *DC = SemaRef.computeDeclContext(SS, EnteringContext: false);
1188 if (!DC)
1189 return QualType();
1190
1191 if (SemaRef.RequireCompleteDeclContext(SS, DC))
1192 return QualType();
1193
1194 TagDecl *Tag = nullptr;
1195 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1196 switch (Result.getResultKind()) {
1197 case LookupResultKind::NotFound:
1198 case LookupResultKind::NotFoundInCurrentInstantiation:
1199 break;
1200
1201 case LookupResultKind::Found:
1202 Tag = Result.getAsSingle<TagDecl>();
1203 break;
1204
1205 case LookupResultKind::FoundOverloaded:
1206 case LookupResultKind::FoundUnresolvedValue:
1207 llvm_unreachable("Tag lookup cannot find non-tags");
1208
1209 case LookupResultKind::Ambiguous:
1210 // Let the LookupResult structure handle ambiguities.
1211 return QualType();
1212 }
1213
1214 if (!Tag) {
1215 // Check where the name exists but isn't a tag type and use that to emit
1216 // better diagnostics.
1217 LookupResult Result(SemaRef, Id, IdLoc, Sema::LookupTagName);
1218 SemaRef.LookupQualifiedName(R&: Result, LookupCtx: DC);
1219 switch (Result.getResultKind()) {
1220 case LookupResultKind::Found:
1221 case LookupResultKind::FoundOverloaded:
1222 case LookupResultKind::FoundUnresolvedValue: {
1223 NamedDecl *SomeDecl = Result.getRepresentativeDecl();
1224 NonTagKind NTK = SemaRef.getNonTagTypeDeclKind(D: SomeDecl, TTK: Kind);
1225 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_tag_reference_non_tag)
1226 << SomeDecl << NTK << Kind;
1227 SemaRef.Diag(Loc: SomeDecl->getLocation(), DiagID: diag::note_declared_at);
1228 break;
1229 }
1230 default:
1231 SemaRef.Diag(Loc: IdLoc, DiagID: diag::err_not_tag_in_scope)
1232 << Kind << Id << DC << QualifierLoc.getSourceRange();
1233 break;
1234 }
1235 return QualType();
1236 }
1237
1238 if (!SemaRef.isAcceptableTagRedeclaration(Previous: Tag, NewTag: Kind, /*isDefinition*/isDefinition: false,
1239 NewTagLoc: IdLoc, Name: Id)) {
1240 SemaRef.Diag(Loc: KeywordLoc, DiagID: diag::err_use_with_wrong_tag) << Id;
1241 SemaRef.Diag(Loc: Tag->getLocation(), DiagID: diag::note_previous_use);
1242 return QualType();
1243 }
1244
1245 // Build the elaborated-type-specifier type.
1246 QualType T = SemaRef.Context.getTypeDeclType(Decl: Tag);
1247 return SemaRef.Context.getElaboratedType(Keyword,
1248 NNS: QualifierLoc.getNestedNameSpecifier(),
1249 NamedType: T);
1250 }
1251
1252 /// Build a new pack expansion type.
1253 ///
1254 /// By default, builds a new PackExpansionType type from the given pattern.
1255 /// Subclasses may override this routine to provide different behavior.
1256 QualType RebuildPackExpansionType(QualType Pattern, SourceRange PatternRange,
1257 SourceLocation EllipsisLoc,
1258 UnsignedOrNone NumExpansions) {
1259 return getSema().CheckPackExpansion(Pattern, PatternRange, EllipsisLoc,
1260 NumExpansions);
1261 }
1262
1263 /// Build a new atomic type given its value type.
1264 ///
1265 /// By default, performs semantic analysis when building the atomic type.
1266 /// Subclasses may override this routine to provide different behavior.
1267 QualType RebuildAtomicType(QualType ValueType, SourceLocation KWLoc);
1268
1269 /// Build a new pipe type given its value type.
1270 QualType RebuildPipeType(QualType ValueType, SourceLocation KWLoc,
1271 bool isReadPipe);
1272
1273 /// Build a bit-precise int given its value type.
1274 QualType RebuildBitIntType(bool IsUnsigned, unsigned NumBits,
1275 SourceLocation Loc);
1276
1277 /// Build a dependent bit-precise int given its value type.
1278 QualType RebuildDependentBitIntType(bool IsUnsigned, Expr *NumBitsExpr,
1279 SourceLocation Loc);
1280
1281 /// Build a new template name given a nested name specifier, a flag
1282 /// indicating whether the "template" keyword was provided, and the template
1283 /// that the template name refers to.
1284 ///
1285 /// By default, builds the new template name directly. Subclasses may override
1286 /// this routine to provide different behavior.
1287 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1288 bool TemplateKW,
1289 TemplateDecl *Template);
1290
1291 /// Build a new template name given a nested name specifier and the
1292 /// name that is referred to as a template.
1293 ///
1294 /// By default, performs semantic analysis to determine whether the name can
1295 /// be resolved to a specific template, then builds the appropriate kind of
1296 /// template name. Subclasses may override this routine to provide different
1297 /// behavior.
1298 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1299 SourceLocation TemplateKWLoc,
1300 const IdentifierInfo &Name,
1301 SourceLocation NameLoc, QualType ObjectType,
1302 NamedDecl *FirstQualifierInScope,
1303 bool AllowInjectedClassName);
1304
1305 /// Build a new template name given a nested name specifier and the
1306 /// overloaded operator name that is referred to as a template.
1307 ///
1308 /// By default, performs semantic analysis to determine whether the name can
1309 /// be resolved to a specific template, then builds the appropriate kind of
1310 /// template name. Subclasses may override this routine to provide different
1311 /// behavior.
1312 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1313 SourceLocation TemplateKWLoc,
1314 OverloadedOperatorKind Operator,
1315 SourceLocation NameLoc, QualType ObjectType,
1316 bool AllowInjectedClassName);
1317
1318 TemplateName RebuildTemplateName(CXXScopeSpec &SS,
1319 SourceLocation TemplateKWLoc,
1320 IdentifierOrOverloadedOperator IO,
1321 SourceLocation NameLoc, QualType ObjectType,
1322 NamedDecl *FirstQualifierInScope,
1323 bool AllowInjectedClassName);
1324
1325 /// Build a new template name given a template template parameter pack
1326 /// and the
1327 ///
1328 /// By default, performs semantic analysis to determine whether the name can
1329 /// be resolved to a specific template, then builds the appropriate kind of
1330 /// template name. Subclasses may override this routine to provide different
1331 /// behavior.
1332 TemplateName RebuildTemplateName(const TemplateArgument &ArgPack,
1333 Decl *AssociatedDecl, unsigned Index,
1334 bool Final) {
1335 return getSema().Context.getSubstTemplateTemplateParmPack(
1336 ArgPack, AssociatedDecl, Index, Final);
1337 }
1338
1339 /// Build a new compound statement.
1340 ///
1341 /// By default, performs semantic analysis to build the new statement.
1342 /// Subclasses may override this routine to provide different behavior.
1343 StmtResult RebuildCompoundStmt(SourceLocation LBraceLoc,
1344 MultiStmtArg Statements,
1345 SourceLocation RBraceLoc,
1346 bool IsStmtExpr) {
1347 return getSema().ActOnCompoundStmt(LBraceLoc, RBraceLoc, Statements,
1348 IsStmtExpr);
1349 }
1350
1351 /// Build a new case statement.
1352 ///
1353 /// By default, performs semantic analysis to build the new statement.
1354 /// Subclasses may override this routine to provide different behavior.
1355 StmtResult RebuildCaseStmt(SourceLocation CaseLoc,
1356 Expr *LHS,
1357 SourceLocation EllipsisLoc,
1358 Expr *RHS,
1359 SourceLocation ColonLoc) {
1360 return getSema().ActOnCaseStmt(CaseLoc, LHS, EllipsisLoc, RHS,
1361 ColonLoc);
1362 }
1363
1364 /// Attach the body to a new case statement.
1365 ///
1366 /// By default, performs semantic analysis to build the new statement.
1367 /// Subclasses may override this routine to provide different behavior.
1368 StmtResult RebuildCaseStmtBody(Stmt *S, Stmt *Body) {
1369 getSema().ActOnCaseStmtBody(S, Body);
1370 return S;
1371 }
1372
1373 /// Build a new default statement.
1374 ///
1375 /// By default, performs semantic analysis to build the new statement.
1376 /// Subclasses may override this routine to provide different behavior.
1377 StmtResult RebuildDefaultStmt(SourceLocation DefaultLoc,
1378 SourceLocation ColonLoc,
1379 Stmt *SubStmt) {
1380 return getSema().ActOnDefaultStmt(DefaultLoc, ColonLoc, SubStmt,
1381 /*CurScope=*/nullptr);
1382 }
1383
1384 /// Build a new label statement.
1385 ///
1386 /// By default, performs semantic analysis to build the new statement.
1387 /// Subclasses may override this routine to provide different behavior.
1388 StmtResult RebuildLabelStmt(SourceLocation IdentLoc, LabelDecl *L,
1389 SourceLocation ColonLoc, Stmt *SubStmt) {
1390 return SemaRef.ActOnLabelStmt(IdentLoc, TheDecl: L, ColonLoc, SubStmt);
1391 }
1392
1393 /// Build a new attributed statement.
1394 ///
1395 /// By default, performs semantic analysis to build the new statement.
1396 /// Subclasses may override this routine to provide different behavior.
1397 StmtResult RebuildAttributedStmt(SourceLocation AttrLoc,
1398 ArrayRef<const Attr *> Attrs,
1399 Stmt *SubStmt) {
1400 if (SemaRef.CheckRebuiltStmtAttributes(Attrs))
1401 return StmtError();
1402 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs, SubStmt);
1403 }
1404
1405 /// Build a new "if" statement.
1406 ///
1407 /// By default, performs semantic analysis to build the new statement.
1408 /// Subclasses may override this routine to provide different behavior.
1409 StmtResult RebuildIfStmt(SourceLocation IfLoc, IfStatementKind Kind,
1410 SourceLocation LParenLoc, Sema::ConditionResult Cond,
1411 SourceLocation RParenLoc, Stmt *Init, Stmt *Then,
1412 SourceLocation ElseLoc, Stmt *Else) {
1413 return getSema().ActOnIfStmt(IfLoc, Kind, LParenLoc, Init, Cond, RParenLoc,
1414 Then, ElseLoc, Else);
1415 }
1416
1417 /// Start building a new switch statement.
1418 ///
1419 /// By default, performs semantic analysis to build the new statement.
1420 /// Subclasses may override this routine to provide different behavior.
1421 StmtResult RebuildSwitchStmtStart(SourceLocation SwitchLoc,
1422 SourceLocation LParenLoc, Stmt *Init,
1423 Sema::ConditionResult Cond,
1424 SourceLocation RParenLoc) {
1425 return getSema().ActOnStartOfSwitchStmt(SwitchLoc, LParenLoc, Init, Cond,
1426 RParenLoc);
1427 }
1428
1429 /// Attach the body to the switch statement.
1430 ///
1431 /// By default, performs semantic analysis to build the new statement.
1432 /// Subclasses may override this routine to provide different behavior.
1433 StmtResult RebuildSwitchStmtBody(SourceLocation SwitchLoc,
1434 Stmt *Switch, Stmt *Body) {
1435 return getSema().ActOnFinishSwitchStmt(SwitchLoc, Switch, Body);
1436 }
1437
1438 /// Build a new while statement.
1439 ///
1440 /// By default, performs semantic analysis to build the new statement.
1441 /// Subclasses may override this routine to provide different behavior.
1442 StmtResult RebuildWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc,
1443 Sema::ConditionResult Cond,
1444 SourceLocation RParenLoc, Stmt *Body) {
1445 return getSema().ActOnWhileStmt(WhileLoc, LParenLoc, Cond, RParenLoc, Body);
1446 }
1447
1448 /// Build a new do-while statement.
1449 ///
1450 /// By default, performs semantic analysis to build the new statement.
1451 /// Subclasses may override this routine to provide different behavior.
1452 StmtResult RebuildDoStmt(SourceLocation DoLoc, Stmt *Body,
1453 SourceLocation WhileLoc, SourceLocation LParenLoc,
1454 Expr *Cond, SourceLocation RParenLoc) {
1455 return getSema().ActOnDoStmt(DoLoc, Body, WhileLoc, LParenLoc,
1456 Cond, RParenLoc);
1457 }
1458
1459 /// Build a new for statement.
1460 ///
1461 /// By default, performs semantic analysis to build the new statement.
1462 /// Subclasses may override this routine to provide different behavior.
1463 StmtResult RebuildForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
1464 Stmt *Init, Sema::ConditionResult Cond,
1465 Sema::FullExprArg Inc, SourceLocation RParenLoc,
1466 Stmt *Body) {
1467 return getSema().ActOnForStmt(ForLoc, LParenLoc, Init, Cond,
1468 Inc, RParenLoc, Body);
1469 }
1470
1471 /// Build a new goto statement.
1472 ///
1473 /// By default, performs semantic analysis to build the new statement.
1474 /// Subclasses may override this routine to provide different behavior.
1475 StmtResult RebuildGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc,
1476 LabelDecl *Label) {
1477 return getSema().ActOnGotoStmt(GotoLoc, LabelLoc, Label);
1478 }
1479
1480 /// Build a new indirect goto statement.
1481 ///
1482 /// By default, performs semantic analysis to build the new statement.
1483 /// Subclasses may override this routine to provide different behavior.
1484 StmtResult RebuildIndirectGotoStmt(SourceLocation GotoLoc,
1485 SourceLocation StarLoc,
1486 Expr *Target) {
1487 return getSema().ActOnIndirectGotoStmt(GotoLoc, StarLoc, Target);
1488 }
1489
1490 /// Build a new return statement.
1491 ///
1492 /// By default, performs semantic analysis to build the new statement.
1493 /// Subclasses may override this routine to provide different behavior.
1494 StmtResult RebuildReturnStmt(SourceLocation ReturnLoc, Expr *Result) {
1495 return getSema().BuildReturnStmt(ReturnLoc, Result);
1496 }
1497
1498 /// Build a new declaration 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 RebuildDeclStmt(MutableArrayRef<Decl *> Decls,
1503 SourceLocation StartLoc, SourceLocation EndLoc) {
1504 Sema::DeclGroupPtrTy DG = getSema().BuildDeclaratorGroup(Decls);
1505 return getSema().ActOnDeclStmt(DG, StartLoc, EndLoc);
1506 }
1507
1508 /// Build a new inline asm 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 RebuildGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
1513 bool IsVolatile, unsigned NumOutputs,
1514 unsigned NumInputs, IdentifierInfo **Names,
1515 MultiExprArg Constraints, MultiExprArg Exprs,
1516 Expr *AsmString, MultiExprArg Clobbers,
1517 unsigned NumLabels,
1518 SourceLocation RParenLoc) {
1519 return getSema().ActOnGCCAsmStmt(AsmLoc, IsSimple, IsVolatile, NumOutputs,
1520 NumInputs, Names, Constraints, Exprs,
1521 AsmString, Clobbers, NumLabels, RParenLoc);
1522 }
1523
1524 /// Build a new MS style inline asm statement.
1525 ///
1526 /// By default, performs semantic analysis to build the new statement.
1527 /// Subclasses may override this routine to provide different behavior.
1528 StmtResult RebuildMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc,
1529 ArrayRef<Token> AsmToks,
1530 StringRef AsmString,
1531 unsigned NumOutputs, unsigned NumInputs,
1532 ArrayRef<StringRef> Constraints,
1533 ArrayRef<StringRef> Clobbers,
1534 ArrayRef<Expr*> Exprs,
1535 SourceLocation EndLoc) {
1536 return getSema().ActOnMSAsmStmt(AsmLoc, LBraceLoc, AsmToks, AsmString,
1537 NumOutputs, NumInputs,
1538 Constraints, Clobbers, Exprs, EndLoc);
1539 }
1540
1541 /// Build a new co_return statement.
1542 ///
1543 /// By default, performs semantic analysis to build the new statement.
1544 /// Subclasses may override this routine to provide different behavior.
1545 StmtResult RebuildCoreturnStmt(SourceLocation CoreturnLoc, Expr *Result,
1546 bool IsImplicit) {
1547 return getSema().BuildCoreturnStmt(CoreturnLoc, Result, IsImplicit);
1548 }
1549
1550 /// Build a new co_await expression.
1551 ///
1552 /// By default, performs semantic analysis to build the new expression.
1553 /// Subclasses may override this routine to provide different behavior.
1554 ExprResult RebuildCoawaitExpr(SourceLocation CoawaitLoc, Expr *Operand,
1555 UnresolvedLookupExpr *OpCoawaitLookup,
1556 bool IsImplicit) {
1557 // This function rebuilds a coawait-expr given its operator.
1558 // For an explicit coawait-expr, the rebuild involves the full set
1559 // of transformations performed by BuildUnresolvedCoawaitExpr(),
1560 // including calling await_transform().
1561 // For an implicit coawait-expr, we need to rebuild the "operator
1562 // coawait" but not await_transform(), so use BuildResolvedCoawaitExpr().
1563 // This mirrors how the implicit CoawaitExpr is originally created
1564 // in Sema::ActOnCoroutineBodyStart().
1565 if (IsImplicit) {
1566 ExprResult Suspend = getSema().BuildOperatorCoawaitCall(
1567 CoawaitLoc, Operand, OpCoawaitLookup);
1568 if (Suspend.isInvalid())
1569 return ExprError();
1570 return getSema().BuildResolvedCoawaitExpr(CoawaitLoc, Operand,
1571 Suspend.get(), true);
1572 }
1573
1574 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Operand,
1575 OpCoawaitLookup);
1576 }
1577
1578 /// Build a new co_await expression.
1579 ///
1580 /// By default, performs semantic analysis to build the new expression.
1581 /// Subclasses may override this routine to provide different behavior.
1582 ExprResult RebuildDependentCoawaitExpr(SourceLocation CoawaitLoc,
1583 Expr *Result,
1584 UnresolvedLookupExpr *Lookup) {
1585 return getSema().BuildUnresolvedCoawaitExpr(CoawaitLoc, Result, Lookup);
1586 }
1587
1588 /// Build a new co_yield expression.
1589 ///
1590 /// By default, performs semantic analysis to build the new expression.
1591 /// Subclasses may override this routine to provide different behavior.
1592 ExprResult RebuildCoyieldExpr(SourceLocation CoyieldLoc, Expr *Result) {
1593 return getSema().BuildCoyieldExpr(CoyieldLoc, Result);
1594 }
1595
1596 StmtResult RebuildCoroutineBodyStmt(CoroutineBodyStmt::CtorArgs Args) {
1597 return getSema().BuildCoroutineBodyStmt(Args);
1598 }
1599
1600 /// Build a new Objective-C \@try statement.
1601 ///
1602 /// By default, performs semantic analysis to build the new statement.
1603 /// Subclasses may override this routine to provide different behavior.
1604 StmtResult RebuildObjCAtTryStmt(SourceLocation AtLoc,
1605 Stmt *TryBody,
1606 MultiStmtArg CatchStmts,
1607 Stmt *Finally) {
1608 return getSema().ObjC().ActOnObjCAtTryStmt(AtLoc, TryBody, CatchStmts,
1609 Finally);
1610 }
1611
1612 /// Rebuild an Objective-C exception declaration.
1613 ///
1614 /// By default, performs semantic analysis to build the new declaration.
1615 /// Subclasses may override this routine to provide different behavior.
1616 VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
1617 TypeSourceInfo *TInfo, QualType T) {
1618 return getSema().ObjC().BuildObjCExceptionDecl(
1619 TInfo, T, ExceptionDecl->getInnerLocStart(),
1620 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
1621 }
1622
1623 /// Build a new Objective-C \@catch statement.
1624 ///
1625 /// By default, performs semantic analysis to build the new statement.
1626 /// Subclasses may override this routine to provide different behavior.
1627 StmtResult RebuildObjCAtCatchStmt(SourceLocation AtLoc,
1628 SourceLocation RParenLoc,
1629 VarDecl *Var,
1630 Stmt *Body) {
1631 return getSema().ObjC().ActOnObjCAtCatchStmt(AtLoc, RParenLoc, Var, Body);
1632 }
1633
1634 /// Build a new Objective-C \@finally statement.
1635 ///
1636 /// By default, performs semantic analysis to build the new statement.
1637 /// Subclasses may override this routine to provide different behavior.
1638 StmtResult RebuildObjCAtFinallyStmt(SourceLocation AtLoc,
1639 Stmt *Body) {
1640 return getSema().ObjC().ActOnObjCAtFinallyStmt(AtLoc, Body);
1641 }
1642
1643 /// Build a new Objective-C \@throw statement.
1644 ///
1645 /// By default, performs semantic analysis to build the new statement.
1646 /// Subclasses may override this routine to provide different behavior.
1647 StmtResult RebuildObjCAtThrowStmt(SourceLocation AtLoc,
1648 Expr *Operand) {
1649 return getSema().ObjC().BuildObjCAtThrowStmt(AtLoc, Operand);
1650 }
1651
1652 /// Build a new OpenMP Canonical loop.
1653 ///
1654 /// Ensures that the outermost loop in @p LoopStmt is wrapped by a
1655 /// OMPCanonicalLoop.
1656 StmtResult RebuildOMPCanonicalLoop(Stmt *LoopStmt) {
1657 return getSema().OpenMP().ActOnOpenMPCanonicalLoop(LoopStmt);
1658 }
1659
1660 /// Build a new OpenMP executable directive.
1661 ///
1662 /// By default, performs semantic analysis to build the new statement.
1663 /// Subclasses may override this routine to provide different behavior.
1664 StmtResult RebuildOMPExecutableDirective(OpenMPDirectiveKind Kind,
1665 DeclarationNameInfo DirName,
1666 OpenMPDirectiveKind CancelRegion,
1667 ArrayRef<OMPClause *> Clauses,
1668 Stmt *AStmt, SourceLocation StartLoc,
1669 SourceLocation EndLoc) {
1670
1671 return getSema().OpenMP().ActOnOpenMPExecutableDirective(
1672 Kind, DirName, CancelRegion, Clauses, AStmt, StartLoc, EndLoc);
1673 }
1674
1675 /// Build a new OpenMP informational directive.
1676 StmtResult RebuildOMPInformationalDirective(OpenMPDirectiveKind Kind,
1677 DeclarationNameInfo DirName,
1678 ArrayRef<OMPClause *> Clauses,
1679 Stmt *AStmt,
1680 SourceLocation StartLoc,
1681 SourceLocation EndLoc) {
1682
1683 return getSema().OpenMP().ActOnOpenMPInformationalDirective(
1684 Kind, DirName, Clauses, AStmt, StartLoc, EndLoc);
1685 }
1686
1687 /// Build a new OpenMP 'if' clause.
1688 ///
1689 /// By default, performs semantic analysis to build the new OpenMP clause.
1690 /// Subclasses may override this routine to provide different behavior.
1691 OMPClause *RebuildOMPIfClause(OpenMPDirectiveKind NameModifier,
1692 Expr *Condition, SourceLocation StartLoc,
1693 SourceLocation LParenLoc,
1694 SourceLocation NameModifierLoc,
1695 SourceLocation ColonLoc,
1696 SourceLocation EndLoc) {
1697 return getSema().OpenMP().ActOnOpenMPIfClause(
1698 NameModifier, Condition, StartLoc, LParenLoc, NameModifierLoc, ColonLoc,
1699 EndLoc);
1700 }
1701
1702 /// Build a new OpenMP 'final' clause.
1703 ///
1704 /// By default, performs semantic analysis to build the new OpenMP clause.
1705 /// Subclasses may override this routine to provide different behavior.
1706 OMPClause *RebuildOMPFinalClause(Expr *Condition, SourceLocation StartLoc,
1707 SourceLocation LParenLoc,
1708 SourceLocation EndLoc) {
1709 return getSema().OpenMP().ActOnOpenMPFinalClause(Condition, StartLoc,
1710 LParenLoc, EndLoc);
1711 }
1712
1713 /// Build a new OpenMP 'num_threads' clause.
1714 ///
1715 /// By default, performs semantic analysis to build the new OpenMP clause.
1716 /// Subclasses may override this routine to provide different behavior.
1717 OMPClause *RebuildOMPNumThreadsClause(OpenMPNumThreadsClauseModifier Modifier,
1718 Expr *NumThreads,
1719 SourceLocation StartLoc,
1720 SourceLocation LParenLoc,
1721 SourceLocation ModifierLoc,
1722 SourceLocation EndLoc) {
1723 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(
1724 Modifier, NumThreads, StartLoc, LParenLoc, ModifierLoc, EndLoc);
1725 }
1726
1727 /// Build a new OpenMP 'safelen' clause.
1728 ///
1729 /// By default, performs semantic analysis to build the new OpenMP clause.
1730 /// Subclasses may override this routine to provide different behavior.
1731 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1732 SourceLocation LParenLoc,
1733 SourceLocation EndLoc) {
1734 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1735 EndLoc);
1736 }
1737
1738 /// Build a new OpenMP 'simdlen' clause.
1739 ///
1740 /// By default, performs semantic analysis to build the new OpenMP clause.
1741 /// Subclasses may override this routine to provide different behavior.
1742 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1743 SourceLocation LParenLoc,
1744 SourceLocation EndLoc) {
1745 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1746 EndLoc);
1747 }
1748
1749 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1750 SourceLocation StartLoc,
1751 SourceLocation LParenLoc,
1752 SourceLocation EndLoc) {
1753 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1754 EndLoc);
1755 }
1756
1757 /// Build a new OpenMP 'permutation' clause.
1758 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1759 SourceLocation StartLoc,
1760 SourceLocation LParenLoc,
1761 SourceLocation EndLoc) {
1762 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1763 LParenLoc, EndLoc);
1764 }
1765
1766 /// Build a new OpenMP 'full' clause.
1767 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1768 SourceLocation EndLoc) {
1769 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1770 }
1771
1772 /// Build a new OpenMP 'partial' clause.
1773 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1774 SourceLocation LParenLoc,
1775 SourceLocation EndLoc) {
1776 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1777 LParenLoc, EndLoc);
1778 }
1779
1780 /// Build a new OpenMP 'allocator' clause.
1781 ///
1782 /// By default, performs semantic analysis to build the new OpenMP clause.
1783 /// Subclasses may override this routine to provide different behavior.
1784 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1785 SourceLocation LParenLoc,
1786 SourceLocation EndLoc) {
1787 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1788 EndLoc);
1789 }
1790
1791 /// Build a new OpenMP 'collapse' clause.
1792 ///
1793 /// By default, performs semantic analysis to build the new OpenMP clause.
1794 /// Subclasses may override this routine to provide different behavior.
1795 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1796 SourceLocation LParenLoc,
1797 SourceLocation EndLoc) {
1798 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1799 LParenLoc, EndLoc);
1800 }
1801
1802 /// Build a new OpenMP 'default' clause.
1803 ///
1804 /// By default, performs semantic analysis to build the new OpenMP clause.
1805 /// Subclasses may override this routine to provide different behavior.
1806 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1807 SourceLocation StartLoc,
1808 SourceLocation LParenLoc,
1809 SourceLocation EndLoc) {
1810 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1811 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1812 }
1813
1814 /// Build a new OpenMP 'proc_bind' clause.
1815 ///
1816 /// By default, performs semantic analysis to build the new OpenMP clause.
1817 /// Subclasses may override this routine to provide different behavior.
1818 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1819 SourceLocation KindKwLoc,
1820 SourceLocation StartLoc,
1821 SourceLocation LParenLoc,
1822 SourceLocation EndLoc) {
1823 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1824 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1825 }
1826
1827 /// Build a new OpenMP 'schedule' clause.
1828 ///
1829 /// By default, performs semantic analysis to build the new OpenMP clause.
1830 /// Subclasses may override this routine to provide different behavior.
1831 OMPClause *RebuildOMPScheduleClause(
1832 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1833 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1834 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1835 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1836 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1837 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1838 CommaLoc, EndLoc);
1839 }
1840
1841 /// Build a new OpenMP 'ordered' clause.
1842 ///
1843 /// By default, performs semantic analysis to build the new OpenMP clause.
1844 /// Subclasses may override this routine to provide different behavior.
1845 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1846 SourceLocation EndLoc,
1847 SourceLocation LParenLoc, Expr *Num) {
1848 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1849 LParenLoc, Num);
1850 }
1851
1852 /// Build a new OpenMP 'private' clause.
1853 ///
1854 /// By default, performs semantic analysis to build the new OpenMP clause.
1855 /// Subclasses may override this routine to provide different behavior.
1856 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1857 SourceLocation StartLoc,
1858 SourceLocation LParenLoc,
1859 SourceLocation EndLoc) {
1860 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1861 LParenLoc, EndLoc);
1862 }
1863
1864 /// Build a new OpenMP 'firstprivate' clause.
1865 ///
1866 /// By default, performs semantic analysis to build the new OpenMP clause.
1867 /// Subclasses may override this routine to provide different behavior.
1868 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1869 SourceLocation StartLoc,
1870 SourceLocation LParenLoc,
1871 SourceLocation EndLoc) {
1872 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1873 LParenLoc, EndLoc);
1874 }
1875
1876 /// Build a new OpenMP 'lastprivate' clause.
1877 ///
1878 /// By default, performs semantic analysis to build the new OpenMP clause.
1879 /// Subclasses may override this routine to provide different behavior.
1880 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1881 OpenMPLastprivateModifier LPKind,
1882 SourceLocation LPKindLoc,
1883 SourceLocation ColonLoc,
1884 SourceLocation StartLoc,
1885 SourceLocation LParenLoc,
1886 SourceLocation EndLoc) {
1887 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1888 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1889 }
1890
1891 /// Build a new OpenMP 'shared' clause.
1892 ///
1893 /// By default, performs semantic analysis to build the new OpenMP clause.
1894 /// Subclasses may override this routine to provide different behavior.
1895 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1896 SourceLocation StartLoc,
1897 SourceLocation LParenLoc,
1898 SourceLocation EndLoc) {
1899 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1900 LParenLoc, EndLoc);
1901 }
1902
1903 /// Build a new OpenMP 'reduction' clause.
1904 ///
1905 /// By default, performs semantic analysis to build the new statement.
1906 /// Subclasses may override this routine to provide different behavior.
1907 OMPClause *RebuildOMPReductionClause(
1908 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1909 OpenMPOriginalSharingModifier OriginalSharingModifier,
1910 SourceLocation StartLoc, SourceLocation LParenLoc,
1911 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1912 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1913 const DeclarationNameInfo &ReductionId,
1914 ArrayRef<Expr *> UnresolvedReductions) {
1915 return getSema().OpenMP().ActOnOpenMPReductionClause(
1916 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1917 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1918 UnresolvedReductions);
1919 }
1920
1921 /// Build a new OpenMP 'task_reduction' clause.
1922 ///
1923 /// By default, performs semantic analysis to build the new statement.
1924 /// Subclasses may override this routine to provide different behavior.
1925 OMPClause *RebuildOMPTaskReductionClause(
1926 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1927 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1928 CXXScopeSpec &ReductionIdScopeSpec,
1929 const DeclarationNameInfo &ReductionId,
1930 ArrayRef<Expr *> UnresolvedReductions) {
1931 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1932 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1933 ReductionId, UnresolvedReductions);
1934 }
1935
1936 /// Build a new OpenMP 'in_reduction' clause.
1937 ///
1938 /// By default, performs semantic analysis to build the new statement.
1939 /// Subclasses may override this routine to provide different behavior.
1940 OMPClause *
1941 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1942 SourceLocation LParenLoc, SourceLocation ColonLoc,
1943 SourceLocation EndLoc,
1944 CXXScopeSpec &ReductionIdScopeSpec,
1945 const DeclarationNameInfo &ReductionId,
1946 ArrayRef<Expr *> UnresolvedReductions) {
1947 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1948 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1949 ReductionId, UnresolvedReductions);
1950 }
1951
1952 /// Build a new OpenMP 'linear' clause.
1953 ///
1954 /// By default, performs semantic analysis to build the new OpenMP clause.
1955 /// Subclasses may override this routine to provide different behavior.
1956 OMPClause *RebuildOMPLinearClause(
1957 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1958 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1959 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1960 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1961 return getSema().OpenMP().ActOnOpenMPLinearClause(
1962 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1963 StepModifierLoc, EndLoc);
1964 }
1965
1966 /// Build a new OpenMP 'aligned' clause.
1967 ///
1968 /// By default, performs semantic analysis to build the new OpenMP clause.
1969 /// Subclasses may override this routine to provide different behavior.
1970 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1971 SourceLocation StartLoc,
1972 SourceLocation LParenLoc,
1973 SourceLocation ColonLoc,
1974 SourceLocation EndLoc) {
1975 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1976 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1977 }
1978
1979 /// Build a new OpenMP 'copyin' clause.
1980 ///
1981 /// By default, performs semantic analysis to build the new OpenMP clause.
1982 /// Subclasses may override this routine to provide different behavior.
1983 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1984 SourceLocation StartLoc,
1985 SourceLocation LParenLoc,
1986 SourceLocation EndLoc) {
1987 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1988 LParenLoc, EndLoc);
1989 }
1990
1991 /// Build a new OpenMP 'copyprivate' clause.
1992 ///
1993 /// By default, performs semantic analysis to build the new OpenMP clause.
1994 /// Subclasses may override this routine to provide different behavior.
1995 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1996 SourceLocation StartLoc,
1997 SourceLocation LParenLoc,
1998 SourceLocation EndLoc) {
1999 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
2000 LParenLoc, EndLoc);
2001 }
2002
2003 /// Build a new OpenMP 'flush' pseudo clause.
2004 ///
2005 /// By default, performs semantic analysis to build the new OpenMP clause.
2006 /// Subclasses may override this routine to provide different behavior.
2007 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2008 SourceLocation StartLoc,
2009 SourceLocation LParenLoc,
2010 SourceLocation EndLoc) {
2011 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2012 LParenLoc, EndLoc);
2013 }
2014
2015 /// Build a new OpenMP 'depobj' pseudo clause.
2016 ///
2017 /// By default, performs semantic analysis to build the new OpenMP clause.
2018 /// Subclasses may override this routine to provide different behavior.
2019 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2020 SourceLocation LParenLoc,
2021 SourceLocation EndLoc) {
2022 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2023 LParenLoc, EndLoc);
2024 }
2025
2026 /// Build a new OpenMP 'depend' pseudo clause.
2027 ///
2028 /// By default, performs semantic analysis to build the new OpenMP clause.
2029 /// Subclasses may override this routine to provide different behavior.
2030 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2031 Expr *DepModifier, ArrayRef<Expr *> VarList,
2032 SourceLocation StartLoc,
2033 SourceLocation LParenLoc,
2034 SourceLocation EndLoc) {
2035 return getSema().OpenMP().ActOnOpenMPDependClause(
2036 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2037 }
2038
2039 /// Build a new OpenMP 'device' clause.
2040 ///
2041 /// By default, performs semantic analysis to build the new statement.
2042 /// Subclasses may override this routine to provide different behavior.
2043 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2044 Expr *Device, SourceLocation StartLoc,
2045 SourceLocation LParenLoc,
2046 SourceLocation ModifierLoc,
2047 SourceLocation EndLoc) {
2048 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2049 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2050 }
2051
2052 /// Build a new OpenMP 'map' clause.
2053 ///
2054 /// By default, performs semantic analysis to build the new OpenMP clause.
2055 /// Subclasses may override this routine to provide different behavior.
2056 OMPClause *RebuildOMPMapClause(
2057 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2058 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2059 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2060 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2061 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2062 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2063 return getSema().OpenMP().ActOnOpenMPMapClause(
2064 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2065 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2066 ColonLoc, VarList, Locs,
2067 /*NoDiagnose=*/false, UnresolvedMappers);
2068 }
2069
2070 /// Build a new OpenMP 'allocate' clause.
2071 ///
2072 /// By default, performs semantic analysis to build the new OpenMP clause.
2073 /// Subclasses may override this routine to provide different behavior.
2074 OMPClause *
2075 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2076 OpenMPAllocateClauseModifier FirstModifier,
2077 SourceLocation FirstModifierLoc,
2078 OpenMPAllocateClauseModifier SecondModifier,
2079 SourceLocation SecondModifierLoc,
2080 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2081 SourceLocation LParenLoc, SourceLocation ColonLoc,
2082 SourceLocation EndLoc) {
2083 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2084 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2085 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2086 }
2087
2088 /// Build a new OpenMP 'num_teams' clause.
2089 ///
2090 /// By default, performs semantic analysis to build the new statement.
2091 /// Subclasses may override this routine to provide different behavior.
2092 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2093 SourceLocation StartLoc,
2094 SourceLocation LParenLoc,
2095 SourceLocation EndLoc) {
2096 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2097 LParenLoc, EndLoc);
2098 }
2099
2100 /// Build a new OpenMP 'thread_limit' clause.
2101 ///
2102 /// By default, performs semantic analysis to build the new statement.
2103 /// Subclasses may override this routine to provide different behavior.
2104 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2105 SourceLocation StartLoc,
2106 SourceLocation LParenLoc,
2107 SourceLocation EndLoc) {
2108 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2109 LParenLoc, EndLoc);
2110 }
2111
2112 /// Build a new OpenMP 'priority' clause.
2113 ///
2114 /// By default, performs semantic analysis to build the new statement.
2115 /// Subclasses may override this routine to provide different behavior.
2116 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2117 SourceLocation LParenLoc,
2118 SourceLocation EndLoc) {
2119 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2120 LParenLoc, EndLoc);
2121 }
2122
2123 /// Build a new OpenMP 'grainsize' clause.
2124 ///
2125 /// By default, performs semantic analysis to build the new statement.
2126 /// Subclasses may override this routine to provide different behavior.
2127 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2128 Expr *Device, SourceLocation StartLoc,
2129 SourceLocation LParenLoc,
2130 SourceLocation ModifierLoc,
2131 SourceLocation EndLoc) {
2132 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2133 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2134 }
2135
2136 /// Build a new OpenMP 'num_tasks' clause.
2137 ///
2138 /// By default, performs semantic analysis to build the new statement.
2139 /// Subclasses may override this routine to provide different behavior.
2140 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2141 Expr *NumTasks, SourceLocation StartLoc,
2142 SourceLocation LParenLoc,
2143 SourceLocation ModifierLoc,
2144 SourceLocation EndLoc) {
2145 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2146 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2147 }
2148
2149 /// Build a new OpenMP 'hint' clause.
2150 ///
2151 /// By default, performs semantic analysis to build the new statement.
2152 /// Subclasses may override this routine to provide different behavior.
2153 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2154 SourceLocation LParenLoc,
2155 SourceLocation EndLoc) {
2156 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2157 EndLoc);
2158 }
2159
2160 /// Build a new OpenMP 'detach' 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 *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2165 SourceLocation LParenLoc,
2166 SourceLocation EndLoc) {
2167 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2168 EndLoc);
2169 }
2170
2171 /// Build a new OpenMP 'dist_schedule' clause.
2172 ///
2173 /// By default, performs semantic analysis to build the new OpenMP clause.
2174 /// Subclasses may override this routine to provide different behavior.
2175 OMPClause *
2176 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2177 Expr *ChunkSize, SourceLocation StartLoc,
2178 SourceLocation LParenLoc, SourceLocation KindLoc,
2179 SourceLocation CommaLoc, SourceLocation EndLoc) {
2180 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2181 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2182 }
2183
2184 /// Build a new OpenMP 'to' 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 *
2189 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2190 ArrayRef<SourceLocation> MotionModifiersLoc,
2191 CXXScopeSpec &MapperIdScopeSpec,
2192 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2193 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2194 ArrayRef<Expr *> UnresolvedMappers) {
2195 return getSema().OpenMP().ActOnOpenMPToClause(
2196 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2197 ColonLoc, VarList, Locs, UnresolvedMappers);
2198 }
2199
2200 /// Build a new OpenMP 'from' clause.
2201 ///
2202 /// By default, performs semantic analysis to build the new statement.
2203 /// Subclasses may override this routine to provide different behavior.
2204 OMPClause *
2205 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2206 ArrayRef<SourceLocation> MotionModifiersLoc,
2207 CXXScopeSpec &MapperIdScopeSpec,
2208 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2209 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2210 ArrayRef<Expr *> UnresolvedMappers) {
2211 return getSema().OpenMP().ActOnOpenMPFromClause(
2212 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2213 ColonLoc, VarList, Locs, UnresolvedMappers);
2214 }
2215
2216 /// Build a new OpenMP 'use_device_ptr' clause.
2217 ///
2218 /// By default, performs semantic analysis to build the new OpenMP clause.
2219 /// Subclasses may override this routine to provide different behavior.
2220 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2221 const OMPVarListLocTy &Locs) {
2222 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2223 }
2224
2225 /// Build a new OpenMP 'use_device_addr' clause.
2226 ///
2227 /// By default, performs semantic analysis to build the new OpenMP clause.
2228 /// Subclasses may override this routine to provide different behavior.
2229 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2230 const OMPVarListLocTy &Locs) {
2231 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2232 }
2233
2234 /// Build a new OpenMP 'is_device_ptr' clause.
2235 ///
2236 /// By default, performs semantic analysis to build the new OpenMP clause.
2237 /// Subclasses may override this routine to provide different behavior.
2238 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2239 const OMPVarListLocTy &Locs) {
2240 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2241 }
2242
2243 /// Build a new OpenMP 'has_device_addr' clause.
2244 ///
2245 /// By default, performs semantic analysis to build the new OpenMP clause.
2246 /// Subclasses may override this routine to provide different behavior.
2247 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2248 const OMPVarListLocTy &Locs) {
2249 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2250 }
2251
2252 /// Build a new OpenMP 'defaultmap' clause.
2253 ///
2254 /// By default, performs semantic analysis to build the new OpenMP clause.
2255 /// Subclasses may override this routine to provide different behavior.
2256 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2257 OpenMPDefaultmapClauseKind Kind,
2258 SourceLocation StartLoc,
2259 SourceLocation LParenLoc,
2260 SourceLocation MLoc,
2261 SourceLocation KindLoc,
2262 SourceLocation EndLoc) {
2263 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2264 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2265 }
2266
2267 /// Build a new OpenMP 'nontemporal' clause.
2268 ///
2269 /// By default, performs semantic analysis to build the new OpenMP clause.
2270 /// Subclasses may override this routine to provide different behavior.
2271 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2272 SourceLocation StartLoc,
2273 SourceLocation LParenLoc,
2274 SourceLocation EndLoc) {
2275 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2276 LParenLoc, EndLoc);
2277 }
2278
2279 /// Build a new OpenMP 'inclusive' 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 *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2284 SourceLocation StartLoc,
2285 SourceLocation LParenLoc,
2286 SourceLocation EndLoc) {
2287 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2288 LParenLoc, EndLoc);
2289 }
2290
2291 /// Build a new OpenMP 'exclusive' 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 *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2296 SourceLocation StartLoc,
2297 SourceLocation LParenLoc,
2298 SourceLocation EndLoc) {
2299 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2300 LParenLoc, EndLoc);
2301 }
2302
2303 /// Build a new OpenMP 'uses_allocators' clause.
2304 ///
2305 /// By default, performs semantic analysis to build the new OpenMP clause.
2306 /// Subclasses may override this routine to provide different behavior.
2307 OMPClause *RebuildOMPUsesAllocatorsClause(
2308 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2309 SourceLocation LParenLoc, SourceLocation EndLoc) {
2310 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2311 StartLoc, LParenLoc, EndLoc, Data);
2312 }
2313
2314 /// Build a new OpenMP 'affinity' clause.
2315 ///
2316 /// By default, performs semantic analysis to build the new OpenMP clause.
2317 /// Subclasses may override this routine to provide different behavior.
2318 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2319 SourceLocation LParenLoc,
2320 SourceLocation ColonLoc,
2321 SourceLocation EndLoc, Expr *Modifier,
2322 ArrayRef<Expr *> Locators) {
2323 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2324 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2325 }
2326
2327 /// Build a new OpenMP 'order' clause.
2328 ///
2329 /// By default, performs semantic analysis to build the new OpenMP clause.
2330 /// Subclasses may override this routine to provide different behavior.
2331 OMPClause *RebuildOMPOrderClause(
2332 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2333 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2334 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2335 return getSema().OpenMP().ActOnOpenMPOrderClause(
2336 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2337 }
2338
2339 /// Build a new OpenMP 'init' clause.
2340 ///
2341 /// By default, performs semantic analysis to build the new OpenMP clause.
2342 /// Subclasses may override this routine to provide different behavior.
2343 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2344 SourceLocation StartLoc,
2345 SourceLocation LParenLoc,
2346 SourceLocation VarLoc,
2347 SourceLocation EndLoc) {
2348 return getSema().OpenMP().ActOnOpenMPInitClause(
2349 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2350 }
2351
2352 /// Build a new OpenMP 'use' clause.
2353 ///
2354 /// By default, performs semantic analysis to build the new OpenMP clause.
2355 /// Subclasses may override this routine to provide different behavior.
2356 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2357 SourceLocation LParenLoc,
2358 SourceLocation VarLoc, SourceLocation EndLoc) {
2359 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2360 LParenLoc, VarLoc, EndLoc);
2361 }
2362
2363 /// Build a new OpenMP 'destroy' clause.
2364 ///
2365 /// By default, performs semantic analysis to build the new OpenMP clause.
2366 /// Subclasses may override this routine to provide different behavior.
2367 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2368 SourceLocation LParenLoc,
2369 SourceLocation VarLoc,
2370 SourceLocation EndLoc) {
2371 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2372 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2373 }
2374
2375 /// Build a new OpenMP 'novariants' clause.
2376 ///
2377 /// By default, performs semantic analysis to build the new OpenMP clause.
2378 /// Subclasses may override this routine to provide different behavior.
2379 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2380 SourceLocation StartLoc,
2381 SourceLocation LParenLoc,
2382 SourceLocation EndLoc) {
2383 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2384 LParenLoc, EndLoc);
2385 }
2386
2387 /// Build a new OpenMP 'nocontext' clause.
2388 ///
2389 /// By default, performs semantic analysis to build the new OpenMP clause.
2390 /// Subclasses may override this routine to provide different behavior.
2391 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2392 SourceLocation LParenLoc,
2393 SourceLocation EndLoc) {
2394 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2395 LParenLoc, EndLoc);
2396 }
2397
2398 /// Build a new OpenMP 'filter' clause.
2399 ///
2400 /// By default, performs semantic analysis to build the new OpenMP clause.
2401 /// Subclasses may override this routine to provide different behavior.
2402 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2403 SourceLocation LParenLoc,
2404 SourceLocation EndLoc) {
2405 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2406 LParenLoc, EndLoc);
2407 }
2408
2409 /// Build a new OpenMP 'bind' clause.
2410 ///
2411 /// By default, performs semantic analysis to build the new OpenMP clause.
2412 /// Subclasses may override this routine to provide different behavior.
2413 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2414 SourceLocation KindLoc,
2415 SourceLocation StartLoc,
2416 SourceLocation LParenLoc,
2417 SourceLocation EndLoc) {
2418 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2419 LParenLoc, EndLoc);
2420 }
2421
2422 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2423 ///
2424 /// By default, performs semantic analysis to build the new OpenMP clause.
2425 /// Subclasses may override this routine to provide different behavior.
2426 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2427 SourceLocation LParenLoc,
2428 SourceLocation EndLoc) {
2429 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2430 LParenLoc, EndLoc);
2431 }
2432
2433 /// Build a new OpenMP 'ompx_attribute' clause.
2434 ///
2435 /// By default, performs semantic analysis to build the new OpenMP clause.
2436 /// Subclasses may override this routine to provide different behavior.
2437 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2438 SourceLocation StartLoc,
2439 SourceLocation LParenLoc,
2440 SourceLocation EndLoc) {
2441 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2442 LParenLoc, EndLoc);
2443 }
2444
2445 /// Build a new OpenMP 'ompx_bare' clause.
2446 ///
2447 /// By default, performs semantic analysis to build the new OpenMP clause.
2448 /// Subclasses may override this routine to provide different behavior.
2449 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2450 SourceLocation EndLoc) {
2451 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2452 }
2453
2454 /// Build a new OpenMP 'align' clause.
2455 ///
2456 /// By default, performs semantic analysis to build the new OpenMP clause.
2457 /// Subclasses may override this routine to provide different behavior.
2458 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2459 SourceLocation LParenLoc,
2460 SourceLocation EndLoc) {
2461 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2462 EndLoc);
2463 }
2464
2465 /// Build a new OpenMP 'at' clause.
2466 ///
2467 /// By default, performs semantic analysis to build the new OpenMP clause.
2468 /// Subclasses may override this routine to provide different behavior.
2469 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2470 SourceLocation StartLoc,
2471 SourceLocation LParenLoc,
2472 SourceLocation EndLoc) {
2473 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2474 LParenLoc, EndLoc);
2475 }
2476
2477 /// Build a new OpenMP 'severity' clause.
2478 ///
2479 /// By default, performs semantic analysis to build the new OpenMP clause.
2480 /// Subclasses may override this routine to provide different behavior.
2481 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2482 SourceLocation KwLoc,
2483 SourceLocation StartLoc,
2484 SourceLocation LParenLoc,
2485 SourceLocation EndLoc) {
2486 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2487 LParenLoc, EndLoc);
2488 }
2489
2490 /// Build a new OpenMP 'message' clause.
2491 ///
2492 /// By default, performs semantic analysis to build the new OpenMP clause.
2493 /// Subclasses may override this routine to provide different behavior.
2494 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2495 SourceLocation LParenLoc,
2496 SourceLocation EndLoc) {
2497 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2498 EndLoc);
2499 }
2500
2501 /// Build a new OpenMP 'doacross' clause.
2502 ///
2503 /// By default, performs semantic analysis to build the new OpenMP clause.
2504 /// Subclasses may override this routine to provide different behavior.
2505 OMPClause *
2506 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2507 SourceLocation DepLoc, SourceLocation ColonLoc,
2508 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2509 SourceLocation LParenLoc, SourceLocation EndLoc) {
2510 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2511 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2512 }
2513
2514 /// Build a new OpenMP 'holds' clause.
2515 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2516 SourceLocation LParenLoc,
2517 SourceLocation EndLoc) {
2518 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2519 EndLoc);
2520 }
2521
2522 /// Rebuild the operand to an Objective-C \@synchronized statement.
2523 ///
2524 /// By default, performs semantic analysis to build the new statement.
2525 /// Subclasses may override this routine to provide different behavior.
2526 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2527 Expr *object) {
2528 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2529 }
2530
2531 /// Build a new Objective-C \@synchronized statement.
2532 ///
2533 /// By default, performs semantic analysis to build the new statement.
2534 /// Subclasses may override this routine to provide different behavior.
2535 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2536 Expr *Object, Stmt *Body) {
2537 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2538 }
2539
2540 /// Build a new Objective-C \@autoreleasepool statement.
2541 ///
2542 /// By default, performs semantic analysis to build the new statement.
2543 /// Subclasses may override this routine to provide different behavior.
2544 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2545 Stmt *Body) {
2546 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2547 }
2548
2549 /// Build a new Objective-C fast enumeration statement.
2550 ///
2551 /// By default, performs semantic analysis to build the new statement.
2552 /// Subclasses may override this routine to provide different behavior.
2553 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2554 Stmt *Element,
2555 Expr *Collection,
2556 SourceLocation RParenLoc,
2557 Stmt *Body) {
2558 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2559 ForLoc, Element, Collection, RParenLoc);
2560 if (ForEachStmt.isInvalid())
2561 return StmtError();
2562
2563 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2564 Body);
2565 }
2566
2567 /// Build a new C++ exception declaration.
2568 ///
2569 /// By default, performs semantic analysis to build the new decaration.
2570 /// Subclasses may override this routine to provide different behavior.
2571 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2572 TypeSourceInfo *Declarator,
2573 SourceLocation StartLoc,
2574 SourceLocation IdLoc,
2575 IdentifierInfo *Id) {
2576 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2577 StartLoc, IdLoc, Id);
2578 if (Var)
2579 getSema().CurContext->addDecl(Var);
2580 return Var;
2581 }
2582
2583 /// Build a new C++ catch statement.
2584 ///
2585 /// By default, performs semantic analysis to build the new statement.
2586 /// Subclasses may override this routine to provide different behavior.
2587 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2588 VarDecl *ExceptionDecl,
2589 Stmt *Handler) {
2590 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2591 Handler));
2592 }
2593
2594 /// Build a new C++ try statement.
2595 ///
2596 /// By default, performs semantic analysis to build the new statement.
2597 /// Subclasses may override this routine to provide different behavior.
2598 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2599 ArrayRef<Stmt *> Handlers) {
2600 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2601 }
2602
2603 /// Build a new C++0x range-based for statement.
2604 ///
2605 /// By default, performs semantic analysis to build the new statement.
2606 /// Subclasses may override this routine to provide different behavior.
2607 StmtResult RebuildCXXForRangeStmt(
2608 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2609 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2610 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2611 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2612 // If we've just learned that the range is actually an Objective-C
2613 // collection, treat this as an Objective-C fast enumeration loop.
2614 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Val: Range)) {
2615 if (RangeStmt->isSingleDecl()) {
2616 if (VarDecl *RangeVar = dyn_cast<VarDecl>(Val: RangeStmt->getSingleDecl())) {
2617 if (RangeVar->isInvalidDecl())
2618 return StmtError();
2619
2620 Expr *RangeExpr = RangeVar->getInit();
2621 if (!RangeExpr->isTypeDependent() &&
2622 RangeExpr->getType()->isObjCObjectPointerType()) {
2623 // FIXME: Support init-statements in Objective-C++20 ranged for
2624 // statement.
2625 if (Init) {
2626 return SemaRef.Diag(Loc: Init->getBeginLoc(),
2627 DiagID: diag::err_objc_for_range_init_stmt)
2628 << Init->getSourceRange();
2629 }
2630 return getSema().ObjC().ActOnObjCForCollectionStmt(
2631 ForLoc, LoopVar, RangeExpr, RParenLoc);
2632 }
2633 }
2634 }
2635 }
2636
2637 return getSema().BuildCXXForRangeStmt(
2638 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2639 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2640 }
2641
2642 /// Build a new C++0x range-based for statement.
2643 ///
2644 /// By default, performs semantic analysis to build the new statement.
2645 /// Subclasses may override this routine to provide different behavior.
2646 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2647 bool IsIfExists,
2648 NestedNameSpecifierLoc QualifierLoc,
2649 DeclarationNameInfo NameInfo,
2650 Stmt *Nested) {
2651 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2652 QualifierLoc, NameInfo, Nested);
2653 }
2654
2655 /// Attach body to a C++0x range-based for statement.
2656 ///
2657 /// By default, performs semantic analysis to finish the new statement.
2658 /// Subclasses may override this routine to provide different behavior.
2659 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2660 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2661 }
2662
2663 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2664 Stmt *TryBlock, Stmt *Handler) {
2665 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2666 }
2667
2668 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2669 Stmt *Block) {
2670 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2671 }
2672
2673 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2674 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2675 }
2676
2677 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2678 SourceLocation LParen,
2679 SourceLocation RParen,
2680 TypeSourceInfo *TSI) {
2681 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2682 TSI);
2683 }
2684
2685 /// Build a new predefined expression.
2686 ///
2687 /// By default, performs semantic analysis to build the new expression.
2688 /// Subclasses may override this routine to provide different behavior.
2689 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2690 return getSema().BuildPredefinedExpr(Loc, IK);
2691 }
2692
2693 /// Build a new expression that references a declaration.
2694 ///
2695 /// By default, performs semantic analysis to build the new expression.
2696 /// Subclasses may override this routine to provide different behavior.
2697 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2698 LookupResult &R,
2699 bool RequiresADL) {
2700 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2701 }
2702
2703
2704 /// Build a new expression that references a declaration.
2705 ///
2706 /// By default, performs semantic analysis to build the new expression.
2707 /// Subclasses may override this routine to provide different behavior.
2708 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2709 ValueDecl *VD,
2710 const DeclarationNameInfo &NameInfo,
2711 NamedDecl *Found,
2712 TemplateArgumentListInfo *TemplateArgs) {
2713 CXXScopeSpec SS;
2714 SS.Adopt(Other: QualifierLoc);
2715 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2716 TemplateArgs);
2717 }
2718
2719 /// Build a new expression in parentheses.
2720 ///
2721 /// By default, performs semantic analysis to build the new expression.
2722 /// Subclasses may override this routine to provide different behavior.
2723 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2724 SourceLocation RParen) {
2725 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2726 }
2727
2728 /// Build a new pseudo-destructor expression.
2729 ///
2730 /// By default, performs semantic analysis to build the new expression.
2731 /// Subclasses may override this routine to provide different behavior.
2732 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2733 SourceLocation OperatorLoc,
2734 bool isArrow,
2735 CXXScopeSpec &SS,
2736 TypeSourceInfo *ScopeType,
2737 SourceLocation CCLoc,
2738 SourceLocation TildeLoc,
2739 PseudoDestructorTypeStorage Destroyed);
2740
2741 /// Build a new unary operator expression.
2742 ///
2743 /// By default, performs semantic analysis to build the new expression.
2744 /// Subclasses may override this routine to provide different behavior.
2745 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2746 UnaryOperatorKind Opc,
2747 Expr *SubExpr) {
2748 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2749 }
2750
2751 /// Build a new builtin offsetof expression.
2752 ///
2753 /// By default, performs semantic analysis to build the new expression.
2754 /// Subclasses may override this routine to provide different behavior.
2755 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2756 TypeSourceInfo *Type,
2757 ArrayRef<Sema::OffsetOfComponent> Components,
2758 SourceLocation RParenLoc) {
2759 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2760 RParenLoc);
2761 }
2762
2763 /// Build a new sizeof, alignof or vec_step expression with a
2764 /// type argument.
2765 ///
2766 /// By default, performs semantic analysis to build the new expression.
2767 /// Subclasses may override this routine to provide different behavior.
2768 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2769 SourceLocation OpLoc,
2770 UnaryExprOrTypeTrait ExprKind,
2771 SourceRange R) {
2772 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2773 }
2774
2775 /// Build a new sizeof, alignof or vec step expression with an
2776 /// expression argument.
2777 ///
2778 /// By default, performs semantic analysis to build the new expression.
2779 /// Subclasses may override this routine to provide different behavior.
2780 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2781 UnaryExprOrTypeTrait ExprKind,
2782 SourceRange R) {
2783 ExprResult Result
2784 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2785 if (Result.isInvalid())
2786 return ExprError();
2787
2788 return Result;
2789 }
2790
2791 /// Build a new array subscript expression.
2792 ///
2793 /// By default, performs semantic analysis to build the new expression.
2794 /// Subclasses may override this routine to provide different behavior.
2795 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2796 SourceLocation LBracketLoc,
2797 Expr *RHS,
2798 SourceLocation RBracketLoc) {
2799 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2800 LBracketLoc, RHS,
2801 RBracketLoc);
2802 }
2803
2804 /// Build a new matrix subscript expression.
2805 ///
2806 /// By default, performs semantic analysis to build the new expression.
2807 /// Subclasses may override this routine to provide different behavior.
2808 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2809 Expr *ColumnIdx,
2810 SourceLocation RBracketLoc) {
2811 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2812 RBracketLoc);
2813 }
2814
2815 /// Build a new array section expression.
2816 ///
2817 /// By default, performs semantic analysis to build the new expression.
2818 /// Subclasses may override this routine to provide different behavior.
2819 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2820 SourceLocation LBracketLoc,
2821 Expr *LowerBound,
2822 SourceLocation ColonLocFirst,
2823 SourceLocation ColonLocSecond,
2824 Expr *Length, Expr *Stride,
2825 SourceLocation RBracketLoc) {
2826 if (IsOMPArraySection)
2827 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2828 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2829 Stride, RBracketLoc);
2830
2831 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2832 "Stride/second colon not allowed for OpenACC");
2833
2834 return getSema().OpenACC().ActOnArraySectionExpr(
2835 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2836 }
2837
2838 /// Build a new array shaping expression.
2839 ///
2840 /// By default, performs semantic analysis to build the new expression.
2841 /// Subclasses may override this routine to provide different behavior.
2842 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2843 SourceLocation RParenLoc,
2844 ArrayRef<Expr *> Dims,
2845 ArrayRef<SourceRange> BracketsRanges) {
2846 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2847 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2848 }
2849
2850 /// Build a new iterator expression.
2851 ///
2852 /// By default, performs semantic analysis to build the new expression.
2853 /// Subclasses may override this routine to provide different behavior.
2854 ExprResult
2855 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2856 SourceLocation RLoc,
2857 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2858 return getSema().OpenMP().ActOnOMPIteratorExpr(
2859 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2860 }
2861
2862 /// Build a new call expression.
2863 ///
2864 /// By default, performs semantic analysis to build the new expression.
2865 /// Subclasses may override this routine to provide different behavior.
2866 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2867 MultiExprArg Args,
2868 SourceLocation RParenLoc,
2869 Expr *ExecConfig = nullptr) {
2870 return getSema().ActOnCallExpr(
2871 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2872 }
2873
2874 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2875 MultiExprArg Args,
2876 SourceLocation RParenLoc) {
2877 return getSema().ActOnArraySubscriptExpr(
2878 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2879 }
2880
2881 /// Build a new member access 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 RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2886 bool isArrow,
2887 NestedNameSpecifierLoc QualifierLoc,
2888 SourceLocation TemplateKWLoc,
2889 const DeclarationNameInfo &MemberNameInfo,
2890 ValueDecl *Member,
2891 NamedDecl *FoundDecl,
2892 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2893 NamedDecl *FirstQualifierInScope) {
2894 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2895 isArrow);
2896 if (!Member->getDeclName()) {
2897 // We have a reference to an unnamed field. This is always the
2898 // base of an anonymous struct/union member access, i.e. the
2899 // field is always of record type.
2900 assert(Member->getType()->isRecordType() &&
2901 "unnamed member not of record type?");
2902
2903 BaseResult =
2904 getSema().PerformObjectMemberConversion(BaseResult.get(),
2905 QualifierLoc.getNestedNameSpecifier(),
2906 FoundDecl, Member);
2907 if (BaseResult.isInvalid())
2908 return ExprError();
2909 Base = BaseResult.get();
2910
2911 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2912 // from the AST, so we need to re-insert them if needed (since
2913 // `BuildFieldRefereneExpr()` doesn't do this).
2914 if (!isArrow && Base->isPRValue()) {
2915 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2916 if (BaseResult.isInvalid())
2917 return ExprError();
2918 Base = BaseResult.get();
2919 }
2920
2921 CXXScopeSpec EmptySS;
2922 return getSema().BuildFieldReferenceExpr(
2923 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Val: Member),
2924 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
2925 MemberNameInfo);
2926 }
2927
2928 CXXScopeSpec SS;
2929 SS.Adopt(Other: QualifierLoc);
2930
2931 Base = BaseResult.get();
2932 if (Base->containsErrors())
2933 return ExprError();
2934
2935 QualType BaseType = Base->getType();
2936
2937 if (isArrow && !BaseType->isPointerType())
2938 return ExprError();
2939
2940 // FIXME: this involves duplicating earlier analysis in a lot of
2941 // cases; we should avoid this when possible.
2942 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2943 R.addDecl(D: FoundDecl);
2944 R.resolveKind();
2945
2946 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2947 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Val: Member)) {
2948 if (auto *ThisClass = cast<CXXThisExpr>(Val: Base)
2949 ->getType()
2950 ->getPointeeType()
2951 ->getAsCXXRecordDecl()) {
2952 auto *Class = cast<CXXRecordDecl>(Val: Member->getDeclContext());
2953 // In unevaluated contexts, an expression supposed to be a member access
2954 // might reference a member in an unrelated class.
2955 if (!ThisClass->Equals(DC: Class) && !ThisClass->isDerivedFrom(Base: Class))
2956 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2957 VK_LValue, Member->getLocation());
2958 }
2959 }
2960
2961 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2962 SS, TemplateKWLoc,
2963 FirstQualifierInScope,
2964 R, ExplicitTemplateArgs,
2965 /*S*/nullptr);
2966 }
2967
2968 /// Build a new binary operator 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 RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
2973 Expr *LHS, Expr *RHS,
2974 bool ForFoldExpression = false) {
2975 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
2976 ForFoldExpression);
2977 }
2978
2979 /// Build a new rewritten operator expression.
2980 ///
2981 /// By default, performs semantic analysis to build the new expression.
2982 /// Subclasses may override this routine to provide different behavior.
2983 ExprResult RebuildCXXRewrittenBinaryOperator(
2984 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2985 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2986 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2987 RHS, /*RequiresADL*/false);
2988 }
2989
2990 /// Build a new conditional operator expression.
2991 ///
2992 /// By default, performs semantic analysis to build the new expression.
2993 /// Subclasses may override this routine to provide different behavior.
2994 ExprResult RebuildConditionalOperator(Expr *Cond,
2995 SourceLocation QuestionLoc,
2996 Expr *LHS,
2997 SourceLocation ColonLoc,
2998 Expr *RHS) {
2999 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
3000 LHS, RHS);
3001 }
3002
3003 /// Build a new C-style cast expression.
3004 ///
3005 /// By default, performs semantic analysis to build the new expression.
3006 /// Subclasses may override this routine to provide different behavior.
3007 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3008 TypeSourceInfo *TInfo,
3009 SourceLocation RParenLoc,
3010 Expr *SubExpr) {
3011 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3012 SubExpr);
3013 }
3014
3015 /// Build a new compound literal expression.
3016 ///
3017 /// By default, performs semantic analysis to build the new expression.
3018 /// Subclasses may override this routine to provide different behavior.
3019 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3020 TypeSourceInfo *TInfo,
3021 SourceLocation RParenLoc,
3022 Expr *Init) {
3023 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3024 Init);
3025 }
3026
3027 /// Build a new extended vector element access expression.
3028 ///
3029 /// By default, performs semantic analysis to build the new expression.
3030 /// Subclasses may override this routine to provide different behavior.
3031 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3032 bool IsArrow,
3033 SourceLocation AccessorLoc,
3034 IdentifierInfo &Accessor) {
3035
3036 CXXScopeSpec SS;
3037 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3038 return getSema().BuildMemberReferenceExpr(
3039 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3040 /*FirstQualifierInScope*/ nullptr, NameInfo,
3041 /* TemplateArgs */ nullptr,
3042 /*S*/ nullptr);
3043 }
3044
3045 /// Build a new initializer list expression.
3046 ///
3047 /// By default, performs semantic analysis to build the new expression.
3048 /// Subclasses may override this routine to provide different behavior.
3049 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3050 MultiExprArg Inits,
3051 SourceLocation RBraceLoc) {
3052 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3053 }
3054
3055 /// Build a new designated initializer 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 RebuildDesignatedInitExpr(Designation &Desig,
3060 MultiExprArg ArrayExprs,
3061 SourceLocation EqualOrColonLoc,
3062 bool GNUSyntax,
3063 Expr *Init) {
3064 ExprResult Result
3065 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3066 Init);
3067 if (Result.isInvalid())
3068 return ExprError();
3069
3070 return Result;
3071 }
3072
3073 /// Build a new value-initialized expression.
3074 ///
3075 /// By default, builds the implicit value initialization without performing
3076 /// any semantic analysis. Subclasses may override this routine to provide
3077 /// different behavior.
3078 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3079 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3080 }
3081
3082 /// Build a new \c va_arg expression.
3083 ///
3084 /// By default, performs semantic analysis to build the new expression.
3085 /// Subclasses may override this routine to provide different behavior.
3086 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3087 Expr *SubExpr, TypeSourceInfo *TInfo,
3088 SourceLocation RParenLoc) {
3089 return getSema().BuildVAArgExpr(BuiltinLoc,
3090 SubExpr, TInfo,
3091 RParenLoc);
3092 }
3093
3094 /// Build a new expression list in parentheses.
3095 ///
3096 /// By default, performs semantic analysis to build the new expression.
3097 /// Subclasses may override this routine to provide different behavior.
3098 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3099 MultiExprArg SubExprs,
3100 SourceLocation RParenLoc) {
3101 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3102 }
3103
3104 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3105 unsigned NumUserSpecifiedExprs,
3106 SourceLocation InitLoc,
3107 SourceLocation LParenLoc,
3108 SourceLocation RParenLoc) {
3109 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3110 InitLoc, LParenLoc, RParenLoc);
3111 }
3112
3113 /// Build a new address-of-label expression.
3114 ///
3115 /// By default, performs semantic analysis, using the name of the label
3116 /// rather than attempting to map the label statement itself.
3117 /// Subclasses may override this routine to provide different behavior.
3118 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3119 SourceLocation LabelLoc, LabelDecl *Label) {
3120 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3121 }
3122
3123 /// Build a new GNU statement expression.
3124 ///
3125 /// By default, performs semantic analysis to build the new expression.
3126 /// Subclasses may override this routine to provide different behavior.
3127 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3128 SourceLocation RParenLoc, unsigned TemplateDepth) {
3129 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3130 TemplateDepth);
3131 }
3132
3133 /// Build a new __builtin_choose_expr 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 RebuildChooseExpr(SourceLocation BuiltinLoc,
3138 Expr *Cond, Expr *LHS, Expr *RHS,
3139 SourceLocation RParenLoc) {
3140 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3141 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3142 RPLoc: RParenLoc);
3143 }
3144
3145 /// Build a new generic selection expression with an expression predicate.
3146 ///
3147 /// By default, performs semantic analysis to build the new expression.
3148 /// Subclasses may override this routine to provide different behavior.
3149 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3150 SourceLocation DefaultLoc,
3151 SourceLocation RParenLoc,
3152 Expr *ControllingExpr,
3153 ArrayRef<TypeSourceInfo *> Types,
3154 ArrayRef<Expr *> Exprs) {
3155 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3156 /*PredicateIsExpr=*/true,
3157 ControllingExpr, Types, Exprs);
3158 }
3159
3160 /// Build a new generic selection expression with a type predicate.
3161 ///
3162 /// By default, performs semantic analysis to build the new expression.
3163 /// Subclasses may override this routine to provide different behavior.
3164 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3165 SourceLocation DefaultLoc,
3166 SourceLocation RParenLoc,
3167 TypeSourceInfo *ControllingType,
3168 ArrayRef<TypeSourceInfo *> Types,
3169 ArrayRef<Expr *> Exprs) {
3170 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3171 /*PredicateIsExpr=*/false,
3172 ControllingType, Types, Exprs);
3173 }
3174
3175 /// Build a new overloaded operator call expression.
3176 ///
3177 /// By default, performs semantic analysis to build the new expression.
3178 /// The semantic analysis provides the behavior of template instantiation,
3179 /// copying with transformations that turn what looks like an overloaded
3180 /// operator call into a use of a builtin operator, performing
3181 /// argument-dependent lookup, etc. Subclasses may override this routine to
3182 /// provide different behavior.
3183 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3184 SourceLocation OpLoc,
3185 SourceLocation CalleeLoc,
3186 bool RequiresADL,
3187 const UnresolvedSetImpl &Functions,
3188 Expr *First, Expr *Second);
3189
3190 /// Build a new C++ "named" cast expression, such as static_cast or
3191 /// reinterpret_cast.
3192 ///
3193 /// By default, this routine dispatches to one of the more-specific routines
3194 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3195 /// Subclasses may override this routine to provide different behavior.
3196 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3197 Stmt::StmtClass Class,
3198 SourceLocation LAngleLoc,
3199 TypeSourceInfo *TInfo,
3200 SourceLocation RAngleLoc,
3201 SourceLocation LParenLoc,
3202 Expr *SubExpr,
3203 SourceLocation RParenLoc) {
3204 switch (Class) {
3205 case Stmt::CXXStaticCastExprClass:
3206 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3207 RAngleLoc, LParenLoc,
3208 SubExpr, RParenLoc);
3209
3210 case Stmt::CXXDynamicCastExprClass:
3211 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3212 RAngleLoc, LParenLoc,
3213 SubExpr, RParenLoc);
3214
3215 case Stmt::CXXReinterpretCastExprClass:
3216 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3217 RAngleLoc, LParenLoc,
3218 SubExpr,
3219 RParenLoc);
3220
3221 case Stmt::CXXConstCastExprClass:
3222 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3223 RAngleLoc, LParenLoc,
3224 SubExpr, RParenLoc);
3225
3226 case Stmt::CXXAddrspaceCastExprClass:
3227 return getDerived().RebuildCXXAddrspaceCastExpr(
3228 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3229
3230 default:
3231 llvm_unreachable("Invalid C++ named cast");
3232 }
3233 }
3234
3235 /// Build a new C++ static_cast expression.
3236 ///
3237 /// By default, performs semantic analysis to build the new expression.
3238 /// Subclasses may override this routine to provide different behavior.
3239 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3240 SourceLocation LAngleLoc,
3241 TypeSourceInfo *TInfo,
3242 SourceLocation RAngleLoc,
3243 SourceLocation LParenLoc,
3244 Expr *SubExpr,
3245 SourceLocation RParenLoc) {
3246 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3247 TInfo, SubExpr,
3248 SourceRange(LAngleLoc, RAngleLoc),
3249 SourceRange(LParenLoc, RParenLoc));
3250 }
3251
3252 /// Build a new C++ dynamic_cast expression.
3253 ///
3254 /// By default, performs semantic analysis to build the new expression.
3255 /// Subclasses may override this routine to provide different behavior.
3256 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3257 SourceLocation LAngleLoc,
3258 TypeSourceInfo *TInfo,
3259 SourceLocation RAngleLoc,
3260 SourceLocation LParenLoc,
3261 Expr *SubExpr,
3262 SourceLocation RParenLoc) {
3263 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3264 TInfo, SubExpr,
3265 SourceRange(LAngleLoc, RAngleLoc),
3266 SourceRange(LParenLoc, RParenLoc));
3267 }
3268
3269 /// Build a new C++ reinterpret_cast expression.
3270 ///
3271 /// By default, performs semantic analysis to build the new expression.
3272 /// Subclasses may override this routine to provide different behavior.
3273 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3274 SourceLocation LAngleLoc,
3275 TypeSourceInfo *TInfo,
3276 SourceLocation RAngleLoc,
3277 SourceLocation LParenLoc,
3278 Expr *SubExpr,
3279 SourceLocation RParenLoc) {
3280 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3281 TInfo, SubExpr,
3282 SourceRange(LAngleLoc, RAngleLoc),
3283 SourceRange(LParenLoc, RParenLoc));
3284 }
3285
3286 /// Build a new C++ const_cast expression.
3287 ///
3288 /// By default, performs semantic analysis to build the new expression.
3289 /// Subclasses may override this routine to provide different behavior.
3290 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3291 SourceLocation LAngleLoc,
3292 TypeSourceInfo *TInfo,
3293 SourceLocation RAngleLoc,
3294 SourceLocation LParenLoc,
3295 Expr *SubExpr,
3296 SourceLocation RParenLoc) {
3297 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3298 TInfo, SubExpr,
3299 SourceRange(LAngleLoc, RAngleLoc),
3300 SourceRange(LParenLoc, RParenLoc));
3301 }
3302
3303 ExprResult
3304 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3305 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3306 SourceLocation LParenLoc, Expr *SubExpr,
3307 SourceLocation RParenLoc) {
3308 return getSema().BuildCXXNamedCast(
3309 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3310 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3311 }
3312
3313 /// Build a new C++ functional-style cast expression.
3314 ///
3315 /// By default, performs semantic analysis to build the new expression.
3316 /// Subclasses may override this routine to provide different behavior.
3317 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3318 SourceLocation LParenLoc,
3319 Expr *Sub,
3320 SourceLocation RParenLoc,
3321 bool ListInitialization) {
3322 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3323 // CXXParenListInitExpr. Pass its expanded arguments so that the
3324 // CXXParenListInitExpr can be rebuilt.
3325 if (auto *PLE = dyn_cast<ParenListExpr>(Val: Sub))
3326 return getSema().BuildCXXTypeConstructExpr(
3327 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3328 RParenLoc, ListInitialization);
3329
3330 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Val: Sub))
3331 return getSema().BuildCXXTypeConstructExpr(
3332 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3333
3334 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3335 MultiExprArg(&Sub, 1), RParenLoc,
3336 ListInitialization);
3337 }
3338
3339 /// Build a new C++ __builtin_bit_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 RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3344 TypeSourceInfo *TSI, Expr *Sub,
3345 SourceLocation RParenLoc) {
3346 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3347 }
3348
3349 /// Build a new C++ typeid(type) expression.
3350 ///
3351 /// By default, performs semantic analysis to build the new expression.
3352 /// Subclasses may override this routine to provide different behavior.
3353 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3354 SourceLocation TypeidLoc,
3355 TypeSourceInfo *Operand,
3356 SourceLocation RParenLoc) {
3357 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3358 RParenLoc);
3359 }
3360
3361
3362 /// Build a new C++ typeid(expr) expression.
3363 ///
3364 /// By default, performs semantic analysis to build the new expression.
3365 /// Subclasses may override this routine to provide different behavior.
3366 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3367 SourceLocation TypeidLoc,
3368 Expr *Operand,
3369 SourceLocation RParenLoc) {
3370 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3371 RParenLoc);
3372 }
3373
3374 /// Build a new C++ __uuidof(type) expression.
3375 ///
3376 /// By default, performs semantic analysis to build the new expression.
3377 /// Subclasses may override this routine to provide different behavior.
3378 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3379 TypeSourceInfo *Operand,
3380 SourceLocation RParenLoc) {
3381 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3382 }
3383
3384 /// Build a new C++ __uuidof(expr) expression.
3385 ///
3386 /// By default, performs semantic analysis to build the new expression.
3387 /// Subclasses may override this routine to provide different behavior.
3388 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3389 Expr *Operand, SourceLocation RParenLoc) {
3390 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3391 }
3392
3393 /// Build a new C++ "this" expression.
3394 ///
3395 /// By default, performs semantic analysis to build a new "this" expression.
3396 /// Subclasses may override this routine to provide different behavior.
3397 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3398 QualType ThisType,
3399 bool isImplicit) {
3400 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3401 return ExprError();
3402 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3403 }
3404
3405 /// Build a new C++ throw expression.
3406 ///
3407 /// By default, performs semantic analysis to build the new expression.
3408 /// Subclasses may override this routine to provide different behavior.
3409 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3410 bool IsThrownVariableInScope) {
3411 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3412 }
3413
3414 /// Build a new C++ default-argument expression.
3415 ///
3416 /// By default, builds a new default-argument expression, which does not
3417 /// require any semantic analysis. Subclasses may override this routine to
3418 /// provide different behavior.
3419 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3420 Expr *RewrittenExpr) {
3421 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3422 RewrittenExpr, UsedContext: getSema().CurContext);
3423 }
3424
3425 /// Build a new C++11 default-initialization expression.
3426 ///
3427 /// By default, builds a new default field initialization expression, which
3428 /// does not require any semantic analysis. Subclasses may override this
3429 /// routine to provide different behavior.
3430 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3431 FieldDecl *Field) {
3432 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3433 }
3434
3435 /// Build a new C++ zero-initialization expression.
3436 ///
3437 /// By default, performs semantic analysis to build the new expression.
3438 /// Subclasses may override this routine to provide different behavior.
3439 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3440 SourceLocation LParenLoc,
3441 SourceLocation RParenLoc) {
3442 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3443 /*ListInitialization=*/false);
3444 }
3445
3446 /// Build a new C++ "new" expression.
3447 ///
3448 /// By default, performs semantic analysis to build the new expression.
3449 /// Subclasses may override this routine to provide different behavior.
3450 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3451 SourceLocation PlacementLParen,
3452 MultiExprArg PlacementArgs,
3453 SourceLocation PlacementRParen,
3454 SourceRange TypeIdParens, QualType AllocatedType,
3455 TypeSourceInfo *AllocatedTypeInfo,
3456 std::optional<Expr *> ArraySize,
3457 SourceRange DirectInitRange, Expr *Initializer) {
3458 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3459 PlacementLParen,
3460 PlacementArgs,
3461 PlacementRParen,
3462 TypeIdParens,
3463 AllocatedType,
3464 AllocatedTypeInfo,
3465 ArraySize,
3466 DirectInitRange,
3467 Initializer);
3468 }
3469
3470 /// Build a new C++ "delete" expression.
3471 ///
3472 /// By default, performs semantic analysis to build the new expression.
3473 /// Subclasses may override this routine to provide different behavior.
3474 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3475 bool IsGlobalDelete,
3476 bool IsArrayForm,
3477 Expr *Operand) {
3478 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3479 Operand);
3480 }
3481
3482 /// Build a new type trait expression.
3483 ///
3484 /// By default, performs semantic analysis to build the new expression.
3485 /// Subclasses may override this routine to provide different behavior.
3486 ExprResult RebuildTypeTrait(TypeTrait Trait,
3487 SourceLocation StartLoc,
3488 ArrayRef<TypeSourceInfo *> Args,
3489 SourceLocation RParenLoc) {
3490 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3491 }
3492
3493 /// Build a new array type trait expression.
3494 ///
3495 /// By default, performs semantic analysis to build the new expression.
3496 /// Subclasses may override this routine to provide different behavior.
3497 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3498 SourceLocation StartLoc,
3499 TypeSourceInfo *TSInfo,
3500 Expr *DimExpr,
3501 SourceLocation RParenLoc) {
3502 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3503 }
3504
3505 /// Build a new expression trait expression.
3506 ///
3507 /// By default, performs semantic analysis to build the new expression.
3508 /// Subclasses may override this routine to provide different behavior.
3509 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3510 SourceLocation StartLoc,
3511 Expr *Queried,
3512 SourceLocation RParenLoc) {
3513 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3514 }
3515
3516 /// Build a new (previously unresolved) declaration reference
3517 /// expression.
3518 ///
3519 /// By default, performs semantic analysis to build the new expression.
3520 /// Subclasses may override this routine to provide different behavior.
3521 ExprResult RebuildDependentScopeDeclRefExpr(
3522 NestedNameSpecifierLoc QualifierLoc,
3523 SourceLocation TemplateKWLoc,
3524 const DeclarationNameInfo &NameInfo,
3525 const TemplateArgumentListInfo *TemplateArgs,
3526 bool IsAddressOfOperand,
3527 TypeSourceInfo **RecoveryTSI) {
3528 CXXScopeSpec SS;
3529 SS.Adopt(Other: QualifierLoc);
3530
3531 if (TemplateArgs || TemplateKWLoc.isValid())
3532 return getSema().BuildQualifiedTemplateIdExpr(
3533 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3534
3535 return getSema().BuildQualifiedDeclarationNameExpr(
3536 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3537 }
3538
3539 /// Build a new template-id expression.
3540 ///
3541 /// By default, performs semantic analysis to build the new expression.
3542 /// Subclasses may override this routine to provide different behavior.
3543 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3544 SourceLocation TemplateKWLoc,
3545 LookupResult &R,
3546 bool RequiresADL,
3547 const TemplateArgumentListInfo *TemplateArgs) {
3548 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3549 TemplateArgs);
3550 }
3551
3552 /// Build a new object-construction expression.
3553 ///
3554 /// By default, performs semantic analysis to build the new expression.
3555 /// Subclasses may override this routine to provide different behavior.
3556 ExprResult RebuildCXXConstructExpr(
3557 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3558 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3559 bool ListInitialization, bool StdInitListInitialization,
3560 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3561 SourceRange ParenRange) {
3562 // Reconstruct the constructor we originally found, which might be
3563 // different if this is a call to an inherited constructor.
3564 CXXConstructorDecl *FoundCtor = Constructor;
3565 if (Constructor->isInheritingConstructor())
3566 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3567
3568 SmallVector<Expr *, 8> ConvertedArgs;
3569 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3570 ConvertedArgs))
3571 return ExprError();
3572
3573 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3574 IsElidable,
3575 ConvertedArgs,
3576 HadMultipleCandidates,
3577 ListInitialization,
3578 StdInitListInitialization,
3579 RequiresZeroInit, ConstructKind,
3580 ParenRange);
3581 }
3582
3583 /// Build a new implicit construction via inherited constructor
3584 /// expression.
3585 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3586 CXXConstructorDecl *Constructor,
3587 bool ConstructsVBase,
3588 bool InheritedFromVBase) {
3589 return new (getSema().Context) CXXInheritedCtorInitExpr(
3590 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3591 }
3592
3593 /// Build a new object-construction expression.
3594 ///
3595 /// By default, performs semantic analysis to build the new expression.
3596 /// Subclasses may override this routine to provide different behavior.
3597 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3598 SourceLocation LParenOrBraceLoc,
3599 MultiExprArg Args,
3600 SourceLocation RParenOrBraceLoc,
3601 bool ListInitialization) {
3602 return getSema().BuildCXXTypeConstructExpr(
3603 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3604 }
3605
3606 /// Build a new object-construction expression.
3607 ///
3608 /// By default, performs semantic analysis to build the new expression.
3609 /// Subclasses may override this routine to provide different behavior.
3610 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3611 SourceLocation LParenLoc,
3612 MultiExprArg Args,
3613 SourceLocation RParenLoc,
3614 bool ListInitialization) {
3615 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3616 RParenLoc, ListInitialization);
3617 }
3618
3619 /// Build a new member reference expression.
3620 ///
3621 /// By default, performs semantic analysis to build the new expression.
3622 /// Subclasses may override this routine to provide different behavior.
3623 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3624 QualType BaseType,
3625 bool IsArrow,
3626 SourceLocation OperatorLoc,
3627 NestedNameSpecifierLoc QualifierLoc,
3628 SourceLocation TemplateKWLoc,
3629 NamedDecl *FirstQualifierInScope,
3630 const DeclarationNameInfo &MemberNameInfo,
3631 const TemplateArgumentListInfo *TemplateArgs) {
3632 CXXScopeSpec SS;
3633 SS.Adopt(Other: QualifierLoc);
3634
3635 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3636 OpLoc: OperatorLoc, IsArrow,
3637 SS, TemplateKWLoc,
3638 FirstQualifierInScope,
3639 NameInfo: MemberNameInfo,
3640 TemplateArgs, /*S*/S: nullptr);
3641 }
3642
3643 /// Build a new member reference expression.
3644 ///
3645 /// By default, performs semantic analysis to build the new expression.
3646 /// Subclasses may override this routine to provide different behavior.
3647 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3648 SourceLocation OperatorLoc,
3649 bool IsArrow,
3650 NestedNameSpecifierLoc QualifierLoc,
3651 SourceLocation TemplateKWLoc,
3652 NamedDecl *FirstQualifierInScope,
3653 LookupResult &R,
3654 const TemplateArgumentListInfo *TemplateArgs) {
3655 CXXScopeSpec SS;
3656 SS.Adopt(Other: QualifierLoc);
3657
3658 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3659 OpLoc: OperatorLoc, IsArrow,
3660 SS, TemplateKWLoc,
3661 FirstQualifierInScope,
3662 R, TemplateArgs, /*S*/S: nullptr);
3663 }
3664
3665 /// Build a new noexcept expression.
3666 ///
3667 /// By default, performs semantic analysis to build the new expression.
3668 /// Subclasses may override this routine to provide different behavior.
3669 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3670 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3671 }
3672
3673 UnsignedOrNone
3674 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3675
3676 /// Build a new expression to compute the length of a parameter pack.
3677 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3678 SourceLocation PackLoc,
3679 SourceLocation RParenLoc,
3680 UnsignedOrNone Length,
3681 ArrayRef<TemplateArgument> PartialArgs) {
3682 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3683 RParenLoc, Length, PartialArgs);
3684 }
3685
3686 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3687 SourceLocation RSquareLoc,
3688 Expr *PackIdExpression, Expr *IndexExpr,
3689 ArrayRef<Expr *> ExpandedExprs,
3690 bool FullySubstituted = false) {
3691 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3692 IndexExpr, RSquareLoc, ExpandedExprs,
3693 FullySubstituted);
3694 }
3695
3696 /// Build a new expression representing a call to a source location
3697 /// builtin.
3698 ///
3699 /// By default, performs semantic analysis to build the new expression.
3700 /// Subclasses may override this routine to provide different behavior.
3701 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3702 SourceLocation BuiltinLoc,
3703 SourceLocation RPLoc,
3704 DeclContext *ParentContext) {
3705 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3706 ParentContext);
3707 }
3708
3709 /// Build a new Objective-C boxed expression.
3710 ///
3711 /// By default, performs semantic analysis to build the new expression.
3712 /// Subclasses may override this routine to provide different behavior.
3713 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3714 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3715 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3716 TemplateArgumentListInfo *TALI) {
3717 CXXScopeSpec SS;
3718 SS.Adopt(Other: NNS);
3719 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3720 ConceptNameInfo,
3721 FoundDecl,
3722 NamedConcept, TALI);
3723 if (Result.isInvalid())
3724 return ExprError();
3725 return Result;
3726 }
3727
3728 /// \brief Build a new requires expression.
3729 ///
3730 /// By default, performs semantic analysis to build the new expression.
3731 /// Subclasses may override this routine to provide different behavior.
3732 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3733 RequiresExprBodyDecl *Body,
3734 SourceLocation LParenLoc,
3735 ArrayRef<ParmVarDecl *> LocalParameters,
3736 SourceLocation RParenLoc,
3737 ArrayRef<concepts::Requirement *> Requirements,
3738 SourceLocation ClosingBraceLoc) {
3739 return RequiresExpr::Create(C&: SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3740 LocalParameters, RParenLoc, Requirements,
3741 RBraceLoc: ClosingBraceLoc);
3742 }
3743
3744 concepts::TypeRequirement *
3745 RebuildTypeRequirement(
3746 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3747 return SemaRef.BuildTypeRequirement(SubstDiag);
3748 }
3749
3750 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3751 return SemaRef.BuildTypeRequirement(Type: T);
3752 }
3753
3754 concepts::ExprRequirement *
3755 RebuildExprRequirement(
3756 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3757 SourceLocation NoexceptLoc,
3758 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3759 return SemaRef.BuildExprRequirement(ExprSubstDiag: SubstDiag, IsSatisfied: IsSimple, NoexceptLoc,
3760 ReturnTypeRequirement: std::move(Ret));
3761 }
3762
3763 concepts::ExprRequirement *
3764 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3765 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3766 return SemaRef.BuildExprRequirement(E, IsSatisfied: IsSimple, NoexceptLoc,
3767 ReturnTypeRequirement: std::move(Ret));
3768 }
3769
3770 concepts::NestedRequirement *
3771 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3772 const ASTConstraintSatisfaction &Satisfaction) {
3773 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3774 Satisfaction);
3775 }
3776
3777 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3778 return SemaRef.BuildNestedRequirement(E: Constraint);
3779 }
3780
3781 /// \brief Build a new Objective-C boxed expression.
3782 ///
3783 /// By default, performs semantic analysis to build the new expression.
3784 /// Subclasses may override this routine to provide different behavior.
3785 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3786 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3787 }
3788
3789 /// Build a new Objective-C array literal.
3790 ///
3791 /// By default, performs semantic analysis to build the new expression.
3792 /// Subclasses may override this routine to provide different behavior.
3793 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3794 Expr **Elements, unsigned NumElements) {
3795 return getSema().ObjC().BuildObjCArrayLiteral(
3796 Range, MultiExprArg(Elements, NumElements));
3797 }
3798
3799 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3800 Expr *Base, Expr *Key,
3801 ObjCMethodDecl *getterMethod,
3802 ObjCMethodDecl *setterMethod) {
3803 return getSema().ObjC().BuildObjCSubscriptExpression(
3804 RB, Base, Key, getterMethod, setterMethod);
3805 }
3806
3807 /// Build a new Objective-C dictionary literal.
3808 ///
3809 /// By default, performs semantic analysis to build the new expression.
3810 /// Subclasses may override this routine to provide different behavior.
3811 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3812 MutableArrayRef<ObjCDictionaryElement> Elements) {
3813 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3814 }
3815
3816 /// Build a new Objective-C \@encode expression.
3817 ///
3818 /// By default, performs semantic analysis to build the new expression.
3819 /// Subclasses may override this routine to provide different behavior.
3820 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3821 TypeSourceInfo *EncodeTypeInfo,
3822 SourceLocation RParenLoc) {
3823 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3824 RParenLoc);
3825 }
3826
3827 /// Build a new Objective-C class message.
3828 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3829 Selector Sel,
3830 ArrayRef<SourceLocation> SelectorLocs,
3831 ObjCMethodDecl *Method,
3832 SourceLocation LBracLoc,
3833 MultiExprArg Args,
3834 SourceLocation RBracLoc) {
3835 return SemaRef.ObjC().BuildClassMessage(
3836 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3837 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3838 RBracLoc, Args);
3839 }
3840
3841 /// Build a new Objective-C instance message.
3842 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3843 Selector Sel,
3844 ArrayRef<SourceLocation> SelectorLocs,
3845 ObjCMethodDecl *Method,
3846 SourceLocation LBracLoc,
3847 MultiExprArg Args,
3848 SourceLocation RBracLoc) {
3849 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3850 /*SuperLoc=*/SuperLoc: SourceLocation(),
3851 Sel, Method, LBracLoc,
3852 SelectorLocs, RBracLoc, Args);
3853 }
3854
3855 /// Build a new Objective-C instance/class message to 'super'.
3856 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3857 Selector Sel,
3858 ArrayRef<SourceLocation> SelectorLocs,
3859 QualType SuperType,
3860 ObjCMethodDecl *Method,
3861 SourceLocation LBracLoc,
3862 MultiExprArg Args,
3863 SourceLocation RBracLoc) {
3864 return Method->isInstanceMethod()
3865 ? SemaRef.ObjC().BuildInstanceMessage(
3866 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3867 SelectorLocs, RBracLoc, Args)
3868 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3869 Sel, Method, LBracLoc,
3870 SelectorLocs, RBracLoc, Args);
3871 }
3872
3873 /// Build a new Objective-C ivar reference expression.
3874 ///
3875 /// By default, performs semantic analysis to build the new expression.
3876 /// Subclasses may override this routine to provide different behavior.
3877 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3878 SourceLocation IvarLoc,
3879 bool IsArrow, bool IsFreeIvar) {
3880 CXXScopeSpec SS;
3881 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3882 ExprResult Result = getSema().BuildMemberReferenceExpr(
3883 BaseArg, BaseArg->getType(),
3884 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3885 /*FirstQualifierInScope=*/nullptr, NameInfo,
3886 /*TemplateArgs=*/nullptr,
3887 /*S=*/nullptr);
3888 if (IsFreeIvar && Result.isUsable())
3889 cast<ObjCIvarRefExpr>(Val: Result.get())->setIsFreeIvar(IsFreeIvar);
3890 return Result;
3891 }
3892
3893 /// Build a new Objective-C property reference expression.
3894 ///
3895 /// By default, performs semantic analysis to build the new expression.
3896 /// Subclasses may override this routine to provide different behavior.
3897 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3898 ObjCPropertyDecl *Property,
3899 SourceLocation PropertyLoc) {
3900 CXXScopeSpec SS;
3901 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3902 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3903 /*FIXME:*/PropertyLoc,
3904 /*IsArrow=*/false,
3905 SS, SourceLocation(),
3906 /*FirstQualifierInScope=*/nullptr,
3907 NameInfo,
3908 /*TemplateArgs=*/nullptr,
3909 /*S=*/nullptr);
3910 }
3911
3912 /// Build a new Objective-C property reference expression.
3913 ///
3914 /// By default, performs semantic analysis to build the new expression.
3915 /// Subclasses may override this routine to provide different behavior.
3916 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3917 ObjCMethodDecl *Getter,
3918 ObjCMethodDecl *Setter,
3919 SourceLocation PropertyLoc) {
3920 // Since these expressions can only be value-dependent, we do not
3921 // need to perform semantic analysis again.
3922 return Owned(
3923 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3924 VK_LValue, OK_ObjCProperty,
3925 PropertyLoc, Base));
3926 }
3927
3928 /// Build a new Objective-C "isa" expression.
3929 ///
3930 /// By default, performs semantic analysis to build the new expression.
3931 /// Subclasses may override this routine to provide different behavior.
3932 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3933 SourceLocation OpLoc, bool IsArrow) {
3934 CXXScopeSpec SS;
3935 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3936 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3937 OpLoc, IsArrow,
3938 SS, SourceLocation(),
3939 /*FirstQualifierInScope=*/nullptr,
3940 NameInfo,
3941 /*TemplateArgs=*/nullptr,
3942 /*S=*/nullptr);
3943 }
3944
3945 /// Build a new shuffle vector expression.
3946 ///
3947 /// By default, performs semantic analysis to build the new expression.
3948 /// Subclasses may override this routine to provide different behavior.
3949 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3950 MultiExprArg SubExprs,
3951 SourceLocation RParenLoc) {
3952 // Find the declaration for __builtin_shufflevector
3953 const IdentifierInfo &Name
3954 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
3955 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3956 DeclContext::lookup_result Lookup = TUDecl->lookup(Name: DeclarationName(&Name));
3957 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3958
3959 // Build a reference to the __builtin_shufflevector builtin
3960 FunctionDecl *Builtin = cast<FunctionDecl>(Val: Lookup.front());
3961 Expr *Callee = new (SemaRef.Context)
3962 DeclRefExpr(SemaRef.Context, Builtin, false,
3963 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3964 QualType CalleePtrTy = SemaRef.Context.getPointerType(T: Builtin->getType());
3965 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
3966 CK: CK_BuiltinFnToFnPtr).get();
3967
3968 // Build the CallExpr
3969 ExprResult TheCall = CallExpr::Create(
3970 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
3971 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
3972 FPFeatures: FPOptionsOverride());
3973
3974 // Type-check the __builtin_shufflevector expression.
3975 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(Val: TheCall.get()));
3976 }
3977
3978 /// Build a new convert vector expression.
3979 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3980 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3981 SourceLocation RParenLoc) {
3982 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
3983 }
3984
3985 /// Build a new template argument pack expansion.
3986 ///
3987 /// By default, performs semantic analysis to build a new pack expansion
3988 /// for a template argument. Subclasses may override this routine to provide
3989 /// different behavior.
3990 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
3991 SourceLocation EllipsisLoc,
3992 UnsignedOrNone NumExpansions) {
3993 switch (Pattern.getArgument().getKind()) {
3994 case TemplateArgument::Expression: {
3995 ExprResult Result
3996 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3997 EllipsisLoc, NumExpansions);
3998 if (Result.isInvalid())
3999 return TemplateArgumentLoc();
4000
4001 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4002 /*IsCanonical=*/false),
4003 Result.get());
4004 }
4005
4006 case TemplateArgument::Template:
4007 return TemplateArgumentLoc(
4008 SemaRef.Context,
4009 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4010 NumExpansions),
4011 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
4012 EllipsisLoc);
4013
4014 case TemplateArgument::Null:
4015 case TemplateArgument::Integral:
4016 case TemplateArgument::Declaration:
4017 case TemplateArgument::StructuralValue:
4018 case TemplateArgument::Pack:
4019 case TemplateArgument::TemplateExpansion:
4020 case TemplateArgument::NullPtr:
4021 llvm_unreachable("Pack expansion pattern has no parameter packs");
4022
4023 case TemplateArgument::Type:
4024 if (TypeSourceInfo *Expansion
4025 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4026 EllipsisLoc,
4027 NumExpansions))
4028 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4029 Expansion);
4030 break;
4031 }
4032
4033 return TemplateArgumentLoc();
4034 }
4035
4036 /// Build a new expression pack expansion.
4037 ///
4038 /// By default, performs semantic analysis to build a new pack expansion
4039 /// for an expression. Subclasses may override this routine to provide
4040 /// different behavior.
4041 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4042 UnsignedOrNone NumExpansions) {
4043 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4044 }
4045
4046 /// Build a new C++1z fold-expression.
4047 ///
4048 /// By default, performs semantic analysis in order to build a new fold
4049 /// expression.
4050 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4051 SourceLocation LParenLoc, Expr *LHS,
4052 BinaryOperatorKind Operator,
4053 SourceLocation EllipsisLoc, Expr *RHS,
4054 SourceLocation RParenLoc,
4055 UnsignedOrNone NumExpansions) {
4056 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4057 EllipsisLoc, RHS, RParenLoc,
4058 NumExpansions);
4059 }
4060
4061 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4062 LambdaScopeInfo *LSI) {
4063 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4064 if (Expr *Init = PVD->getInit())
4065 LSI->ContainsUnexpandedParameterPack |=
4066 Init->containsUnexpandedParameterPack();
4067 else if (PVD->hasUninstantiatedDefaultArg())
4068 LSI->ContainsUnexpandedParameterPack |=
4069 PVD->getUninstantiatedDefaultArg()
4070 ->containsUnexpandedParameterPack();
4071 }
4072 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4073 }
4074
4075 /// Build an empty C++1z fold-expression with the given operator.
4076 ///
4077 /// By default, produces the fallback value for the fold-expression, or
4078 /// produce an error if there is no fallback value.
4079 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4080 BinaryOperatorKind Operator) {
4081 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4082 }
4083
4084 /// Build a new atomic operation expression.
4085 ///
4086 /// By default, performs semantic analysis to build the new expression.
4087 /// Subclasses may override this routine to provide different behavior.
4088 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4089 AtomicExpr::AtomicOp Op,
4090 SourceLocation RParenLoc) {
4091 // Use this for all of the locations, since we don't know the difference
4092 // between the call and the expr at this point.
4093 SourceRange Range{BuiltinLoc, RParenLoc};
4094 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4095 Sema::AtomicArgumentOrder::AST);
4096 }
4097
4098 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4099 ArrayRef<Expr *> SubExprs, QualType Type) {
4100 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4101 }
4102
4103 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4104 SourceLocation BeginLoc,
4105 SourceLocation DirLoc,
4106 SourceLocation EndLoc,
4107 ArrayRef<OpenACCClause *> Clauses,
4108 StmtResult StrBlock) {
4109 return getSema().OpenACC().ActOnEndStmtDirective(
4110 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4111 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4112 }
4113
4114 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4115 SourceLocation DirLoc,
4116 SourceLocation EndLoc,
4117 ArrayRef<OpenACCClause *> Clauses,
4118 StmtResult Loop) {
4119 return getSema().OpenACC().ActOnEndStmtDirective(
4120 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4121 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4122 Clauses, Loop);
4123 }
4124
4125 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4126 SourceLocation BeginLoc,
4127 SourceLocation DirLoc,
4128 SourceLocation EndLoc,
4129 ArrayRef<OpenACCClause *> Clauses,
4130 StmtResult Loop) {
4131 return getSema().OpenACC().ActOnEndStmtDirective(
4132 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4133 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4134 }
4135
4136 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4137 SourceLocation DirLoc,
4138 SourceLocation EndLoc,
4139 ArrayRef<OpenACCClause *> Clauses,
4140 StmtResult StrBlock) {
4141 return getSema().OpenACC().ActOnEndStmtDirective(
4142 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4143 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4144 Clauses, StrBlock);
4145 }
4146
4147 StmtResult
4148 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4149 SourceLocation DirLoc, SourceLocation EndLoc,
4150 ArrayRef<OpenACCClause *> Clauses) {
4151 return getSema().OpenACC().ActOnEndStmtDirective(
4152 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4153 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4154 Clauses, {});
4155 }
4156
4157 StmtResult
4158 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4159 SourceLocation DirLoc, SourceLocation EndLoc,
4160 ArrayRef<OpenACCClause *> Clauses) {
4161 return getSema().OpenACC().ActOnEndStmtDirective(
4162 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4163 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4164 Clauses, {});
4165 }
4166
4167 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4168 SourceLocation DirLoc,
4169 SourceLocation EndLoc,
4170 ArrayRef<OpenACCClause *> Clauses,
4171 StmtResult StrBlock) {
4172 return getSema().OpenACC().ActOnEndStmtDirective(
4173 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4174 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4175 Clauses, StrBlock);
4176 }
4177
4178 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4179 SourceLocation DirLoc,
4180 SourceLocation EndLoc,
4181 ArrayRef<OpenACCClause *> Clauses) {
4182 return getSema().OpenACC().ActOnEndStmtDirective(
4183 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4184 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4185 Clauses, {});
4186 }
4187
4188 StmtResult
4189 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4190 SourceLocation DirLoc, SourceLocation EndLoc,
4191 ArrayRef<OpenACCClause *> Clauses) {
4192 return getSema().OpenACC().ActOnEndStmtDirective(
4193 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4194 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4195 Clauses, {});
4196 }
4197
4198 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4199 SourceLocation DirLoc,
4200 SourceLocation EndLoc,
4201 ArrayRef<OpenACCClause *> Clauses) {
4202 return getSema().OpenACC().ActOnEndStmtDirective(
4203 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4204 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4205 Clauses, {});
4206 }
4207
4208 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4209 SourceLocation DirLoc,
4210 SourceLocation EndLoc,
4211 ArrayRef<OpenACCClause *> Clauses) {
4212 return getSema().OpenACC().ActOnEndStmtDirective(
4213 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4214 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4215 Clauses, {});
4216 }
4217
4218 StmtResult RebuildOpenACCWaitConstruct(
4219 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4220 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4221 SourceLocation RParenLoc, SourceLocation EndLoc,
4222 ArrayRef<OpenACCClause *> Clauses) {
4223 llvm::SmallVector<Expr *> Exprs;
4224 Exprs.push_back(Elt: DevNumExpr);
4225 llvm::append_range(C&: Exprs, R&: QueueIdExprs);
4226 return getSema().OpenACC().ActOnEndStmtDirective(
4227 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4228 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4229 }
4230
4231 StmtResult RebuildOpenACCCacheConstruct(
4232 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4233 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4234 SourceLocation RParenLoc, SourceLocation EndLoc) {
4235 return getSema().OpenACC().ActOnEndStmtDirective(
4236 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4237 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4238 }
4239
4240 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4241 SourceLocation DirLoc,
4242 OpenACCAtomicKind AtKind,
4243 SourceLocation EndLoc,
4244 ArrayRef<OpenACCClause *> Clauses,
4245 StmtResult AssociatedStmt) {
4246 return getSema().OpenACC().ActOnEndStmtDirective(
4247 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4248 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4249 AssociatedStmt);
4250 }
4251
4252 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4253 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4254 }
4255
4256private:
4257 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4258 QualType ObjectType,
4259 NamedDecl *FirstQualifierInScope,
4260 CXXScopeSpec &SS);
4261
4262 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4263 QualType ObjectType,
4264 NamedDecl *FirstQualifierInScope,
4265 CXXScopeSpec &SS);
4266
4267 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4268 NamedDecl *FirstQualifierInScope,
4269 CXXScopeSpec &SS);
4270
4271 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4272 DependentNameTypeLoc TL,
4273 bool DeducibleTSTContext);
4274
4275 llvm::SmallVector<OpenACCClause *>
4276 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4277 ArrayRef<const OpenACCClause *> OldClauses);
4278
4279 OpenACCClause *
4280 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4281 OpenACCDirectiveKind DirKind,
4282 const OpenACCClause *OldClause);
4283};
4284
4285template <typename Derived>
4286StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4287 if (!S)
4288 return S;
4289
4290 switch (S->getStmtClass()) {
4291 case Stmt::NoStmtClass: break;
4292
4293 // Transform individual statement nodes
4294 // Pass SDK into statements that can produce a value
4295#define STMT(Node, Parent) \
4296 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4297#define VALUESTMT(Node, Parent) \
4298 case Stmt::Node##Class: \
4299 return getDerived().Transform##Node(cast<Node>(S), SDK);
4300#define ABSTRACT_STMT(Node)
4301#define EXPR(Node, Parent)
4302#include "clang/AST/StmtNodes.inc"
4303
4304 // Transform expressions by calling TransformExpr.
4305#define STMT(Node, Parent)
4306#define ABSTRACT_STMT(Stmt)
4307#define EXPR(Node, Parent) case Stmt::Node##Class:
4308#include "clang/AST/StmtNodes.inc"
4309 {
4310 ExprResult E = getDerived().TransformExpr(cast<Expr>(Val: S));
4311
4312 if (SDK == StmtDiscardKind::StmtExprResult)
4313 E = getSema().ActOnStmtExprResult(E);
4314 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4315 }
4316 }
4317
4318 return S;
4319}
4320
4321template<typename Derived>
4322OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4323 if (!S)
4324 return S;
4325
4326 switch (S->getClauseKind()) {
4327 default: break;
4328 // Transform individual clause nodes
4329#define GEN_CLANG_CLAUSE_CLASS
4330#define CLAUSE_CLASS(Enum, Str, Class) \
4331 case Enum: \
4332 return getDerived().Transform##Class(cast<Class>(S));
4333#include "llvm/Frontend/OpenMP/OMP.inc"
4334 }
4335
4336 return S;
4337}
4338
4339
4340template<typename Derived>
4341ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4342 if (!E)
4343 return E;
4344
4345 switch (E->getStmtClass()) {
4346 case Stmt::NoStmtClass: break;
4347#define STMT(Node, Parent) case Stmt::Node##Class: break;
4348#define ABSTRACT_STMT(Stmt)
4349#define EXPR(Node, Parent) \
4350 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4351#include "clang/AST/StmtNodes.inc"
4352 }
4353
4354 return E;
4355}
4356
4357template<typename Derived>
4358ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4359 bool NotCopyInit) {
4360 // Initializers are instantiated like expressions, except that various outer
4361 // layers are stripped.
4362 if (!Init)
4363 return Init;
4364
4365 if (auto *FE = dyn_cast<FullExpr>(Val: Init))
4366 Init = FE->getSubExpr();
4367
4368 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Val: Init)) {
4369 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4370 Init = OVE->getSourceExpr();
4371 }
4372
4373 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Val: Init))
4374 Init = MTE->getSubExpr();
4375
4376 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Val: Init))
4377 Init = Binder->getSubExpr();
4378
4379 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Init))
4380 Init = ICE->getSubExprAsWritten();
4381
4382 if (CXXStdInitializerListExpr *ILE =
4383 dyn_cast<CXXStdInitializerListExpr>(Val: Init))
4384 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4385
4386 // If this is copy-initialization, we only need to reconstruct
4387 // InitListExprs. Other forms of copy-initialization will be a no-op if
4388 // the initializer is already the right type.
4389 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Val: Init);
4390 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4391 return getDerived().TransformExpr(Init);
4392
4393 // Revert value-initialization back to empty parens.
4394 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Val: Init)) {
4395 SourceRange Parens = VIE->getSourceRange();
4396 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4397 Parens.getEnd());
4398 }
4399
4400 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4401 if (isa<ImplicitValueInitExpr>(Val: Init))
4402 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4403 SourceLocation());
4404
4405 // Revert initialization by constructor back to a parenthesized or braced list
4406 // of expressions. Any other form of initializer can just be reused directly.
4407 if (!Construct || isa<CXXTemporaryObjectExpr>(Val: Construct))
4408 return getDerived().TransformExpr(Init);
4409
4410 // If the initialization implicitly converted an initializer list to a
4411 // std::initializer_list object, unwrap the std::initializer_list too.
4412 if (Construct && Construct->isStdInitListInitialization())
4413 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4414
4415 // Enter a list-init context if this was list initialization.
4416 EnterExpressionEvaluationContext Context(
4417 getSema(), EnterExpressionEvaluationContext::InitList,
4418 Construct->isListInitialization());
4419
4420 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4421 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4422 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4423 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4424 SmallVector<Expr*, 8> NewArgs;
4425 bool ArgChanged = false;
4426 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4427 /*IsCall*/true, NewArgs, &ArgChanged))
4428 return ExprError();
4429
4430 // If this was list initialization, revert to syntactic list form.
4431 if (Construct->isListInitialization())
4432 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4433 Construct->getEndLoc());
4434
4435 // Build a ParenListExpr to represent anything else.
4436 SourceRange Parens = Construct->getParenOrBraceRange();
4437 if (Parens.isInvalid()) {
4438 // This was a variable declaration's initialization for which no initializer
4439 // was specified.
4440 assert(NewArgs.empty() &&
4441 "no parens or braces but have direct init with arguments?");
4442 return ExprEmpty();
4443 }
4444 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4445 Parens.getEnd());
4446}
4447
4448template<typename Derived>
4449bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4450 unsigned NumInputs,
4451 bool IsCall,
4452 SmallVectorImpl<Expr *> &Outputs,
4453 bool *ArgChanged) {
4454 for (unsigned I = 0; I != NumInputs; ++I) {
4455 // If requested, drop call arguments that need to be dropped.
4456 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4457 if (ArgChanged)
4458 *ArgChanged = true;
4459
4460 break;
4461 }
4462
4463 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Val: Inputs[I])) {
4464 Expr *Pattern = Expansion->getPattern();
4465
4466 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4467 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4468 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4469
4470 // Determine whether the set of unexpanded parameter packs can and should
4471 // be expanded.
4472 bool Expand = true;
4473 bool RetainExpansion = false;
4474 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4475 UnsignedOrNone NumExpansions = OrigNumExpansions;
4476 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4477 Pattern->getSourceRange(),
4478 Unexpanded,
4479 Expand, RetainExpansion,
4480 NumExpansions))
4481 return true;
4482
4483 if (!Expand) {
4484 // The transform has determined that we should perform a simple
4485 // transformation on the pack expansion, producing another pack
4486 // expansion.
4487 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4488 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4489 if (OutPattern.isInvalid())
4490 return true;
4491
4492 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4493 Expansion->getEllipsisLoc(),
4494 NumExpansions);
4495 if (Out.isInvalid())
4496 return true;
4497
4498 if (ArgChanged)
4499 *ArgChanged = true;
4500 Outputs.push_back(Elt: Out.get());
4501 continue;
4502 }
4503
4504 // Record right away that the argument was changed. This needs
4505 // to happen even if the array expands to nothing.
4506 if (ArgChanged) *ArgChanged = true;
4507
4508 // The transform has determined that we should perform an elementwise
4509 // expansion of the pattern. Do so.
4510 for (unsigned I = 0; I != *NumExpansions; ++I) {
4511 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4512 ExprResult Out = getDerived().TransformExpr(Pattern);
4513 if (Out.isInvalid())
4514 return true;
4515
4516 if (Out.get()->containsUnexpandedParameterPack()) {
4517 Out = getDerived().RebuildPackExpansion(
4518 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4519 if (Out.isInvalid())
4520 return true;
4521 }
4522
4523 Outputs.push_back(Elt: Out.get());
4524 }
4525
4526 // If we're supposed to retain a pack expansion, do so by temporarily
4527 // forgetting the partially-substituted parameter pack.
4528 if (RetainExpansion) {
4529 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4530
4531 ExprResult Out = getDerived().TransformExpr(Pattern);
4532 if (Out.isInvalid())
4533 return true;
4534
4535 Out = getDerived().RebuildPackExpansion(
4536 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4537 if (Out.isInvalid())
4538 return true;
4539
4540 Outputs.push_back(Elt: Out.get());
4541 }
4542
4543 continue;
4544 }
4545
4546 ExprResult Result =
4547 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4548 : getDerived().TransformExpr(Inputs[I]);
4549 if (Result.isInvalid())
4550 return true;
4551
4552 if (Result.get() != Inputs[I] && ArgChanged)
4553 *ArgChanged = true;
4554
4555 Outputs.push_back(Elt: Result.get());
4556 }
4557
4558 return false;
4559}
4560
4561template <typename Derived>
4562Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4563 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4564 if (Var) {
4565 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4566 getDerived().TransformDefinition(Var->getLocation(), Var));
4567
4568 if (!ConditionVar)
4569 return Sema::ConditionError();
4570
4571 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4572 }
4573
4574 if (Expr) {
4575 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4576
4577 if (CondExpr.isInvalid())
4578 return Sema::ConditionError();
4579
4580 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4581 /*MissingOK=*/true);
4582 }
4583
4584 return Sema::ConditionResult();
4585}
4586
4587template <typename Derived>
4588NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4589 NestedNameSpecifierLoc NNS, QualType ObjectType,
4590 NamedDecl *FirstQualifierInScope) {
4591 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4592
4593 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4594 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4595 Qualifier = Qualifier.getPrefix())
4596 Qualifiers.push_back(Elt: Qualifier);
4597 };
4598 insertNNS(NNS);
4599
4600 CXXScopeSpec SS;
4601 while (!Qualifiers.empty()) {
4602 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4603 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4604
4605 switch (QNNS->getKind()) {
4606 case NestedNameSpecifier::Identifier: {
4607 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4608 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4609 ObjectType);
4610 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4611 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4612 return NestedNameSpecifierLoc();
4613 break;
4614 }
4615
4616 case NestedNameSpecifier::Namespace: {
4617 NamespaceDecl *NS =
4618 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4619 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4620 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4621 break;
4622 }
4623
4624 case NestedNameSpecifier::NamespaceAlias: {
4625 NamespaceAliasDecl *Alias =
4626 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4627 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4628 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4629 ColonColonLoc: Q.getLocalEndLoc());
4630 break;
4631 }
4632
4633 case NestedNameSpecifier::Global:
4634 // There is no meaningful transformation that one could perform on the
4635 // global scope.
4636 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4637 break;
4638
4639 case NestedNameSpecifier::Super: {
4640 CXXRecordDecl *RD =
4641 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4642 SourceLocation(), QNNS->getAsRecordDecl()));
4643 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4644 break;
4645 }
4646
4647 case NestedNameSpecifier::TypeSpec: {
4648 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4649 FirstQualifierInScope, SS);
4650
4651 if (!TL)
4652 return NestedNameSpecifierLoc();
4653
4654 QualType T = TL.getType();
4655 if (T->isDependentType() || T->isRecordType() ||
4656 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4657 if (T->isEnumeralType())
4658 SemaRef.Diag(Loc: TL.getBeginLoc(),
4659 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4660
4661 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4662 SS.Adopt(Other: ETL.getQualifierLoc());
4663 TL = ETL.getNamedTypeLoc();
4664 }
4665
4666 SS.Extend(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4667 break;
4668 }
4669 // If the nested-name-specifier is an invalid type def, don't emit an
4670 // error because a previous error should have already been emitted.
4671 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4672 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4673 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4674 << T << SS.getRange();
4675 }
4676 return NestedNameSpecifierLoc();
4677 }
4678 }
4679
4680 // The qualifier-in-scope and object type only apply to the leftmost entity.
4681 FirstQualifierInScope = nullptr;
4682 ObjectType = QualType();
4683 }
4684
4685 // Don't rebuild the nested-name-specifier if we don't have to.
4686 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4687 !getDerived().AlwaysRebuild())
4688 return NNS;
4689
4690 // If we can re-use the source-location data from the original
4691 // nested-name-specifier, do so.
4692 if (SS.location_size() == NNS.getDataLength() &&
4693 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4694 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4695
4696 // Allocate new nested-name-specifier location information.
4697 return SS.getWithLocInContext(Context&: SemaRef.Context);
4698}
4699
4700template<typename Derived>
4701DeclarationNameInfo
4702TreeTransform<Derived>
4703::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4704 DeclarationName Name = NameInfo.getName();
4705 if (!Name)
4706 return DeclarationNameInfo();
4707
4708 switch (Name.getNameKind()) {
4709 case DeclarationName::Identifier:
4710 case DeclarationName::ObjCZeroArgSelector:
4711 case DeclarationName::ObjCOneArgSelector:
4712 case DeclarationName::ObjCMultiArgSelector:
4713 case DeclarationName::CXXOperatorName:
4714 case DeclarationName::CXXLiteralOperatorName:
4715 case DeclarationName::CXXUsingDirective:
4716 return NameInfo;
4717
4718 case DeclarationName::CXXDeductionGuideName: {
4719 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4720 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4721 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4722 if (!NewTemplate)
4723 return DeclarationNameInfo();
4724
4725 DeclarationNameInfo NewNameInfo(NameInfo);
4726 NewNameInfo.setName(
4727 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4728 return NewNameInfo;
4729 }
4730
4731 case DeclarationName::CXXConstructorName:
4732 case DeclarationName::CXXDestructorName:
4733 case DeclarationName::CXXConversionFunctionName: {
4734 TypeSourceInfo *NewTInfo;
4735 CanQualType NewCanTy;
4736 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4737 NewTInfo = getDerived().TransformType(OldTInfo);
4738 if (!NewTInfo)
4739 return DeclarationNameInfo();
4740 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4741 }
4742 else {
4743 NewTInfo = nullptr;
4744 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4745 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4746 if (NewT.isNull())
4747 return DeclarationNameInfo();
4748 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4749 }
4750
4751 DeclarationName NewName
4752 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4753 Ty: NewCanTy);
4754 DeclarationNameInfo NewNameInfo(NameInfo);
4755 NewNameInfo.setName(NewName);
4756 NewNameInfo.setNamedTypeInfo(NewTInfo);
4757 return NewNameInfo;
4758 }
4759 }
4760
4761 llvm_unreachable("Unknown name kind.");
4762}
4763
4764template <typename Derived>
4765TemplateName TreeTransform<Derived>::RebuildTemplateName(
4766 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4767 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4768 QualType ObjectType, NamedDecl *FirstQualifierInScope,
4769 bool AllowInjectedClassName) {
4770 if (const IdentifierInfo *II = IO.getIdentifier()) {
4771 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4772 ObjectType, FirstQualifierInScope,
4773 AllowInjectedClassName);
4774 }
4775 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4776 NameLoc, ObjectType,
4777 AllowInjectedClassName);
4778}
4779
4780template<typename Derived>
4781TemplateName
4782TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4783 TemplateName Name,
4784 SourceLocation NameLoc,
4785 QualType ObjectType,
4786 NamedDecl *FirstQualifierInScope,
4787 bool AllowInjectedClassName) {
4788 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4789 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4790 assert(Template && "qualified template name must refer to a template");
4791
4792 TemplateDecl *TransTemplate
4793 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4794 Template));
4795 if (!TransTemplate)
4796 return TemplateName();
4797
4798 if (!getDerived().AlwaysRebuild() &&
4799 SS.getScopeRep() == QTN->getQualifier() &&
4800 TransTemplate == Template)
4801 return Name;
4802
4803 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4804 TransTemplate);
4805 }
4806
4807 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4808 if (SS.getScopeRep()) {
4809 // These apply to the scope specifier, not the template.
4810 ObjectType = QualType();
4811 FirstQualifierInScope = nullptr;
4812 }
4813
4814 if (!getDerived().AlwaysRebuild() &&
4815 SS.getScopeRep() == DTN->getQualifier() &&
4816 ObjectType.isNull())
4817 return Name;
4818
4819 // FIXME: Preserve the location of the "template" keyword.
4820 SourceLocation TemplateKWLoc = NameLoc;
4821 return getDerived().RebuildTemplateName(
4822 SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType,
4823 FirstQualifierInScope, AllowInjectedClassName);
4824 }
4825
4826 // FIXME: Try to preserve more of the TemplateName.
4827 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4828 TemplateDecl *TransTemplate
4829 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4830 Template));
4831 if (!TransTemplate)
4832 return TemplateName();
4833
4834 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4835 TransTemplate);
4836 }
4837
4838 if (SubstTemplateTemplateParmPackStorage *SubstPack
4839 = Name.getAsSubstTemplateTemplateParmPack()) {
4840 return getDerived().RebuildTemplateName(
4841 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4842 SubstPack->getIndex(), SubstPack->getFinal());
4843 }
4844
4845 // These should be getting filtered out before they reach the AST.
4846 llvm_unreachable("overloaded function decl survived to here");
4847}
4848
4849template<typename Derived>
4850void TreeTransform<Derived>::InventTemplateArgumentLoc(
4851 const TemplateArgument &Arg,
4852 TemplateArgumentLoc &Output) {
4853 Output = getSema().getTrivialTemplateArgumentLoc(
4854 Arg, QualType(), getDerived().getBaseLocation());
4855}
4856
4857template <typename Derived>
4858bool TreeTransform<Derived>::TransformTemplateArgument(
4859 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4860 bool Uneval) {
4861 const TemplateArgument &Arg = Input.getArgument();
4862 switch (Arg.getKind()) {
4863 case TemplateArgument::Null:
4864 case TemplateArgument::Pack:
4865 llvm_unreachable("Unexpected TemplateArgument");
4866
4867 case TemplateArgument::Integral:
4868 case TemplateArgument::NullPtr:
4869 case TemplateArgument::Declaration:
4870 case TemplateArgument::StructuralValue: {
4871 // Transform a resolved template argument straight to a resolved template
4872 // argument. We get here when substituting into an already-substituted
4873 // template type argument during concept satisfaction checking.
4874 QualType T = Arg.getNonTypeTemplateArgumentType();
4875 QualType NewT = getDerived().TransformType(T);
4876 if (NewT.isNull())
4877 return true;
4878
4879 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4880 ? Arg.getAsDecl()
4881 : nullptr;
4882 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4883 getDerived().getBaseLocation(), D))
4884 : nullptr;
4885 if (D && !NewD)
4886 return true;
4887
4888 if (NewT == T && D == NewD)
4889 Output = Input;
4890 else if (Arg.getKind() == TemplateArgument::Integral)
4891 Output = TemplateArgumentLoc(
4892 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4893 TemplateArgumentLocInfo());
4894 else if (Arg.getKind() == TemplateArgument::NullPtr)
4895 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4896 TemplateArgumentLocInfo());
4897 else if (Arg.getKind() == TemplateArgument::Declaration)
4898 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4899 TemplateArgumentLocInfo());
4900 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4901 Output = TemplateArgumentLoc(
4902 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4903 TemplateArgumentLocInfo());
4904 else
4905 llvm_unreachable("unexpected template argument kind");
4906
4907 return false;
4908 }
4909
4910 case TemplateArgument::Type: {
4911 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4912 if (!DI)
4913 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4914
4915 DI = getDerived().TransformType(DI);
4916 if (!DI)
4917 return true;
4918
4919 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4920 return false;
4921 }
4922
4923 case TemplateArgument::Template: {
4924 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4925 if (QualifierLoc) {
4926 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4927 if (!QualifierLoc)
4928 return true;
4929 }
4930
4931 CXXScopeSpec SS;
4932 SS.Adopt(Other: QualifierLoc);
4933 TemplateName Template = getDerived().TransformTemplateName(
4934 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4935 if (Template.isNull())
4936 return true;
4937
4938 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4939 QualifierLoc, Input.getTemplateNameLoc());
4940 return false;
4941 }
4942
4943 case TemplateArgument::TemplateExpansion:
4944 llvm_unreachable("Caller should expand pack expansions");
4945
4946 case TemplateArgument::Expression: {
4947 // Template argument expressions are constant expressions.
4948 EnterExpressionEvaluationContext Unevaluated(
4949 getSema(),
4950 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4951 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4952 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4953 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4954
4955 Expr *InputExpr = Input.getSourceExpression();
4956 if (!InputExpr)
4957 InputExpr = Input.getArgument().getAsExpr();
4958
4959 ExprResult E = getDerived().TransformExpr(InputExpr);
4960 E = SemaRef.ActOnConstantExpression(Res: E);
4961 if (E.isInvalid())
4962 return true;
4963 Output = TemplateArgumentLoc(
4964 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
4965 return false;
4966 }
4967 }
4968
4969 // Work around bogus GCC warning
4970 return true;
4971}
4972
4973/// Iterator adaptor that invents template argument location information
4974/// for each of the template arguments in its underlying iterator.
4975template<typename Derived, typename InputIterator>
4976class TemplateArgumentLocInventIterator {
4977 TreeTransform<Derived> &Self;
4978 InputIterator Iter;
4979
4980public:
4981 typedef TemplateArgumentLoc value_type;
4982 typedef TemplateArgumentLoc reference;
4983 typedef typename std::iterator_traits<InputIterator>::difference_type
4984 difference_type;
4985 typedef std::input_iterator_tag iterator_category;
4986
4987 class pointer {
4988 TemplateArgumentLoc Arg;
4989
4990 public:
4991 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4992
4993 const TemplateArgumentLoc *operator->() const { return &Arg; }
4994 };
4995
4996 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4997 InputIterator Iter)
4998 : Self(Self), Iter(Iter) { }
4999
5000 TemplateArgumentLocInventIterator &operator++() {
5001 ++Iter;
5002 return *this;
5003 }
5004
5005 TemplateArgumentLocInventIterator operator++(int) {
5006 TemplateArgumentLocInventIterator Old(*this);
5007 ++(*this);
5008 return Old;
5009 }
5010
5011 reference operator*() const {
5012 TemplateArgumentLoc Result;
5013 Self.InventTemplateArgumentLoc(*Iter, Result);
5014 return Result;
5015 }
5016
5017 pointer operator->() const { return pointer(**this); }
5018
5019 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5020 const TemplateArgumentLocInventIterator &Y) {
5021 return X.Iter == Y.Iter;
5022 }
5023
5024 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5025 const TemplateArgumentLocInventIterator &Y) {
5026 return X.Iter != Y.Iter;
5027 }
5028};
5029
5030template<typename Derived>
5031template<typename InputIterator>
5032bool TreeTransform<Derived>::TransformTemplateArguments(
5033 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5034 bool Uneval) {
5035 for (; First != Last; ++First) {
5036 TemplateArgumentLoc Out;
5037 TemplateArgumentLoc In = *First;
5038
5039 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5040 // Unpack argument packs, which we translate them into separate
5041 // arguments.
5042 // FIXME: We could do much better if we could guarantee that the
5043 // TemplateArgumentLocInfo for the pack expansion would be usable for
5044 // all of the template arguments in the argument pack.
5045 typedef TemplateArgumentLocInventIterator<Derived,
5046 TemplateArgument::pack_iterator>
5047 PackLocIterator;
5048 if (TransformTemplateArguments(PackLocIterator(*this,
5049 In.getArgument().pack_begin()),
5050 PackLocIterator(*this,
5051 In.getArgument().pack_end()),
5052 Outputs, Uneval))
5053 return true;
5054
5055 continue;
5056 }
5057
5058 if (In.getArgument().isPackExpansion()) {
5059 // We have a pack expansion, for which we will be substituting into
5060 // the pattern.
5061 SourceLocation Ellipsis;
5062 UnsignedOrNone OrigNumExpansions = std::nullopt;
5063 TemplateArgumentLoc Pattern
5064 = getSema().getTemplateArgumentPackExpansionPattern(
5065 In, Ellipsis, OrigNumExpansions);
5066
5067 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5068 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5069 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5070
5071 // Determine whether the set of unexpanded parameter packs can and should
5072 // be expanded.
5073 bool Expand = true;
5074 bool RetainExpansion = false;
5075 UnsignedOrNone NumExpansions = OrigNumExpansions;
5076 if (getDerived().TryExpandParameterPacks(Ellipsis,
5077 Pattern.getSourceRange(),
5078 Unexpanded,
5079 Expand,
5080 RetainExpansion,
5081 NumExpansions))
5082 return true;
5083
5084 if (!Expand) {
5085 // The transform has determined that we should perform a simple
5086 // transformation on the pack expansion, producing another pack
5087 // expansion.
5088 TemplateArgumentLoc OutPattern;
5089 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5090 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5091 return true;
5092
5093 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5094 NumExpansions);
5095 if (Out.getArgument().isNull())
5096 return true;
5097
5098 Outputs.addArgument(Loc: Out);
5099 continue;
5100 }
5101
5102 // The transform has determined that we should perform an elementwise
5103 // expansion of the pattern. Do so.
5104 for (unsigned I = 0; I != *NumExpansions; ++I) {
5105 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5106
5107 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5108 return true;
5109
5110 if (Out.getArgument().containsUnexpandedParameterPack()) {
5111 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5112 OrigNumExpansions);
5113 if (Out.getArgument().isNull())
5114 return true;
5115 }
5116
5117 Outputs.addArgument(Loc: Out);
5118 }
5119
5120 // If we're supposed to retain a pack expansion, do so by temporarily
5121 // forgetting the partially-substituted parameter pack.
5122 if (RetainExpansion) {
5123 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5124
5125 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5126 return true;
5127
5128 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5129 OrigNumExpansions);
5130 if (Out.getArgument().isNull())
5131 return true;
5132
5133 Outputs.addArgument(Loc: Out);
5134 }
5135
5136 continue;
5137 }
5138
5139 // The simple case:
5140 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5141 return true;
5142
5143 Outputs.addArgument(Loc: Out);
5144 }
5145
5146 return false;
5147
5148}
5149
5150//===----------------------------------------------------------------------===//
5151// Type transformation
5152//===----------------------------------------------------------------------===//
5153
5154template<typename Derived>
5155QualType TreeTransform<Derived>::TransformType(QualType T) {
5156 if (getDerived().AlreadyTransformed(T))
5157 return T;
5158
5159 // Temporary workaround. All of these transformations should
5160 // eventually turn into transformations on TypeLocs.
5161 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5162 getDerived().getBaseLocation());
5163
5164 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5165
5166 if (!NewDI)
5167 return QualType();
5168
5169 return NewDI->getType();
5170}
5171
5172template<typename Derived>
5173TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5174 // Refine the base location to the type's location.
5175 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5176 getDerived().getBaseEntity());
5177 if (getDerived().AlreadyTransformed(DI->getType()))
5178 return DI;
5179
5180 TypeLocBuilder TLB;
5181
5182 TypeLoc TL = DI->getTypeLoc();
5183 TLB.reserve(Requested: TL.getFullDataSize());
5184
5185 QualType Result = getDerived().TransformType(TLB, TL);
5186 if (Result.isNull())
5187 return nullptr;
5188
5189 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5190}
5191
5192template<typename Derived>
5193QualType
5194TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5195 switch (T.getTypeLocClass()) {
5196#define ABSTRACT_TYPELOC(CLASS, PARENT)
5197#define TYPELOC(CLASS, PARENT) \
5198 case TypeLoc::CLASS: \
5199 return getDerived().Transform##CLASS##Type(TLB, \
5200 T.castAs<CLASS##TypeLoc>());
5201#include "clang/AST/TypeLocNodes.def"
5202 }
5203
5204 llvm_unreachable("unhandled type loc!");
5205}
5206
5207template<typename Derived>
5208QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5209 if (!isa<DependentNameType>(Val: T))
5210 return TransformType(T);
5211
5212 if (getDerived().AlreadyTransformed(T))
5213 return T;
5214 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5215 getDerived().getBaseLocation());
5216 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5217 return NewDI ? NewDI->getType() : QualType();
5218}
5219
5220template<typename Derived>
5221TypeSourceInfo *
5222TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5223 if (!isa<DependentNameType>(Val: DI->getType()))
5224 return TransformType(DI);
5225
5226 // Refine the base location to the type's location.
5227 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5228 getDerived().getBaseEntity());
5229 if (getDerived().AlreadyTransformed(DI->getType()))
5230 return DI;
5231
5232 TypeLocBuilder TLB;
5233
5234 TypeLoc TL = DI->getTypeLoc();
5235 TLB.reserve(Requested: TL.getFullDataSize());
5236
5237 auto QTL = TL.getAs<QualifiedTypeLoc>();
5238 if (QTL)
5239 TL = QTL.getUnqualifiedLoc();
5240
5241 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5242
5243 QualType Result = getDerived().TransformDependentNameType(
5244 TLB, DNTL, /*DeducedTSTContext*/true);
5245 if (Result.isNull())
5246 return nullptr;
5247
5248 if (QTL) {
5249 Result = getDerived().RebuildQualifiedType(Result, QTL);
5250 if (Result.isNull())
5251 return nullptr;
5252 TLB.TypeWasModifiedSafely(T: Result);
5253 }
5254
5255 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5256}
5257
5258template<typename Derived>
5259QualType
5260TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5261 QualifiedTypeLoc T) {
5262 QualType Result;
5263 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5264 auto SuppressObjCLifetime =
5265 T.getType().getLocalQualifiers().hasObjCLifetime();
5266 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5267 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5268 SuppressObjCLifetime);
5269 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5270 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5271 TLB, STTP, SuppressObjCLifetime);
5272 } else {
5273 Result = getDerived().TransformType(TLB, UnqualTL);
5274 }
5275
5276 if (Result.isNull())
5277 return QualType();
5278
5279 Result = getDerived().RebuildQualifiedType(Result, T);
5280
5281 if (Result.isNull())
5282 return QualType();
5283
5284 // RebuildQualifiedType might have updated the type, but not in a way
5285 // that invalidates the TypeLoc. (There's no location information for
5286 // qualifiers.)
5287 TLB.TypeWasModifiedSafely(T: Result);
5288
5289 return Result;
5290}
5291
5292template <typename Derived>
5293QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5294 QualifiedTypeLoc TL) {
5295
5296 SourceLocation Loc = TL.getBeginLoc();
5297 Qualifiers Quals = TL.getType().getLocalQualifiers();
5298
5299 if ((T.getAddressSpace() != LangAS::Default &&
5300 Quals.getAddressSpace() != LangAS::Default) &&
5301 T.getAddressSpace() != Quals.getAddressSpace()) {
5302 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5303 << TL.getType() << T;
5304 return QualType();
5305 }
5306
5307 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5308 if (LocalPointerAuth.isPresent()) {
5309 if (T.getPointerAuth().isPresent()) {
5310 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5311 return QualType();
5312 }
5313 if (!T->isDependentType()) {
5314 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5315 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5316 return QualType();
5317 }
5318 }
5319 }
5320 // C++ [dcl.fct]p7:
5321 // [When] adding cv-qualifications on top of the function type [...] the
5322 // cv-qualifiers are ignored.
5323 if (T->isFunctionType()) {
5324 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5325 AddressSpace: Quals.getAddressSpace());
5326 return T;
5327 }
5328
5329 // C++ [dcl.ref]p1:
5330 // when the cv-qualifiers are introduced through the use of a typedef-name
5331 // or decltype-specifier [...] the cv-qualifiers are ignored.
5332 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5333 // applied to a reference type.
5334 if (T->isReferenceType()) {
5335 // The only qualifier that applies to a reference type is restrict.
5336 if (!Quals.hasRestrict())
5337 return T;
5338 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5339 }
5340
5341 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5342 // resulting type.
5343 if (Quals.hasObjCLifetime()) {
5344 if (!T->isObjCLifetimeType() && !T->isDependentType())
5345 Quals.removeObjCLifetime();
5346 else if (T.getObjCLifetime()) {
5347 // Objective-C ARC:
5348 // A lifetime qualifier applied to a substituted template parameter
5349 // overrides the lifetime qualifier from the template argument.
5350 const AutoType *AutoTy;
5351 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5352 // 'auto' types behave the same way as template parameters.
5353 QualType Deduced = AutoTy->getDeducedType();
5354 Qualifiers Qs = Deduced.getQualifiers();
5355 Qs.removeObjCLifetime();
5356 Deduced =
5357 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5358 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5359 IsDependent: AutoTy->isDependentType(),
5360 /*isPack=*/IsPack: false,
5361 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5362 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5363 } else {
5364 // Otherwise, complain about the addition of a qualifier to an
5365 // already-qualified type.
5366 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5367 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5368 Quals.removeObjCLifetime();
5369 }
5370 }
5371 }
5372
5373 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5374}
5375
5376template<typename Derived>
5377TypeLoc
5378TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5379 QualType ObjectType,
5380 NamedDecl *UnqualLookup,
5381 CXXScopeSpec &SS) {
5382 if (getDerived().AlreadyTransformed(TL.getType()))
5383 return TL;
5384
5385 TypeSourceInfo *TSI =
5386 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5387 if (TSI)
5388 return TSI->getTypeLoc();
5389 return TypeLoc();
5390}
5391
5392template<typename Derived>
5393TypeSourceInfo *
5394TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5395 QualType ObjectType,
5396 NamedDecl *UnqualLookup,
5397 CXXScopeSpec &SS) {
5398 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5399 return TSInfo;
5400
5401 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5402 FirstQualifierInScope: UnqualLookup, SS);
5403}
5404
5405template <typename Derived>
5406TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5407 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5408 CXXScopeSpec &SS) {
5409 QualType T = TL.getType();
5410 assert(!getDerived().AlreadyTransformed(T));
5411
5412 TypeLocBuilder TLB;
5413 QualType Result;
5414
5415 if (isa<TemplateSpecializationType>(Val: T)) {
5416 TemplateSpecializationTypeLoc SpecTL =
5417 TL.castAs<TemplateSpecializationTypeLoc>();
5418
5419 TemplateName Template = getDerived().TransformTemplateName(
5420 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5421 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5422 if (Template.isNull())
5423 return nullptr;
5424
5425 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5426 Template);
5427 } else if (isa<DependentTemplateSpecializationType>(Val: T)) {
5428 DependentTemplateSpecializationTypeLoc SpecTL =
5429 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5430
5431 const IdentifierInfo *II = SpecTL.getTypePtr()
5432 ->getDependentTemplateName()
5433 .getName()
5434 .getIdentifier();
5435 TemplateName Template = getDerived().RebuildTemplateName(
5436 SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(),
5437 ObjectType, UnqualLookup,
5438 /*AllowInjectedClassName*/ true);
5439 if (Template.isNull())
5440 return nullptr;
5441
5442 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5443 SpecTL,
5444 Template,
5445 SS);
5446 } else {
5447 // Nothing special needs to be done for these.
5448 Result = getDerived().TransformType(TLB, TL);
5449 }
5450
5451 if (Result.isNull())
5452 return nullptr;
5453
5454 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5455}
5456
5457template <class TyLoc> static inline
5458QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5459 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5460 NewT.setNameLoc(T.getNameLoc());
5461 return T.getType();
5462}
5463
5464template<typename Derived>
5465QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5466 BuiltinTypeLoc T) {
5467 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5468 NewT.setBuiltinLoc(T.getBuiltinLoc());
5469 if (T.needsExtraLocalData())
5470 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5471 return T.getType();
5472}
5473
5474template<typename Derived>
5475QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5476 ComplexTypeLoc T) {
5477 // FIXME: recurse?
5478 return TransformTypeSpecType(TLB, T);
5479}
5480
5481template <typename Derived>
5482QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5483 AdjustedTypeLoc TL) {
5484 // Adjustments applied during transformation are handled elsewhere.
5485 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5486}
5487
5488template<typename Derived>
5489QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5490 DecayedTypeLoc TL) {
5491 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5492 if (OriginalType.isNull())
5493 return QualType();
5494
5495 QualType Result = TL.getType();
5496 if (getDerived().AlwaysRebuild() ||
5497 OriginalType != TL.getOriginalLoc().getType())
5498 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5499 TLB.push<DecayedTypeLoc>(T: Result);
5500 // Nothing to set for DecayedTypeLoc.
5501 return Result;
5502}
5503
5504template <typename Derived>
5505QualType
5506TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5507 ArrayParameterTypeLoc TL) {
5508 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5509 if (OriginalType.isNull())
5510 return QualType();
5511
5512 QualType Result = TL.getType();
5513 if (getDerived().AlwaysRebuild() ||
5514 OriginalType != TL.getElementLoc().getType())
5515 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5516 TLB.push<ArrayParameterTypeLoc>(T: Result);
5517 // Nothing to set for ArrayParameterTypeLoc.
5518 return Result;
5519}
5520
5521template<typename Derived>
5522QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5523 PointerTypeLoc TL) {
5524 QualType PointeeType
5525 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5526 if (PointeeType.isNull())
5527 return QualType();
5528
5529 QualType Result = TL.getType();
5530 if (PointeeType->getAs<ObjCObjectType>()) {
5531 // A dependent pointer type 'T *' has is being transformed such
5532 // that an Objective-C class type is being replaced for 'T'. The
5533 // resulting pointer type is an ObjCObjectPointerType, not a
5534 // PointerType.
5535 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5536
5537 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5538 NewT.setStarLoc(TL.getStarLoc());
5539 return Result;
5540 }
5541
5542 if (getDerived().AlwaysRebuild() ||
5543 PointeeType != TL.getPointeeLoc().getType()) {
5544 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5545 if (Result.isNull())
5546 return QualType();
5547 }
5548
5549 // Objective-C ARC can add lifetime qualifiers to the type that we're
5550 // pointing to.
5551 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5552
5553 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5554 NewT.setSigilLoc(TL.getSigilLoc());
5555 return Result;
5556}
5557
5558template<typename Derived>
5559QualType
5560TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5561 BlockPointerTypeLoc TL) {
5562 QualType PointeeType
5563 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5564 if (PointeeType.isNull())
5565 return QualType();
5566
5567 QualType Result = TL.getType();
5568 if (getDerived().AlwaysRebuild() ||
5569 PointeeType != TL.getPointeeLoc().getType()) {
5570 Result = getDerived().RebuildBlockPointerType(PointeeType,
5571 TL.getSigilLoc());
5572 if (Result.isNull())
5573 return QualType();
5574 }
5575
5576 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5577 NewT.setSigilLoc(TL.getSigilLoc());
5578 return Result;
5579}
5580
5581/// Transforms a reference type. Note that somewhat paradoxically we
5582/// don't care whether the type itself is an l-value type or an r-value
5583/// type; we only care if the type was *written* as an l-value type
5584/// or an r-value type.
5585template<typename Derived>
5586QualType
5587TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5588 ReferenceTypeLoc TL) {
5589 const ReferenceType *T = TL.getTypePtr();
5590
5591 // Note that this works with the pointee-as-written.
5592 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5593 if (PointeeType.isNull())
5594 return QualType();
5595
5596 QualType Result = TL.getType();
5597 if (getDerived().AlwaysRebuild() ||
5598 PointeeType != T->getPointeeTypeAsWritten()) {
5599 Result = getDerived().RebuildReferenceType(PointeeType,
5600 T->isSpelledAsLValue(),
5601 TL.getSigilLoc());
5602 if (Result.isNull())
5603 return QualType();
5604 }
5605
5606 // Objective-C ARC can add lifetime qualifiers to the type that we're
5607 // referring to.
5608 TLB.TypeWasModifiedSafely(
5609 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5610
5611 // r-value references can be rebuilt as l-value references.
5612 ReferenceTypeLoc NewTL;
5613 if (isa<LValueReferenceType>(Val: Result))
5614 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5615 else
5616 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5617 NewTL.setSigilLoc(TL.getSigilLoc());
5618
5619 return Result;
5620}
5621
5622template<typename Derived>
5623QualType
5624TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5625 LValueReferenceTypeLoc TL) {
5626 return TransformReferenceType(TLB, TL);
5627}
5628
5629template<typename Derived>
5630QualType
5631TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5632 RValueReferenceTypeLoc TL) {
5633 return TransformReferenceType(TLB, TL);
5634}
5635
5636template<typename Derived>
5637QualType
5638TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5639 MemberPointerTypeLoc TL) {
5640 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5641 if (PointeeType.isNull())
5642 return QualType();
5643
5644 const MemberPointerType *T = TL.getTypePtr();
5645
5646 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5647 NestedNameSpecifierLoc NewQualifierLoc =
5648 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5649 if (!NewQualifierLoc)
5650 return QualType();
5651
5652 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5653 if (OldCls) {
5654 NewCls = cast_or_null<CXXRecordDecl>(
5655 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5656 if (!NewCls)
5657 return QualType();
5658 }
5659
5660 QualType Result = TL.getType();
5661 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5662 NewQualifierLoc.getNestedNameSpecifier() !=
5663 OldQualifierLoc.getNestedNameSpecifier() ||
5664 NewCls != OldCls) {
5665 CXXScopeSpec SS;
5666 SS.Adopt(Other: NewQualifierLoc);
5667 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5668 TL.getStarLoc());
5669 if (Result.isNull())
5670 return QualType();
5671 }
5672
5673 // If we had to adjust the pointee type when building a member pointer, make
5674 // sure to push TypeLoc info for it.
5675 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5676 if (MPT && PointeeType != MPT->getPointeeType()) {
5677 assert(isa<AdjustedType>(MPT->getPointeeType()));
5678 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5679 }
5680
5681 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5682 NewTL.setSigilLoc(TL.getSigilLoc());
5683 NewTL.setQualifierLoc(NewQualifierLoc);
5684
5685 return Result;
5686}
5687
5688template<typename Derived>
5689QualType
5690TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5691 ConstantArrayTypeLoc TL) {
5692 const ConstantArrayType *T = TL.getTypePtr();
5693 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5694 if (ElementType.isNull())
5695 return QualType();
5696
5697 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5698 Expr *OldSize = TL.getSizeExpr();
5699 if (!OldSize)
5700 OldSize = const_cast<Expr*>(T->getSizeExpr());
5701 Expr *NewSize = nullptr;
5702 if (OldSize) {
5703 EnterExpressionEvaluationContext Unevaluated(
5704 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5705 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5706 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5707 }
5708
5709 QualType Result = TL.getType();
5710 if (getDerived().AlwaysRebuild() ||
5711 ElementType != T->getElementType() ||
5712 (T->getSizeExpr() && NewSize != OldSize)) {
5713 Result = getDerived().RebuildConstantArrayType(ElementType,
5714 T->getSizeModifier(),
5715 T->getSize(), NewSize,
5716 T->getIndexTypeCVRQualifiers(),
5717 TL.getBracketsRange());
5718 if (Result.isNull())
5719 return QualType();
5720 }
5721
5722 // We might have either a ConstantArrayType or a VariableArrayType now:
5723 // a ConstantArrayType is allowed to have an element type which is a
5724 // VariableArrayType if the type is dependent. Fortunately, all array
5725 // types have the same location layout.
5726 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5727 NewTL.setLBracketLoc(TL.getLBracketLoc());
5728 NewTL.setRBracketLoc(TL.getRBracketLoc());
5729 NewTL.setSizeExpr(NewSize);
5730
5731 return Result;
5732}
5733
5734template<typename Derived>
5735QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5736 TypeLocBuilder &TLB,
5737 IncompleteArrayTypeLoc TL) {
5738 const IncompleteArrayType *T = TL.getTypePtr();
5739 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5740 if (ElementType.isNull())
5741 return QualType();
5742
5743 QualType Result = TL.getType();
5744 if (getDerived().AlwaysRebuild() ||
5745 ElementType != T->getElementType()) {
5746 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5747 T->getSizeModifier(),
5748 T->getIndexTypeCVRQualifiers(),
5749 TL.getBracketsRange());
5750 if (Result.isNull())
5751 return QualType();
5752 }
5753
5754 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5755 NewTL.setLBracketLoc(TL.getLBracketLoc());
5756 NewTL.setRBracketLoc(TL.getRBracketLoc());
5757 NewTL.setSizeExpr(nullptr);
5758
5759 return Result;
5760}
5761
5762template<typename Derived>
5763QualType
5764TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5765 VariableArrayTypeLoc TL) {
5766 const VariableArrayType *T = TL.getTypePtr();
5767 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5768 if (ElementType.isNull())
5769 return QualType();
5770
5771 ExprResult SizeResult;
5772 {
5773 EnterExpressionEvaluationContext Context(
5774 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5775 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5776 }
5777 if (SizeResult.isInvalid())
5778 return QualType();
5779 SizeResult =
5780 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5781 if (SizeResult.isInvalid())
5782 return QualType();
5783
5784 Expr *Size = SizeResult.get();
5785
5786 QualType Result = TL.getType();
5787 if (getDerived().AlwaysRebuild() ||
5788 ElementType != T->getElementType() ||
5789 Size != T->getSizeExpr()) {
5790 Result = getDerived().RebuildVariableArrayType(ElementType,
5791 T->getSizeModifier(),
5792 Size,
5793 T->getIndexTypeCVRQualifiers(),
5794 TL.getBracketsRange());
5795 if (Result.isNull())
5796 return QualType();
5797 }
5798
5799 // We might have constant size array now, but fortunately it has the same
5800 // location layout.
5801 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5802 NewTL.setLBracketLoc(TL.getLBracketLoc());
5803 NewTL.setRBracketLoc(TL.getRBracketLoc());
5804 NewTL.setSizeExpr(Size);
5805
5806 return Result;
5807}
5808
5809template<typename Derived>
5810QualType
5811TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5812 DependentSizedArrayTypeLoc TL) {
5813 const DependentSizedArrayType *T = TL.getTypePtr();
5814 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5815 if (ElementType.isNull())
5816 return QualType();
5817
5818 // Array bounds are constant expressions.
5819 EnterExpressionEvaluationContext Unevaluated(
5820 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5821
5822 // If we have a VLA then it won't be a constant.
5823 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5824
5825 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5826 Expr *origSize = TL.getSizeExpr();
5827 if (!origSize) origSize = T->getSizeExpr();
5828
5829 ExprResult sizeResult
5830 = getDerived().TransformExpr(origSize);
5831 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5832 if (sizeResult.isInvalid())
5833 return QualType();
5834
5835 Expr *size = sizeResult.get();
5836
5837 QualType Result = TL.getType();
5838 if (getDerived().AlwaysRebuild() ||
5839 ElementType != T->getElementType() ||
5840 size != origSize) {
5841 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5842 T->getSizeModifier(),
5843 size,
5844 T->getIndexTypeCVRQualifiers(),
5845 TL.getBracketsRange());
5846 if (Result.isNull())
5847 return QualType();
5848 }
5849
5850 // We might have any sort of array type now, but fortunately they
5851 // all have the same location layout.
5852 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5853 NewTL.setLBracketLoc(TL.getLBracketLoc());
5854 NewTL.setRBracketLoc(TL.getRBracketLoc());
5855 NewTL.setSizeExpr(size);
5856
5857 return Result;
5858}
5859
5860template <typename Derived>
5861QualType TreeTransform<Derived>::TransformDependentVectorType(
5862 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5863 const DependentVectorType *T = TL.getTypePtr();
5864 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5865 if (ElementType.isNull())
5866 return QualType();
5867
5868 EnterExpressionEvaluationContext Unevaluated(
5869 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5870
5871 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5872 Size = SemaRef.ActOnConstantExpression(Res: Size);
5873 if (Size.isInvalid())
5874 return QualType();
5875
5876 QualType Result = TL.getType();
5877 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5878 Size.get() != T->getSizeExpr()) {
5879 Result = getDerived().RebuildDependentVectorType(
5880 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5881 if (Result.isNull())
5882 return QualType();
5883 }
5884
5885 // Result might be dependent or not.
5886 if (isa<DependentVectorType>(Val: Result)) {
5887 DependentVectorTypeLoc NewTL =
5888 TLB.push<DependentVectorTypeLoc>(T: Result);
5889 NewTL.setNameLoc(TL.getNameLoc());
5890 } else {
5891 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
5892 NewTL.setNameLoc(TL.getNameLoc());
5893 }
5894
5895 return Result;
5896}
5897
5898template<typename Derived>
5899QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5900 TypeLocBuilder &TLB,
5901 DependentSizedExtVectorTypeLoc TL) {
5902 const DependentSizedExtVectorType *T = TL.getTypePtr();
5903
5904 // FIXME: ext vector locs should be nested
5905 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5906 if (ElementType.isNull())
5907 return QualType();
5908
5909 // Vector sizes are constant expressions.
5910 EnterExpressionEvaluationContext Unevaluated(
5911 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5912
5913 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5914 Size = SemaRef.ActOnConstantExpression(Res: Size);
5915 if (Size.isInvalid())
5916 return QualType();
5917
5918 QualType Result = TL.getType();
5919 if (getDerived().AlwaysRebuild() ||
5920 ElementType != T->getElementType() ||
5921 Size.get() != T->getSizeExpr()) {
5922 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5923 Size.get(),
5924 T->getAttributeLoc());
5925 if (Result.isNull())
5926 return QualType();
5927 }
5928
5929 // Result might be dependent or not.
5930 if (isa<DependentSizedExtVectorType>(Val: Result)) {
5931 DependentSizedExtVectorTypeLoc NewTL
5932 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
5933 NewTL.setNameLoc(TL.getNameLoc());
5934 } else {
5935 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
5936 NewTL.setNameLoc(TL.getNameLoc());
5937 }
5938
5939 return Result;
5940}
5941
5942template <typename Derived>
5943QualType
5944TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5945 ConstantMatrixTypeLoc TL) {
5946 const ConstantMatrixType *T = TL.getTypePtr();
5947 QualType ElementType = getDerived().TransformType(T->getElementType());
5948 if (ElementType.isNull())
5949 return QualType();
5950
5951 QualType Result = TL.getType();
5952 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5953 Result = getDerived().RebuildConstantMatrixType(
5954 ElementType, T->getNumRows(), T->getNumColumns());
5955 if (Result.isNull())
5956 return QualType();
5957 }
5958
5959 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
5960 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5961 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5962 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5963 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5964
5965 return Result;
5966}
5967
5968template <typename Derived>
5969QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5970 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5971 const DependentSizedMatrixType *T = TL.getTypePtr();
5972
5973 QualType ElementType = getDerived().TransformType(T->getElementType());
5974 if (ElementType.isNull()) {
5975 return QualType();
5976 }
5977
5978 // Matrix dimensions are constant expressions.
5979 EnterExpressionEvaluationContext Unevaluated(
5980 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5981
5982 Expr *origRows = TL.getAttrRowOperand();
5983 if (!origRows)
5984 origRows = T->getRowExpr();
5985 Expr *origColumns = TL.getAttrColumnOperand();
5986 if (!origColumns)
5987 origColumns = T->getColumnExpr();
5988
5989 ExprResult rowResult = getDerived().TransformExpr(origRows);
5990 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5991 if (rowResult.isInvalid())
5992 return QualType();
5993
5994 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5995 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
5996 if (columnResult.isInvalid())
5997 return QualType();
5998
5999 Expr *rows = rowResult.get();
6000 Expr *columns = columnResult.get();
6001
6002 QualType Result = TL.getType();
6003 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6004 rows != origRows || columns != origColumns) {
6005 Result = getDerived().RebuildDependentSizedMatrixType(
6006 ElementType, rows, columns, T->getAttributeLoc());
6007
6008 if (Result.isNull())
6009 return QualType();
6010 }
6011
6012 // We might have any sort of matrix type now, but fortunately they
6013 // all have the same location layout.
6014 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6015 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6016 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6017 NewTL.setAttrRowOperand(rows);
6018 NewTL.setAttrColumnOperand(columns);
6019 return Result;
6020}
6021
6022template <typename Derived>
6023QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6024 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6025 const DependentAddressSpaceType *T = TL.getTypePtr();
6026
6027 QualType pointeeType =
6028 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6029
6030 if (pointeeType.isNull())
6031 return QualType();
6032
6033 // Address spaces are constant expressions.
6034 EnterExpressionEvaluationContext Unevaluated(
6035 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6036
6037 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6038 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6039 if (AddrSpace.isInvalid())
6040 return QualType();
6041
6042 QualType Result = TL.getType();
6043 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6044 AddrSpace.get() != T->getAddrSpaceExpr()) {
6045 Result = getDerived().RebuildDependentAddressSpaceType(
6046 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6047 if (Result.isNull())
6048 return QualType();
6049 }
6050
6051 // Result might be dependent or not.
6052 if (isa<DependentAddressSpaceType>(Val: Result)) {
6053 DependentAddressSpaceTypeLoc NewTL =
6054 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6055
6056 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6057 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6058 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6059
6060 } else {
6061 TLB.TypeWasModifiedSafely(T: Result);
6062 }
6063
6064 return Result;
6065}
6066
6067template <typename Derived>
6068QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6069 VectorTypeLoc TL) {
6070 const VectorType *T = TL.getTypePtr();
6071 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6072 if (ElementType.isNull())
6073 return QualType();
6074
6075 QualType Result = TL.getType();
6076 if (getDerived().AlwaysRebuild() ||
6077 ElementType != T->getElementType()) {
6078 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6079 T->getVectorKind());
6080 if (Result.isNull())
6081 return QualType();
6082 }
6083
6084 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6085 NewTL.setNameLoc(TL.getNameLoc());
6086
6087 return Result;
6088}
6089
6090template<typename Derived>
6091QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6092 ExtVectorTypeLoc TL) {
6093 const VectorType *T = TL.getTypePtr();
6094 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6095 if (ElementType.isNull())
6096 return QualType();
6097
6098 QualType Result = TL.getType();
6099 if (getDerived().AlwaysRebuild() ||
6100 ElementType != T->getElementType()) {
6101 Result = getDerived().RebuildExtVectorType(ElementType,
6102 T->getNumElements(),
6103 /*FIXME*/ SourceLocation());
6104 if (Result.isNull())
6105 return QualType();
6106 }
6107
6108 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6109 NewTL.setNameLoc(TL.getNameLoc());
6110
6111 return Result;
6112}
6113
6114template <typename Derived>
6115ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6116 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6117 bool ExpectParameterPack) {
6118 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6119 TypeSourceInfo *NewDI = nullptr;
6120
6121 if (NumExpansions && isa<PackExpansionType>(Val: OldDI->getType())) {
6122 // If we're substituting into a pack expansion type and we know the
6123 // length we want to expand to, just substitute for the pattern.
6124 TypeLoc OldTL = OldDI->getTypeLoc();
6125 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6126
6127 TypeLocBuilder TLB;
6128 TypeLoc NewTL = OldDI->getTypeLoc();
6129 TLB.reserve(Requested: NewTL.getFullDataSize());
6130
6131 QualType Result = getDerived().TransformType(TLB,
6132 OldExpansionTL.getPatternLoc());
6133 if (Result.isNull())
6134 return nullptr;
6135
6136 Result = RebuildPackExpansionType(Pattern: Result,
6137 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6138 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6139 NumExpansions);
6140 if (Result.isNull())
6141 return nullptr;
6142
6143 PackExpansionTypeLoc NewExpansionTL
6144 = TLB.push<PackExpansionTypeLoc>(T: Result);
6145 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6146 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6147 } else
6148 NewDI = getDerived().TransformType(OldDI);
6149 if (!NewDI)
6150 return nullptr;
6151
6152 if (NewDI == OldDI && indexAdjustment == 0)
6153 return OldParm;
6154
6155 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
6156 DC: OldParm->getDeclContext(),
6157 StartLoc: OldParm->getInnerLocStart(),
6158 IdLoc: OldParm->getLocation(),
6159 Id: OldParm->getIdentifier(),
6160 T: NewDI->getType(),
6161 TInfo: NewDI,
6162 S: OldParm->getStorageClass(),
6163 /* DefArg */ DefArg: nullptr);
6164 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6165 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6166 transformedLocalDecl(Old: OldParm, New: {newParm});
6167 return newParm;
6168}
6169
6170template <typename Derived>
6171bool TreeTransform<Derived>::TransformFunctionTypeParams(
6172 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6173 const QualType *ParamTypes,
6174 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6175 SmallVectorImpl<QualType> &OutParamTypes,
6176 SmallVectorImpl<ParmVarDecl *> *PVars,
6177 Sema::ExtParameterInfoBuilder &PInfos,
6178 unsigned *LastParamTransformed) {
6179 int indexAdjustment = 0;
6180
6181 unsigned NumParams = Params.size();
6182 for (unsigned i = 0; i != NumParams; ++i) {
6183 if (LastParamTransformed)
6184 *LastParamTransformed = i;
6185 if (ParmVarDecl *OldParm = Params[i]) {
6186 assert(OldParm->getFunctionScopeIndex() == i);
6187
6188 UnsignedOrNone NumExpansions = std::nullopt;
6189 ParmVarDecl *NewParm = nullptr;
6190 if (OldParm->isParameterPack()) {
6191 // We have a function parameter pack that may need to be expanded.
6192 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6193
6194 // Find the parameter packs that could be expanded.
6195 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6196 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6197 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6198 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6199
6200 // Determine whether we should expand the parameter packs.
6201 bool ShouldExpand = false;
6202 bool RetainExpansion = false;
6203 UnsignedOrNone OrigNumExpansions = std::nullopt;
6204 if (Unexpanded.size() > 0) {
6205 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6206 NumExpansions = OrigNumExpansions;
6207 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6208 Pattern.getSourceRange(),
6209 Unexpanded,
6210 ShouldExpand,
6211 RetainExpansion,
6212 NumExpansions)) {
6213 return true;
6214 }
6215 } else {
6216#ifndef NDEBUG
6217 const AutoType *AT =
6218 Pattern.getType().getTypePtr()->getContainedAutoType();
6219 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6220 "Could not find parameter packs or undeduced auto type!");
6221#endif
6222 }
6223
6224 if (ShouldExpand) {
6225 // Expand the function parameter pack into multiple, separate
6226 // parameters.
6227 getDerived().ExpandingFunctionParameterPack(OldParm);
6228 for (unsigned I = 0; I != *NumExpansions; ++I) {
6229 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6230 ParmVarDecl *NewParm
6231 = getDerived().TransformFunctionTypeParam(OldParm,
6232 indexAdjustment++,
6233 OrigNumExpansions,
6234 /*ExpectParameterPack=*/false);
6235 if (!NewParm)
6236 return true;
6237
6238 if (ParamInfos)
6239 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6240 OutParamTypes.push_back(Elt: NewParm->getType());
6241 if (PVars)
6242 PVars->push_back(Elt: NewParm);
6243 }
6244
6245 // If we're supposed to retain a pack expansion, do so by temporarily
6246 // forgetting the partially-substituted parameter pack.
6247 if (RetainExpansion) {
6248 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6249 ParmVarDecl *NewParm
6250 = getDerived().TransformFunctionTypeParam(OldParm,
6251 indexAdjustment++,
6252 OrigNumExpansions,
6253 /*ExpectParameterPack=*/false);
6254 if (!NewParm)
6255 return true;
6256
6257 if (ParamInfos)
6258 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6259 OutParamTypes.push_back(Elt: NewParm->getType());
6260 if (PVars)
6261 PVars->push_back(Elt: NewParm);
6262 }
6263
6264 // The next parameter should have the same adjustment as the
6265 // last thing we pushed, but we post-incremented indexAdjustment
6266 // on every push. Also, if we push nothing, the adjustment should
6267 // go down by one.
6268 indexAdjustment--;
6269
6270 // We're done with the pack expansion.
6271 continue;
6272 }
6273
6274 // We'll substitute the parameter now without expanding the pack
6275 // expansion.
6276 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6277 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6278 indexAdjustment,
6279 NumExpansions,
6280 /*ExpectParameterPack=*/true);
6281 assert(NewParm->isParameterPack() &&
6282 "Parameter pack no longer a parameter pack after "
6283 "transformation.");
6284 } else {
6285 NewParm = getDerived().TransformFunctionTypeParam(
6286 OldParm, indexAdjustment, std::nullopt,
6287 /*ExpectParameterPack=*/false);
6288 }
6289
6290 if (!NewParm)
6291 return true;
6292
6293 if (ParamInfos)
6294 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6295 OutParamTypes.push_back(Elt: NewParm->getType());
6296 if (PVars)
6297 PVars->push_back(Elt: NewParm);
6298 continue;
6299 }
6300
6301 // Deal with the possibility that we don't have a parameter
6302 // declaration for this parameter.
6303 assert(ParamTypes);
6304 QualType OldType = ParamTypes[i];
6305 bool IsPackExpansion = false;
6306 UnsignedOrNone NumExpansions = std::nullopt;
6307 QualType NewType;
6308 if (const PackExpansionType *Expansion
6309 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6310 // We have a function parameter pack that may need to be expanded.
6311 QualType Pattern = Expansion->getPattern();
6312 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6313 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6314
6315 // Determine whether we should expand the parameter packs.
6316 bool ShouldExpand = false;
6317 bool RetainExpansion = false;
6318 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6319 Unexpanded,
6320 ShouldExpand,
6321 RetainExpansion,
6322 NumExpansions)) {
6323 return true;
6324 }
6325
6326 if (ShouldExpand) {
6327 // Expand the function parameter pack into multiple, separate
6328 // parameters.
6329 for (unsigned I = 0; I != *NumExpansions; ++I) {
6330 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6331 QualType NewType = getDerived().TransformType(Pattern);
6332 if (NewType.isNull())
6333 return true;
6334
6335 if (NewType->containsUnexpandedParameterPack()) {
6336 NewType = getSema().getASTContext().getPackExpansionType(
6337 NewType, std::nullopt);
6338
6339 if (NewType.isNull())
6340 return true;
6341 }
6342
6343 if (ParamInfos)
6344 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6345 OutParamTypes.push_back(Elt: NewType);
6346 if (PVars)
6347 PVars->push_back(Elt: nullptr);
6348 }
6349
6350 // We're done with the pack expansion.
6351 continue;
6352 }
6353
6354 // If we're supposed to retain a pack expansion, do so by temporarily
6355 // forgetting the partially-substituted parameter pack.
6356 if (RetainExpansion) {
6357 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6358 QualType NewType = getDerived().TransformType(Pattern);
6359 if (NewType.isNull())
6360 return true;
6361
6362 if (ParamInfos)
6363 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6364 OutParamTypes.push_back(Elt: NewType);
6365 if (PVars)
6366 PVars->push_back(Elt: nullptr);
6367 }
6368
6369 // We'll substitute the parameter now without expanding the pack
6370 // expansion.
6371 OldType = Expansion->getPattern();
6372 IsPackExpansion = true;
6373 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6374 NewType = getDerived().TransformType(OldType);
6375 } else {
6376 NewType = getDerived().TransformType(OldType);
6377 }
6378
6379 if (NewType.isNull())
6380 return true;
6381
6382 if (IsPackExpansion)
6383 NewType = getSema().Context.getPackExpansionType(NewType,
6384 NumExpansions);
6385
6386 if (ParamInfos)
6387 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6388 OutParamTypes.push_back(Elt: NewType);
6389 if (PVars)
6390 PVars->push_back(Elt: nullptr);
6391 }
6392
6393#ifndef NDEBUG
6394 if (PVars) {
6395 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6396 if (ParmVarDecl *parm = (*PVars)[i])
6397 assert(parm->getFunctionScopeIndex() == i);
6398 }
6399#endif
6400
6401 return false;
6402}
6403
6404template<typename Derived>
6405QualType
6406TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6407 FunctionProtoTypeLoc TL) {
6408 SmallVector<QualType, 4> ExceptionStorage;
6409 return getDerived().TransformFunctionProtoType(
6410 TLB, TL, nullptr, Qualifiers(),
6411 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6412 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6413 ExceptionStorage, Changed);
6414 });
6415}
6416
6417template<typename Derived> template<typename Fn>
6418QualType TreeTransform<Derived>::TransformFunctionProtoType(
6419 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6420 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6421
6422 // Transform the parameters and return type.
6423 //
6424 // We are required to instantiate the params and return type in source order.
6425 // When the function has a trailing return type, we instantiate the
6426 // parameters before the return type, since the return type can then refer
6427 // to the parameters themselves (via decltype, sizeof, etc.).
6428 //
6429 SmallVector<QualType, 4> ParamTypes;
6430 SmallVector<ParmVarDecl*, 4> ParamDecls;
6431 Sema::ExtParameterInfoBuilder ExtParamInfos;
6432 const FunctionProtoType *T = TL.getTypePtr();
6433
6434 QualType ResultType;
6435
6436 if (T->hasTrailingReturn()) {
6437 if (getDerived().TransformFunctionTypeParams(
6438 TL.getBeginLoc(), TL.getParams(),
6439 TL.getTypePtr()->param_type_begin(),
6440 T->getExtParameterInfosOrNull(),
6441 ParamTypes, &ParamDecls, ExtParamInfos))
6442 return QualType();
6443
6444 {
6445 // C++11 [expr.prim.general]p3:
6446 // If a declaration declares a member function or member function
6447 // template of a class X, the expression this is a prvalue of type
6448 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6449 // and the end of the function-definition, member-declarator, or
6450 // declarator.
6451 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6452 Sema::CXXThisScopeRAII ThisScope(
6453 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6454
6455 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6456 if (ResultType.isNull())
6457 return QualType();
6458 }
6459 }
6460 else {
6461 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6462 if (ResultType.isNull())
6463 return QualType();
6464
6465 if (getDerived().TransformFunctionTypeParams(
6466 TL.getBeginLoc(), TL.getParams(),
6467 TL.getTypePtr()->param_type_begin(),
6468 T->getExtParameterInfosOrNull(),
6469 ParamTypes, &ParamDecls, ExtParamInfos))
6470 return QualType();
6471 }
6472
6473 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6474
6475 bool EPIChanged = false;
6476 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6477 return QualType();
6478
6479 // Handle extended parameter information.
6480 if (auto NewExtParamInfos =
6481 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6482 if (!EPI.ExtParameterInfos ||
6483 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6484 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6485 EPIChanged = true;
6486 }
6487 EPI.ExtParameterInfos = NewExtParamInfos;
6488 } else if (EPI.ExtParameterInfos) {
6489 EPIChanged = true;
6490 EPI.ExtParameterInfos = nullptr;
6491 }
6492
6493 // Transform any function effects with unevaluated conditions.
6494 // Hold this set in a local for the rest of this function, since EPI
6495 // may need to hold a FunctionEffectsRef pointing into it.
6496 std::optional<FunctionEffectSet> NewFX;
6497 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6498 NewFX.emplace();
6499 EnterExpressionEvaluationContext Unevaluated(
6500 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6501
6502 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6503 FunctionEffectWithCondition NewEC = PrevEC;
6504 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6505 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6506 if (NewExpr.isInvalid())
6507 return QualType();
6508 std::optional<FunctionEffectMode> Mode =
6509 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6510 if (!Mode)
6511 return QualType();
6512
6513 // The condition expression has been transformed, and re-evaluated.
6514 // It may or may not have become constant.
6515 switch (*Mode) {
6516 case FunctionEffectMode::True:
6517 NewEC.Cond = {};
6518 break;
6519 case FunctionEffectMode::False:
6520 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6521 NewEC.Cond = {};
6522 break;
6523 case FunctionEffectMode::Dependent:
6524 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6525 break;
6526 case FunctionEffectMode::None:
6527 llvm_unreachable(
6528 "FunctionEffectMode::None shouldn't be possible here");
6529 }
6530 }
6531 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6532 NewAttrLoc: TL.getBeginLoc())) {
6533 FunctionEffectSet::Conflicts Errs;
6534 NewFX->insert(NewEC, Errs);
6535 assert(Errs.empty());
6536 }
6537 }
6538 EPI.FunctionEffects = *NewFX;
6539 EPIChanged = true;
6540 }
6541
6542 QualType Result = TL.getType();
6543 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6544 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6545 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6546 if (Result.isNull())
6547 return QualType();
6548 }
6549
6550 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6551 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6552 NewTL.setLParenLoc(TL.getLParenLoc());
6553 NewTL.setRParenLoc(TL.getRParenLoc());
6554 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6555 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6556 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6557 NewTL.setParam(i, VD: ParamDecls[i]);
6558
6559 return Result;
6560}
6561
6562template<typename Derived>
6563bool TreeTransform<Derived>::TransformExceptionSpec(
6564 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6565 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6566 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6567
6568 // Instantiate a dynamic noexcept expression, if any.
6569 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6570 // Update this scrope because ContextDecl in Sema will be used in
6571 // TransformExpr.
6572 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6573 Sema::CXXThisScopeRAII ThisScope(
6574 SemaRef, Method ? Method->getParent() : nullptr,
6575 Method ? Method->getMethodQualifiers() : Qualifiers{},
6576 Method != nullptr);
6577 EnterExpressionEvaluationContext Unevaluated(
6578 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6579 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6580 if (NoexceptExpr.isInvalid())
6581 return true;
6582
6583 ExceptionSpecificationType EST = ESI.Type;
6584 NoexceptExpr =
6585 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6586 if (NoexceptExpr.isInvalid())
6587 return true;
6588
6589 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6590 Changed = true;
6591 ESI.NoexceptExpr = NoexceptExpr.get();
6592 ESI.Type = EST;
6593 }
6594
6595 if (ESI.Type != EST_Dynamic)
6596 return false;
6597
6598 // Instantiate a dynamic exception specification's type.
6599 for (QualType T : ESI.Exceptions) {
6600 if (const PackExpansionType *PackExpansion =
6601 T->getAs<PackExpansionType>()) {
6602 Changed = true;
6603
6604 // We have a pack expansion. Instantiate it.
6605 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6606 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6607 Unexpanded);
6608 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6609
6610 // Determine whether the set of unexpanded parameter packs can and
6611 // should
6612 // be expanded.
6613 bool Expand = false;
6614 bool RetainExpansion = false;
6615 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6616 // FIXME: Track the location of the ellipsis (and track source location
6617 // information for the types in the exception specification in general).
6618 if (getDerived().TryExpandParameterPacks(
6619 Loc, SourceRange(), Unexpanded, Expand,
6620 RetainExpansion, NumExpansions))
6621 return true;
6622
6623 if (!Expand) {
6624 // We can't expand this pack expansion into separate arguments yet;
6625 // just substitute into the pattern and create a new pack expansion
6626 // type.
6627 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6628 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6629 if (U.isNull())
6630 return true;
6631
6632 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6633 Exceptions.push_back(Elt: U);
6634 continue;
6635 }
6636
6637 // Substitute into the pack expansion pattern for each slice of the
6638 // pack.
6639 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6640 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6641
6642 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6643 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6644 return true;
6645
6646 Exceptions.push_back(Elt: U);
6647 }
6648 } else {
6649 QualType U = getDerived().TransformType(T);
6650 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6651 return true;
6652 if (T != U)
6653 Changed = true;
6654
6655 Exceptions.push_back(Elt: U);
6656 }
6657 }
6658
6659 ESI.Exceptions = Exceptions;
6660 if (ESI.Exceptions.empty())
6661 ESI.Type = EST_DynamicNone;
6662 return false;
6663}
6664
6665template<typename Derived>
6666QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6667 TypeLocBuilder &TLB,
6668 FunctionNoProtoTypeLoc TL) {
6669 const FunctionNoProtoType *T = TL.getTypePtr();
6670 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6671 if (ResultType.isNull())
6672 return QualType();
6673
6674 QualType Result = TL.getType();
6675 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6676 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6677
6678 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6679 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6680 NewTL.setLParenLoc(TL.getLParenLoc());
6681 NewTL.setRParenLoc(TL.getRParenLoc());
6682 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6683
6684 return Result;
6685}
6686
6687template <typename Derived>
6688QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6689 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6690 const UnresolvedUsingType *T = TL.getTypePtr();
6691 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6692 if (!D)
6693 return QualType();
6694
6695 QualType Result = TL.getType();
6696 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6697 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6698 if (Result.isNull())
6699 return QualType();
6700 }
6701
6702 // We might get an arbitrary type spec type back. We should at
6703 // least always get a type spec type, though.
6704 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6705 NewTL.setNameLoc(TL.getNameLoc());
6706
6707 return Result;
6708}
6709
6710template <typename Derived>
6711QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6712 UsingTypeLoc TL) {
6713 const UsingType *T = TL.getTypePtr();
6714
6715 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6716 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6717 if (!Found)
6718 return QualType();
6719
6720 QualType Underlying = getDerived().TransformType(T->desugar());
6721 if (Underlying.isNull())
6722 return QualType();
6723
6724 QualType Result = TL.getType();
6725 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6726 Underlying != T->getUnderlyingType()) {
6727 Result = getDerived().RebuildUsingType(Found, Underlying);
6728 if (Result.isNull())
6729 return QualType();
6730 }
6731
6732 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6733 return Result;
6734}
6735
6736template<typename Derived>
6737QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6738 TypedefTypeLoc TL) {
6739 const TypedefType *T = TL.getTypePtr();
6740 TypedefNameDecl *Typedef
6741 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6742 T->getDecl()));
6743 if (!Typedef)
6744 return QualType();
6745
6746 QualType Result = TL.getType();
6747 if (getDerived().AlwaysRebuild() ||
6748 Typedef != T->getDecl()) {
6749 Result = getDerived().RebuildTypedefType(Typedef);
6750 if (Result.isNull())
6751 return QualType();
6752 }
6753
6754 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(T: Result);
6755 NewTL.setNameLoc(TL.getNameLoc());
6756
6757 return Result;
6758}
6759
6760template<typename Derived>
6761QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6762 TypeOfExprTypeLoc TL) {
6763 // typeof expressions are not potentially evaluated contexts
6764 EnterExpressionEvaluationContext Unevaluated(
6765 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6766 Sema::ReuseLambdaContextDecl);
6767
6768 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6769 if (E.isInvalid())
6770 return QualType();
6771
6772 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6773 if (E.isInvalid())
6774 return QualType();
6775
6776 QualType Result = TL.getType();
6777 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6778 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6779 Result =
6780 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6781 if (Result.isNull())
6782 return QualType();
6783 }
6784
6785 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
6786 NewTL.setTypeofLoc(TL.getTypeofLoc());
6787 NewTL.setLParenLoc(TL.getLParenLoc());
6788 NewTL.setRParenLoc(TL.getRParenLoc());
6789
6790 return Result;
6791}
6792
6793template<typename Derived>
6794QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6795 TypeOfTypeLoc TL) {
6796 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6797 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6798 if (!New_Under_TI)
6799 return QualType();
6800
6801 QualType Result = TL.getType();
6802 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6803 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6804 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6805 if (Result.isNull())
6806 return QualType();
6807 }
6808
6809 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
6810 NewTL.setTypeofLoc(TL.getTypeofLoc());
6811 NewTL.setLParenLoc(TL.getLParenLoc());
6812 NewTL.setRParenLoc(TL.getRParenLoc());
6813 NewTL.setUnmodifiedTInfo(New_Under_TI);
6814
6815 return Result;
6816}
6817
6818template<typename Derived>
6819QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6820 DecltypeTypeLoc TL) {
6821 const DecltypeType *T = TL.getTypePtr();
6822
6823 // decltype expressions are not potentially evaluated contexts
6824 EnterExpressionEvaluationContext Unevaluated(
6825 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6826 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6827
6828 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6829 if (E.isInvalid())
6830 return QualType();
6831
6832 E = getSema().ActOnDecltypeExpression(E.get());
6833 if (E.isInvalid())
6834 return QualType();
6835
6836 QualType Result = TL.getType();
6837 if (getDerived().AlwaysRebuild() ||
6838 E.get() != T->getUnderlyingExpr()) {
6839 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6840 if (Result.isNull())
6841 return QualType();
6842 }
6843 else E.get();
6844
6845 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
6846 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6847 NewTL.setRParenLoc(TL.getRParenLoc());
6848 return Result;
6849}
6850
6851template <typename Derived>
6852QualType
6853TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6854 PackIndexingTypeLoc TL) {
6855 // Transform the index
6856 ExprResult IndexExpr;
6857 {
6858 EnterExpressionEvaluationContext ConstantContext(
6859 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6860
6861 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6862 if (IndexExpr.isInvalid())
6863 return QualType();
6864 }
6865 QualType Pattern = TL.getPattern();
6866
6867 const PackIndexingType *PIT = TL.getTypePtr();
6868 SmallVector<QualType, 5> SubtitutedTypes;
6869 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6870
6871 bool NotYetExpanded = Types.empty();
6872 bool FullySubstituted = true;
6873
6874 if (Types.empty() && !PIT->expandsToEmptyPack())
6875 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6876
6877 for (QualType T : Types) {
6878 if (!T->containsUnexpandedParameterPack()) {
6879 QualType Transformed = getDerived().TransformType(T);
6880 if (Transformed.isNull())
6881 return QualType();
6882 SubtitutedTypes.push_back(Elt: Transformed);
6883 continue;
6884 }
6885
6886 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6887 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6888 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6889 // Determine whether the set of unexpanded parameter packs can and should
6890 // be expanded.
6891 bool ShouldExpand = true;
6892 bool RetainExpansion = false;
6893 UnsignedOrNone NumExpansions = std::nullopt;
6894 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6895 Unexpanded, ShouldExpand,
6896 RetainExpansion, NumExpansions))
6897 return QualType();
6898 if (!ShouldExpand) {
6899 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6900 // FIXME: should we keep TypeLoc for individual expansions in
6901 // PackIndexingTypeLoc?
6902 TypeSourceInfo *TI =
6903 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
6904 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6905 if (Pack.isNull())
6906 return QualType();
6907 if (NotYetExpanded) {
6908 FullySubstituted = false;
6909 QualType Out = getDerived().RebuildPackIndexingType(
6910 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6911 FullySubstituted);
6912 if (Out.isNull())
6913 return QualType();
6914
6915 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6916 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6917 return Out;
6918 }
6919 SubtitutedTypes.push_back(Elt: Pack);
6920 continue;
6921 }
6922 for (unsigned I = 0; I != *NumExpansions; ++I) {
6923 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6924 QualType Out = getDerived().TransformType(T);
6925 if (Out.isNull())
6926 return QualType();
6927 SubtitutedTypes.push_back(Elt: Out);
6928 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6929 }
6930 // If we're supposed to retain a pack expansion, do so by temporarily
6931 // forgetting the partially-substituted parameter pack.
6932 if (RetainExpansion) {
6933 FullySubstituted = false;
6934 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6935 QualType Out = getDerived().TransformType(T);
6936 if (Out.isNull())
6937 return QualType();
6938 SubtitutedTypes.push_back(Elt: Out);
6939 }
6940 }
6941
6942 // A pack indexing type can appear in a larger pack expansion,
6943 // e.g. `Pack...[pack_of_indexes]...`
6944 // so we need to temporarily disable substitution of pack elements
6945 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6946 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6947
6948 QualType Out = getDerived().RebuildPackIndexingType(
6949 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6950 FullySubstituted, SubtitutedTypes);
6951 if (Out.isNull())
6952 return Out;
6953
6954 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6955 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6956 return Out;
6957}
6958
6959template<typename Derived>
6960QualType TreeTransform<Derived>::TransformUnaryTransformType(
6961 TypeLocBuilder &TLB,
6962 UnaryTransformTypeLoc TL) {
6963 QualType Result = TL.getType();
6964 if (Result->isDependentType()) {
6965 const UnaryTransformType *T = TL.getTypePtr();
6966
6967 TypeSourceInfo *NewBaseTSI =
6968 getDerived().TransformType(TL.getUnderlyingTInfo());
6969 if (!NewBaseTSI)
6970 return QualType();
6971 QualType NewBase = NewBaseTSI->getType();
6972
6973 Result = getDerived().RebuildUnaryTransformType(NewBase,
6974 T->getUTTKind(),
6975 TL.getKWLoc());
6976 if (Result.isNull())
6977 return QualType();
6978 }
6979
6980 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
6981 NewTL.setKWLoc(TL.getKWLoc());
6982 NewTL.setParensRange(TL.getParensRange());
6983 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6984 return Result;
6985}
6986
6987template<typename Derived>
6988QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6989 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6990 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6991
6992 CXXScopeSpec SS;
6993 TemplateName TemplateName = getDerived().TransformTemplateName(
6994 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6995 if (TemplateName.isNull())
6996 return QualType();
6997
6998 QualType OldDeduced = T->getDeducedType();
6999 QualType NewDeduced;
7000 if (!OldDeduced.isNull()) {
7001 NewDeduced = getDerived().TransformType(OldDeduced);
7002 if (NewDeduced.isNull())
7003 return QualType();
7004 }
7005
7006 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7007 TemplateName, NewDeduced);
7008 if (Result.isNull())
7009 return QualType();
7010
7011 DeducedTemplateSpecializationTypeLoc NewTL =
7012 TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7013 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7014
7015 return Result;
7016}
7017
7018template<typename Derived>
7019QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7020 RecordTypeLoc TL) {
7021 const RecordType *T = TL.getTypePtr();
7022 RecordDecl *Record
7023 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7024 T->getDecl()));
7025 if (!Record)
7026 return QualType();
7027
7028 QualType Result = TL.getType();
7029 if (getDerived().AlwaysRebuild() ||
7030 Record != T->getDecl()) {
7031 Result = getDerived().RebuildRecordType(Record);
7032 if (Result.isNull())
7033 return QualType();
7034 }
7035
7036 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(T: Result);
7037 NewTL.setNameLoc(TL.getNameLoc());
7038
7039 return Result;
7040}
7041
7042template<typename Derived>
7043QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7044 EnumTypeLoc TL) {
7045 const EnumType *T = TL.getTypePtr();
7046 EnumDecl *Enum
7047 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7048 T->getDecl()));
7049 if (!Enum)
7050 return QualType();
7051
7052 QualType Result = TL.getType();
7053 if (getDerived().AlwaysRebuild() ||
7054 Enum != T->getDecl()) {
7055 Result = getDerived().RebuildEnumType(Enum);
7056 if (Result.isNull())
7057 return QualType();
7058 }
7059
7060 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(T: Result);
7061 NewTL.setNameLoc(TL.getNameLoc());
7062
7063 return Result;
7064}
7065
7066template<typename Derived>
7067QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7068 TypeLocBuilder &TLB,
7069 InjectedClassNameTypeLoc TL) {
7070 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7071 TL.getTypePtr()->getDecl());
7072 if (!D) return QualType();
7073
7074 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: D));
7075 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7076 return T;
7077}
7078
7079template<typename Derived>
7080QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7081 TypeLocBuilder &TLB,
7082 TemplateTypeParmTypeLoc TL) {
7083 return getDerived().TransformTemplateTypeParmType(
7084 TLB, TL,
7085 /*SuppressObjCLifetime=*/false);
7086}
7087
7088template <typename Derived>
7089QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7090 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7091 return TransformTypeSpecType(TLB, T: TL);
7092}
7093
7094template<typename Derived>
7095QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7096 TypeLocBuilder &TLB,
7097 SubstTemplateTypeParmTypeLoc TL) {
7098 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7099
7100 Decl *NewReplaced =
7101 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7102
7103 // Substitute into the replacement type, which itself might involve something
7104 // that needs to be transformed. This only tends to occur with default
7105 // template arguments of template template parameters.
7106 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7107 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7108 if (Replacement.isNull())
7109 return QualType();
7110
7111 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7112 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7113 Final: T->getFinal());
7114
7115 // Propagate type-source information.
7116 SubstTemplateTypeParmTypeLoc NewTL
7117 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7118 NewTL.setNameLoc(TL.getNameLoc());
7119 return Result;
7120
7121}
7122
7123template<typename Derived>
7124QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7125 TypeLocBuilder &TLB,
7126 SubstTemplateTypeParmPackTypeLoc TL) {
7127 return getDerived().TransformSubstTemplateTypeParmPackType(
7128 TLB, TL, /*SuppressObjCLifetime=*/false);
7129}
7130
7131template <typename Derived>
7132QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7133 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7134 return TransformTypeSpecType(TLB, T: TL);
7135}
7136
7137template<typename Derived>
7138QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7139 TypeLocBuilder &TLB,
7140 TemplateSpecializationTypeLoc TL) {
7141 const TemplateSpecializationType *T = TL.getTypePtr();
7142
7143 // The nested-name-specifier never matters in a TemplateSpecializationType,
7144 // because we can't have a dependent nested-name-specifier anyway.
7145 CXXScopeSpec SS;
7146 TemplateName Template
7147 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7148 TL.getTemplateNameLoc());
7149 if (Template.isNull())
7150 return QualType();
7151
7152 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7153}
7154
7155template<typename Derived>
7156QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7157 AtomicTypeLoc TL) {
7158 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7159 if (ValueType.isNull())
7160 return QualType();
7161
7162 QualType Result = TL.getType();
7163 if (getDerived().AlwaysRebuild() ||
7164 ValueType != TL.getValueLoc().getType()) {
7165 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7166 if (Result.isNull())
7167 return QualType();
7168 }
7169
7170 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7171 NewTL.setKWLoc(TL.getKWLoc());
7172 NewTL.setLParenLoc(TL.getLParenLoc());
7173 NewTL.setRParenLoc(TL.getRParenLoc());
7174
7175 return Result;
7176}
7177
7178template <typename Derived>
7179QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7180 PipeTypeLoc TL) {
7181 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7182 if (ValueType.isNull())
7183 return QualType();
7184
7185 QualType Result = TL.getType();
7186 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7187 const PipeType *PT = Result->castAs<PipeType>();
7188 bool isReadPipe = PT->isReadOnly();
7189 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7190 if (Result.isNull())
7191 return QualType();
7192 }
7193
7194 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7195 NewTL.setKWLoc(TL.getKWLoc());
7196
7197 return Result;
7198}
7199
7200template <typename Derived>
7201QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7202 BitIntTypeLoc TL) {
7203 const BitIntType *EIT = TL.getTypePtr();
7204 QualType Result = TL.getType();
7205
7206 if (getDerived().AlwaysRebuild()) {
7207 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7208 EIT->getNumBits(), TL.getNameLoc());
7209 if (Result.isNull())
7210 return QualType();
7211 }
7212
7213 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7214 NewTL.setNameLoc(TL.getNameLoc());
7215 return Result;
7216}
7217
7218template <typename Derived>
7219QualType TreeTransform<Derived>::TransformDependentBitIntType(
7220 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7221 const DependentBitIntType *EIT = TL.getTypePtr();
7222
7223 EnterExpressionEvaluationContext Unevaluated(
7224 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7225 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7226 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7227
7228 if (BitsExpr.isInvalid())
7229 return QualType();
7230
7231 QualType Result = TL.getType();
7232
7233 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7234 Result = getDerived().RebuildDependentBitIntType(
7235 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7236
7237 if (Result.isNull())
7238 return QualType();
7239 }
7240
7241 if (isa<DependentBitIntType>(Val: Result)) {
7242 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7243 NewTL.setNameLoc(TL.getNameLoc());
7244 } else {
7245 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7246 NewTL.setNameLoc(TL.getNameLoc());
7247 }
7248 return Result;
7249}
7250
7251 /// Simple iterator that traverses the template arguments in a
7252 /// container that provides a \c getArgLoc() member function.
7253 ///
7254 /// This iterator is intended to be used with the iterator form of
7255 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7256 template<typename ArgLocContainer>
7257 class TemplateArgumentLocContainerIterator {
7258 ArgLocContainer *Container;
7259 unsigned Index;
7260
7261 public:
7262 typedef TemplateArgumentLoc value_type;
7263 typedef TemplateArgumentLoc reference;
7264 typedef int difference_type;
7265 typedef std::input_iterator_tag iterator_category;
7266
7267 class pointer {
7268 TemplateArgumentLoc Arg;
7269
7270 public:
7271 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7272
7273 const TemplateArgumentLoc *operator->() const {
7274 return &Arg;
7275 }
7276 };
7277
7278
7279 TemplateArgumentLocContainerIterator() {}
7280
7281 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7282 unsigned Index)
7283 : Container(&Container), Index(Index) { }
7284
7285 TemplateArgumentLocContainerIterator &operator++() {
7286 ++Index;
7287 return *this;
7288 }
7289
7290 TemplateArgumentLocContainerIterator operator++(int) {
7291 TemplateArgumentLocContainerIterator Old(*this);
7292 ++(*this);
7293 return Old;
7294 }
7295
7296 TemplateArgumentLoc operator*() const {
7297 return Container->getArgLoc(Index);
7298 }
7299
7300 pointer operator->() const {
7301 return pointer(Container->getArgLoc(Index));
7302 }
7303
7304 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7305 const TemplateArgumentLocContainerIterator &Y) {
7306 return X.Container == Y.Container && X.Index == Y.Index;
7307 }
7308
7309 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7310 const TemplateArgumentLocContainerIterator &Y) {
7311 return !(X == Y);
7312 }
7313 };
7314
7315template<typename Derived>
7316QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7317 AutoTypeLoc TL) {
7318 const AutoType *T = TL.getTypePtr();
7319 QualType OldDeduced = T->getDeducedType();
7320 QualType NewDeduced;
7321 if (!OldDeduced.isNull()) {
7322 NewDeduced = getDerived().TransformType(OldDeduced);
7323 if (NewDeduced.isNull())
7324 return QualType();
7325 }
7326
7327 ConceptDecl *NewCD = nullptr;
7328 TemplateArgumentListInfo NewTemplateArgs;
7329 NestedNameSpecifierLoc NewNestedNameSpec;
7330 if (T->isConstrained()) {
7331 assert(TL.getConceptReference());
7332 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7333 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7334
7335 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7336 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7337 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7338 if (getDerived().TransformTemplateArguments(
7339 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7340 NewTemplateArgs))
7341 return QualType();
7342
7343 if (TL.getNestedNameSpecifierLoc()) {
7344 NewNestedNameSpec
7345 = getDerived().TransformNestedNameSpecifierLoc(
7346 TL.getNestedNameSpecifierLoc());
7347 if (!NewNestedNameSpec)
7348 return QualType();
7349 }
7350 }
7351
7352 QualType Result = TL.getType();
7353 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7354 T->isDependentType() || T->isConstrained()) {
7355 // FIXME: Maybe don't rebuild if all template arguments are the same.
7356 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7357 NewArgList.reserve(N: NewTemplateArgs.size());
7358 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7359 NewArgList.push_back(Elt: ArgLoc.getArgument());
7360 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7361 NewArgList);
7362 if (Result.isNull())
7363 return QualType();
7364 }
7365
7366 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7367 NewTL.setNameLoc(TL.getNameLoc());
7368 NewTL.setRParenLoc(TL.getRParenLoc());
7369 NewTL.setConceptReference(nullptr);
7370
7371 if (T->isConstrained()) {
7372 DeclarationNameInfo DNI = DeclarationNameInfo(
7373 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7374 TL.getConceptNameLoc(),
7375 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7376 auto *CR = ConceptReference::Create(
7377 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7378 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7379 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7380 NewTL.setConceptReference(CR);
7381 }
7382
7383 return Result;
7384}
7385
7386template <typename Derived>
7387QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7388 TypeLocBuilder &TLB,
7389 TemplateSpecializationTypeLoc TL,
7390 TemplateName Template) {
7391 TemplateArgumentListInfo NewTemplateArgs;
7392 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7393 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7394 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7395 ArgIterator;
7396 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7397 ArgIterator(TL, TL.getNumArgs()),
7398 NewTemplateArgs))
7399 return QualType();
7400
7401 // This needs to be rebuilt if either the arguments changed, or if the
7402 // original template changed. If the template changed, and even if the
7403 // arguments didn't change, these arguments might not correspond to their
7404 // respective parameters, therefore needing conversions.
7405 QualType Result =
7406 getDerived().RebuildTemplateSpecializationType(Template,
7407 TL.getTemplateNameLoc(),
7408 NewTemplateArgs);
7409
7410 if (!Result.isNull()) {
7411 // Specializations of template template parameters are represented as
7412 // TemplateSpecializationTypes, and substitution of type alias templates
7413 // within a dependent context can transform them into
7414 // DependentTemplateSpecializationTypes.
7415 if (isa<DependentTemplateSpecializationType>(Val: Result)) {
7416 DependentTemplateSpecializationTypeLoc NewTL
7417 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7418 NewTL.setElaboratedKeywordLoc(SourceLocation());
7419 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7420 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7421 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7422 NewTL.setLAngleLoc(TL.getLAngleLoc());
7423 NewTL.setRAngleLoc(TL.getRAngleLoc());
7424 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7425 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7426 return Result;
7427 }
7428
7429 TemplateSpecializationTypeLoc NewTL
7430 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7431 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7432 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7433 NewTL.setLAngleLoc(TL.getLAngleLoc());
7434 NewTL.setRAngleLoc(TL.getRAngleLoc());
7435 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7436 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7437 }
7438
7439 return Result;
7440}
7441
7442template <typename Derived>
7443QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7444 TypeLocBuilder &TLB,
7445 DependentTemplateSpecializationTypeLoc TL,
7446 TemplateName Template,
7447 CXXScopeSpec &SS) {
7448 TemplateArgumentListInfo NewTemplateArgs;
7449 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7450 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7451 typedef TemplateArgumentLocContainerIterator<
7452 DependentTemplateSpecializationTypeLoc> ArgIterator;
7453 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7454 ArgIterator(TL, TL.getNumArgs()),
7455 NewTemplateArgs))
7456 return QualType();
7457
7458 // FIXME: maybe don't rebuild if all the template arguments are the same.
7459
7460 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7461 assert(DTN->getQualifier() == SS.getScopeRep());
7462 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7463 TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments());
7464
7465 DependentTemplateSpecializationTypeLoc NewTL
7466 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7467 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7468 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7469 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7470 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7471 NewTL.setLAngleLoc(TL.getLAngleLoc());
7472 NewTL.setRAngleLoc(TL.getRAngleLoc());
7473 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7474 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7475 return Result;
7476 }
7477
7478 QualType Result
7479 = getDerived().RebuildTemplateSpecializationType(Template,
7480 TL.getTemplateNameLoc(),
7481 NewTemplateArgs);
7482
7483 if (!Result.isNull()) {
7484 /// FIXME: Wrap this in an elaborated-type-specifier?
7485 TemplateSpecializationTypeLoc NewTL
7486 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7487 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7488 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7489 NewTL.setLAngleLoc(TL.getLAngleLoc());
7490 NewTL.setRAngleLoc(TL.getRAngleLoc());
7491 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7492 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7493 }
7494
7495 return Result;
7496}
7497
7498template<typename Derived>
7499QualType
7500TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7501 ElaboratedTypeLoc TL) {
7502 const ElaboratedType *T = TL.getTypePtr();
7503
7504 NestedNameSpecifierLoc QualifierLoc;
7505 // NOTE: the qualifier in an ElaboratedType is optional.
7506 if (TL.getQualifierLoc()) {
7507 QualifierLoc
7508 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7509 if (!QualifierLoc)
7510 return QualType();
7511 }
7512
7513 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7514 if (NamedT.isNull())
7515 return QualType();
7516
7517 // C++0x [dcl.type.elab]p2:
7518 // If the identifier resolves to a typedef-name or the simple-template-id
7519 // resolves to an alias template specialization, the
7520 // elaborated-type-specifier is ill-formed.
7521 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7522 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7523 if (const TemplateSpecializationType *TST =
7524 NamedT->getAs<TemplateSpecializationType>()) {
7525 TemplateName Template = TST->getTemplateName();
7526 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7527 Val: Template.getAsTemplateDecl())) {
7528 SemaRef.Diag(Loc: TL.getNamedTypeLoc().getBeginLoc(),
7529 DiagID: diag::err_tag_reference_non_tag)
7530 << TAT << NonTagKind::TypeAliasTemplate
7531 << ElaboratedType::getTagTypeKindForKeyword(Keyword: T->getKeyword());
7532 SemaRef.Diag(Loc: TAT->getLocation(), DiagID: diag::note_declared_at);
7533 }
7534 }
7535 }
7536
7537 QualType Result = TL.getType();
7538 if (getDerived().AlwaysRebuild() ||
7539 QualifierLoc != TL.getQualifierLoc() ||
7540 NamedT != T->getNamedType()) {
7541 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7542 T->getKeyword(),
7543 QualifierLoc, NamedT);
7544 if (Result.isNull())
7545 return QualType();
7546 }
7547
7548 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7549 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7550 NewTL.setQualifierLoc(QualifierLoc);
7551 return Result;
7552}
7553
7554template <typename Derived>
7555QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7556 AttributedTypeLoc TL) {
7557 const AttributedType *oldType = TL.getTypePtr();
7558 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7559 if (modifiedType.isNull())
7560 return QualType();
7561
7562 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7563 const Attr *oldAttr = TL.getAttr();
7564 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7565 if (oldAttr && !newAttr)
7566 return QualType();
7567
7568 QualType result = TL.getType();
7569
7570 // FIXME: dependent operand expressions?
7571 if (getDerived().AlwaysRebuild() ||
7572 modifiedType != oldType->getModifiedType()) {
7573 // If the equivalent type is equal to the modified type, we don't want to
7574 // transform it as well because:
7575 //
7576 // 1. The transformation would yield the same result and is therefore
7577 // superfluous, and
7578 //
7579 // 2. Transforming the same type twice can cause problems, e.g. if it
7580 // is a FunctionProtoType, we may end up instantiating the function
7581 // parameters twice, which causes an assertion since the parameters
7582 // are already bound to their counterparts in the template for this
7583 // instantiation.
7584 //
7585 QualType equivalentType = modifiedType;
7586 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7587 TypeLocBuilder AuxiliaryTLB;
7588 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7589 equivalentType =
7590 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7591 if (equivalentType.isNull())
7592 return QualType();
7593 }
7594
7595 // Check whether we can add nullability; it is only represented as
7596 // type sugar, and therefore cannot be diagnosed in any other way.
7597 if (auto nullability = oldType->getImmediateNullability()) {
7598 if (!modifiedType->canHaveNullability()) {
7599 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7600 : TL.getModifiedLoc().getBeginLoc()),
7601 DiagID: diag::err_nullability_nonpointer)
7602 << DiagNullabilityKind(*nullability, false) << modifiedType;
7603 return QualType();
7604 }
7605 }
7606
7607 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7608 modifiedType,
7609 equivalentType,
7610 attr: TL.getAttr());
7611 }
7612
7613 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7614 newTL.setAttr(newAttr);
7615 return result;
7616}
7617
7618template <typename Derived>
7619QualType TreeTransform<Derived>::TransformCountAttributedType(
7620 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7621 const CountAttributedType *OldTy = TL.getTypePtr();
7622 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7623 if (InnerTy.isNull())
7624 return QualType();
7625
7626 Expr *OldCount = TL.getCountExpr();
7627 Expr *NewCount = nullptr;
7628 if (OldCount) {
7629 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7630 if (CountResult.isInvalid())
7631 return QualType();
7632 NewCount = CountResult.get();
7633 }
7634
7635 QualType Result = TL.getType();
7636 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7637 OldCount != NewCount) {
7638 // Currently, CountAttributedType can only wrap incomplete array types.
7639 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7640 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7641 }
7642
7643 TLB.push<CountAttributedTypeLoc>(T: Result);
7644 return Result;
7645}
7646
7647template <typename Derived>
7648QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7649 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7650 // The BTFTagAttributedType is available for C only.
7651 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7652}
7653
7654template <typename Derived>
7655QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7656 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7657
7658 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7659
7660 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7661 if (WrappedTy.isNull())
7662 return QualType();
7663
7664 QualType ContainedTy = QualType();
7665 QualType OldContainedTy = oldType->getContainedType();
7666 if (!OldContainedTy.isNull()) {
7667 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7668 if (!oldContainedTSI)
7669 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7670 OldContainedTy, SourceLocation());
7671 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7672 if (!ContainedTSI)
7673 return QualType();
7674 ContainedTy = ContainedTSI->getType();
7675 }
7676
7677 QualType Result = TL.getType();
7678 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7679 ContainedTy != oldType->getContainedType()) {
7680 Result = SemaRef.Context.getHLSLAttributedResourceType(
7681 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7682 }
7683
7684 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7685 return Result;
7686}
7687
7688template <typename Derived>
7689QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7690 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7691 // No transformations needed.
7692 return TL.getType();
7693}
7694
7695template<typename Derived>
7696QualType
7697TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7698 ParenTypeLoc TL) {
7699 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7700 if (Inner.isNull())
7701 return QualType();
7702
7703 QualType Result = TL.getType();
7704 if (getDerived().AlwaysRebuild() ||
7705 Inner != TL.getInnerLoc().getType()) {
7706 Result = getDerived().RebuildParenType(Inner);
7707 if (Result.isNull())
7708 return QualType();
7709 }
7710
7711 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7712 NewTL.setLParenLoc(TL.getLParenLoc());
7713 NewTL.setRParenLoc(TL.getRParenLoc());
7714 return Result;
7715}
7716
7717template <typename Derived>
7718QualType
7719TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7720 MacroQualifiedTypeLoc TL) {
7721 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7722 if (Inner.isNull())
7723 return QualType();
7724
7725 QualType Result = TL.getType();
7726 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7727 Result =
7728 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7729 if (Result.isNull())
7730 return QualType();
7731 }
7732
7733 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7734 NewTL.setExpansionLoc(TL.getExpansionLoc());
7735 return Result;
7736}
7737
7738template<typename Derived>
7739QualType TreeTransform<Derived>::TransformDependentNameType(
7740 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7741 return TransformDependentNameType(TLB, TL, false);
7742}
7743
7744template<typename Derived>
7745QualType TreeTransform<Derived>::TransformDependentNameType(
7746 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7747 const DependentNameType *T = TL.getTypePtr();
7748
7749 NestedNameSpecifierLoc QualifierLoc
7750 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7751 if (!QualifierLoc)
7752 return QualType();
7753
7754 QualType Result
7755 = getDerived().RebuildDependentNameType(T->getKeyword(),
7756 TL.getElaboratedKeywordLoc(),
7757 QualifierLoc,
7758 T->getIdentifier(),
7759 TL.getNameLoc(),
7760 DeducedTSTContext);
7761 if (Result.isNull())
7762 return QualType();
7763
7764 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7765 QualType NamedT = ElabT->getNamedType();
7766 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7767
7768 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7769 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7770 NewTL.setQualifierLoc(QualifierLoc);
7771 } else {
7772 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7773 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7774 NewTL.setQualifierLoc(QualifierLoc);
7775 NewTL.setNameLoc(TL.getNameLoc());
7776 }
7777 return Result;
7778}
7779
7780template<typename Derived>
7781QualType TreeTransform<Derived>::
7782 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7783 DependentTemplateSpecializationTypeLoc TL) {
7784 NestedNameSpecifierLoc QualifierLoc;
7785 if (TL.getQualifierLoc()) {
7786 QualifierLoc
7787 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7788 if (!QualifierLoc)
7789 return QualType();
7790 }
7791
7792 CXXScopeSpec SS;
7793 SS.Adopt(Other: QualifierLoc);
7794 return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS);
7795}
7796
7797template <typename Derived>
7798QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7799 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
7800 CXXScopeSpec &SS) {
7801 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7802
7803 TemplateArgumentListInfo NewTemplateArgs;
7804 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7805 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7806
7807 auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator<
7808 DependentTemplateSpecializationTypeLoc>>(x: {TL, 0}, y: {TL, TL.getNumArgs()});
7809
7810 if (getDerived().TransformTemplateArguments(ArgsRange.begin(),
7811 ArgsRange.end(), NewTemplateArgs))
7812 return QualType();
7813 bool TemplateArgumentsChanged = !llvm::equal(
7814 ArgsRange, NewTemplateArgs.arguments(),
7815 [](const TemplateArgumentLoc &A, const TemplateArgumentLoc &B) {
7816 return A.getArgument().structurallyEquals(Other: B.getArgument());
7817 });
7818
7819 const DependentTemplateStorage &DTN = T->getDependentTemplateName();
7820
7821 QualType Result = TL.getType();
7822 if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() ||
7823 TemplateArgumentsChanged) {
7824 TemplateName Name = getDerived().RebuildTemplateName(
7825 SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(),
7826 /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7827 /*AllowInjectedClassName=*/false);
7828 if (Name.isNull())
7829 return QualType();
7830 Result = getDerived().RebuildDependentTemplateSpecializationType(
7831 T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name,
7832 TL.getTemplateNameLoc(), NewTemplateArgs,
7833 /*AllowInjectedClassName=*/false);
7834 if (Result.isNull())
7835 return QualType();
7836 }
7837
7838 NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context&: SemaRef.Context);
7839 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Val&: Result)) {
7840 QualType NamedT = ElabT->getNamedType();
7841
7842 // Copy information relevant to the template specialization.
7843 TemplateSpecializationTypeLoc NamedTL
7844 = TLB.push<TemplateSpecializationTypeLoc>(T: NamedT);
7845 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7846 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7847 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7848 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7849 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7850 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7851
7852 // Copy information relevant to the elaborated type.
7853 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7854 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7855 NewTL.setQualifierLoc(QualifierLoc);
7856 } else {
7857 assert(isa<DependentTemplateSpecializationType>(Result));
7858 DependentTemplateSpecializationTypeLoc SpecTL
7859 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7860 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7861 SpecTL.setQualifierLoc(QualifierLoc);
7862 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7863 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7864 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7865 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7866 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7867 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7868 }
7869 return Result;
7870}
7871
7872template<typename Derived>
7873QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7874 PackExpansionTypeLoc TL) {
7875 QualType Pattern
7876 = getDerived().TransformType(TLB, TL.getPatternLoc());
7877 if (Pattern.isNull())
7878 return QualType();
7879
7880 QualType Result = TL.getType();
7881 if (getDerived().AlwaysRebuild() ||
7882 Pattern != TL.getPatternLoc().getType()) {
7883 Result = getDerived().RebuildPackExpansionType(Pattern,
7884 TL.getPatternLoc().getSourceRange(),
7885 TL.getEllipsisLoc(),
7886 TL.getTypePtr()->getNumExpansions());
7887 if (Result.isNull())
7888 return QualType();
7889 }
7890
7891 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7892 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7893 return Result;
7894}
7895
7896template<typename Derived>
7897QualType
7898TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7899 ObjCInterfaceTypeLoc TL) {
7900 // ObjCInterfaceType is never dependent.
7901 TLB.pushFullCopy(L: TL);
7902 return TL.getType();
7903}
7904
7905template<typename Derived>
7906QualType
7907TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7908 ObjCTypeParamTypeLoc TL) {
7909 const ObjCTypeParamType *T = TL.getTypePtr();
7910 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7911 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7912 if (!OTP)
7913 return QualType();
7914
7915 QualType Result = TL.getType();
7916 if (getDerived().AlwaysRebuild() ||
7917 OTP != T->getDecl()) {
7918 Result = getDerived().RebuildObjCTypeParamType(
7919 OTP, TL.getProtocolLAngleLoc(),
7920 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7921 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7922 if (Result.isNull())
7923 return QualType();
7924 }
7925
7926 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7927 if (TL.getNumProtocols()) {
7928 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7929 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7930 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7931 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7932 }
7933 return Result;
7934}
7935
7936template<typename Derived>
7937QualType
7938TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7939 ObjCObjectTypeLoc TL) {
7940 // Transform base type.
7941 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7942 if (BaseType.isNull())
7943 return QualType();
7944
7945 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7946
7947 // Transform type arguments.
7948 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7949 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7950 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7951 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7952 QualType TypeArg = TypeArgInfo->getType();
7953 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7954 AnyChanged = true;
7955
7956 // We have a pack expansion. Instantiate it.
7957 const auto *PackExpansion = PackExpansionLoc.getType()
7958 ->castAs<PackExpansionType>();
7959 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7960 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
7961 Unexpanded);
7962 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7963
7964 // Determine whether the set of unexpanded parameter packs can
7965 // and should be expanded.
7966 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7967 bool Expand = false;
7968 bool RetainExpansion = false;
7969 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
7970 if (getDerived().TryExpandParameterPacks(
7971 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7972 Unexpanded, Expand, RetainExpansion, NumExpansions))
7973 return QualType();
7974
7975 if (!Expand) {
7976 // We can't expand this pack expansion into separate arguments yet;
7977 // just substitute into the pattern and create a new pack expansion
7978 // type.
7979 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7980
7981 TypeLocBuilder TypeArgBuilder;
7982 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7983 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7984 PatternLoc);
7985 if (NewPatternType.isNull())
7986 return QualType();
7987
7988 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7989 Pattern: NewPatternType, NumExpansions);
7990 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
7991 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7992 NewTypeArgInfos.push_back(
7993 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
7994 continue;
7995 }
7996
7997 // Substitute into the pack expansion pattern for each slice of the
7998 // pack.
7999 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8000 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8001
8002 TypeLocBuilder TypeArgBuilder;
8003 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8004
8005 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8006 PatternLoc);
8007 if (NewTypeArg.isNull())
8008 return QualType();
8009
8010 NewTypeArgInfos.push_back(
8011 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8012 }
8013
8014 continue;
8015 }
8016
8017 TypeLocBuilder TypeArgBuilder;
8018 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8019 QualType NewTypeArg =
8020 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8021 if (NewTypeArg.isNull())
8022 return QualType();
8023
8024 // If nothing changed, just keep the old TypeSourceInfo.
8025 if (NewTypeArg == TypeArg) {
8026 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8027 continue;
8028 }
8029
8030 NewTypeArgInfos.push_back(
8031 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8032 AnyChanged = true;
8033 }
8034
8035 QualType Result = TL.getType();
8036 if (getDerived().AlwaysRebuild() || AnyChanged) {
8037 // Rebuild the type.
8038 Result = getDerived().RebuildObjCObjectType(
8039 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8040 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8041 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8042 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8043
8044 if (Result.isNull())
8045 return QualType();
8046 }
8047
8048 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8049 NewT.setHasBaseTypeAsWritten(true);
8050 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8051 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8052 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8053 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8054 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8055 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8056 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8057 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8058 return Result;
8059}
8060
8061template<typename Derived>
8062QualType
8063TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8064 ObjCObjectPointerTypeLoc TL) {
8065 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8066 if (PointeeType.isNull())
8067 return QualType();
8068
8069 QualType Result = TL.getType();
8070 if (getDerived().AlwaysRebuild() ||
8071 PointeeType != TL.getPointeeLoc().getType()) {
8072 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8073 TL.getStarLoc());
8074 if (Result.isNull())
8075 return QualType();
8076 }
8077
8078 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8079 NewT.setStarLoc(TL.getStarLoc());
8080 return Result;
8081}
8082
8083//===----------------------------------------------------------------------===//
8084// Statement transformation
8085//===----------------------------------------------------------------------===//
8086template<typename Derived>
8087StmtResult
8088TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8089 return S;
8090}
8091
8092template<typename Derived>
8093StmtResult
8094TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8095 return getDerived().TransformCompoundStmt(S, false);
8096}
8097
8098template<typename Derived>
8099StmtResult
8100TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8101 bool IsStmtExpr) {
8102 Sema::CompoundScopeRAII CompoundScope(getSema());
8103 Sema::FPFeaturesStateRAII FPSave(getSema());
8104 if (S->hasStoredFPFeatures())
8105 getSema().resetFPOptions(
8106 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8107
8108 const Stmt *ExprResult = S->getStmtExprResult();
8109 bool SubStmtInvalid = false;
8110 bool SubStmtChanged = false;
8111 SmallVector<Stmt*, 8> Statements;
8112 for (auto *B : S->body()) {
8113 StmtResult Result = getDerived().TransformStmt(
8114 B, IsStmtExpr && B == ExprResult ? StmtDiscardKind::StmtExprResult
8115 : StmtDiscardKind::Discarded);
8116
8117 if (Result.isInvalid()) {
8118 // Immediately fail if this was a DeclStmt, since it's very
8119 // likely that this will cause problems for future statements.
8120 if (isa<DeclStmt>(Val: B))
8121 return StmtError();
8122
8123 // Otherwise, just keep processing substatements and fail later.
8124 SubStmtInvalid = true;
8125 continue;
8126 }
8127
8128 SubStmtChanged = SubStmtChanged || Result.get() != B;
8129 Statements.push_back(Elt: Result.getAs<Stmt>());
8130 }
8131
8132 if (SubStmtInvalid)
8133 return StmtError();
8134
8135 if (!getDerived().AlwaysRebuild() &&
8136 !SubStmtChanged)
8137 return S;
8138
8139 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8140 Statements,
8141 S->getRBracLoc(),
8142 IsStmtExpr);
8143}
8144
8145template<typename Derived>
8146StmtResult
8147TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8148 ExprResult LHS, RHS;
8149 {
8150 EnterExpressionEvaluationContext Unevaluated(
8151 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8152
8153 // Transform the left-hand case value.
8154 LHS = getDerived().TransformExpr(S->getLHS());
8155 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8156 if (LHS.isInvalid())
8157 return StmtError();
8158
8159 // Transform the right-hand case value (for the GNU case-range extension).
8160 RHS = getDerived().TransformExpr(S->getRHS());
8161 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8162 if (RHS.isInvalid())
8163 return StmtError();
8164 }
8165
8166 // Build the case statement.
8167 // Case statements are always rebuilt so that they will attached to their
8168 // transformed switch statement.
8169 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8170 LHS.get(),
8171 S->getEllipsisLoc(),
8172 RHS.get(),
8173 S->getColonLoc());
8174 if (Case.isInvalid())
8175 return StmtError();
8176
8177 // Transform the statement following the case
8178 StmtResult SubStmt =
8179 getDerived().TransformStmt(S->getSubStmt());
8180 if (SubStmt.isInvalid())
8181 return StmtError();
8182
8183 // Attach the body to the case statement
8184 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8185}
8186
8187template <typename Derived>
8188StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8189 // Transform the statement following the default case
8190 StmtResult SubStmt =
8191 getDerived().TransformStmt(S->getSubStmt());
8192 if (SubStmt.isInvalid())
8193 return StmtError();
8194
8195 // Default statements are always rebuilt
8196 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8197 SubStmt.get());
8198}
8199
8200template<typename Derived>
8201StmtResult
8202TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8203 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8204 if (SubStmt.isInvalid())
8205 return StmtError();
8206
8207 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8208 S->getDecl());
8209 if (!LD)
8210 return StmtError();
8211
8212 // If we're transforming "in-place" (we're not creating new local
8213 // declarations), assume we're replacing the old label statement
8214 // and clear out the reference to it.
8215 if (LD == S->getDecl())
8216 S->getDecl()->setStmt(nullptr);
8217
8218 // FIXME: Pass the real colon location in.
8219 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8220 cast<LabelDecl>(Val: LD), SourceLocation(),
8221 SubStmt.get());
8222}
8223
8224template <typename Derived>
8225const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8226 if (!R)
8227 return R;
8228
8229 switch (R->getKind()) {
8230// Transform attributes by calling TransformXXXAttr.
8231#define ATTR(X) \
8232 case attr::X: \
8233 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8234#include "clang/Basic/AttrList.inc"
8235 }
8236 return R;
8237}
8238
8239template <typename Derived>
8240const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8241 const Stmt *InstS,
8242 const Attr *R) {
8243 if (!R)
8244 return R;
8245
8246 switch (R->getKind()) {
8247// Transform attributes by calling TransformStmtXXXAttr.
8248#define ATTR(X) \
8249 case attr::X: \
8250 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8251#include "clang/Basic/AttrList.inc"
8252 }
8253 return TransformAttr(R);
8254}
8255
8256template <typename Derived>
8257StmtResult
8258TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8259 StmtDiscardKind SDK) {
8260 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8261 if (SubStmt.isInvalid())
8262 return StmtError();
8263
8264 bool AttrsChanged = false;
8265 SmallVector<const Attr *, 1> Attrs;
8266
8267 // Visit attributes and keep track if any are transformed.
8268 for (const auto *I : S->getAttrs()) {
8269 const Attr *R =
8270 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8271 AttrsChanged |= (I != R);
8272 if (R)
8273 Attrs.push_back(Elt: R);
8274 }
8275
8276 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8277 return S;
8278
8279 // If transforming the attributes failed for all of the attributes in the
8280 // statement, don't make an AttributedStmt without attributes.
8281 if (Attrs.empty())
8282 return SubStmt;
8283
8284 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8285 SubStmt.get());
8286}
8287
8288template<typename Derived>
8289StmtResult
8290TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8291 // Transform the initialization statement
8292 StmtResult Init = getDerived().TransformStmt(S->getInit());
8293 if (Init.isInvalid())
8294 return StmtError();
8295
8296 Sema::ConditionResult Cond;
8297 if (!S->isConsteval()) {
8298 // Transform the condition
8299 Cond = getDerived().TransformCondition(
8300 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8301 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8302 : Sema::ConditionKind::Boolean);
8303 if (Cond.isInvalid())
8304 return StmtError();
8305 }
8306
8307 // If this is a constexpr if, determine which arm we should instantiate.
8308 std::optional<bool> ConstexprConditionValue;
8309 if (S->isConstexpr())
8310 ConstexprConditionValue = Cond.getKnownValue();
8311
8312 // Transform the "then" branch.
8313 StmtResult Then;
8314 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8315 EnterExpressionEvaluationContext Ctx(
8316 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8317 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8318 S->isNonNegatedConsteval());
8319
8320 Then = getDerived().TransformStmt(S->getThen());
8321 if (Then.isInvalid())
8322 return StmtError();
8323 } else {
8324 // Discarded branch is replaced with empty CompoundStmt so we can keep
8325 // proper source location for start and end of original branch, so
8326 // subsequent transformations like CoverageMapping work properly
8327 Then = new (getSema().Context)
8328 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8329 }
8330
8331 // Transform the "else" branch.
8332 StmtResult Else;
8333 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8334 EnterExpressionEvaluationContext Ctx(
8335 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8336 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8337 S->isNegatedConsteval());
8338
8339 Else = getDerived().TransformStmt(S->getElse());
8340 if (Else.isInvalid())
8341 return StmtError();
8342 } else if (S->getElse() && ConstexprConditionValue &&
8343 *ConstexprConditionValue) {
8344 // Same thing here as with <then> branch, we are discarding it, we can't
8345 // replace it with NULL nor NullStmt as we need to keep for source location
8346 // range, for CoverageMapping
8347 Else = new (getSema().Context)
8348 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8349 }
8350
8351 if (!getDerived().AlwaysRebuild() &&
8352 Init.get() == S->getInit() &&
8353 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8354 Then.get() == S->getThen() &&
8355 Else.get() == S->getElse())
8356 return S;
8357
8358 return getDerived().RebuildIfStmt(
8359 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8360 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8361}
8362
8363template<typename Derived>
8364StmtResult
8365TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8366 // Transform the initialization statement
8367 StmtResult Init = getDerived().TransformStmt(S->getInit());
8368 if (Init.isInvalid())
8369 return StmtError();
8370
8371 // Transform the condition.
8372 Sema::ConditionResult Cond = getDerived().TransformCondition(
8373 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8374 Sema::ConditionKind::Switch);
8375 if (Cond.isInvalid())
8376 return StmtError();
8377
8378 // Rebuild the switch statement.
8379 StmtResult Switch =
8380 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8381 Init.get(), Cond, S->getRParenLoc());
8382 if (Switch.isInvalid())
8383 return StmtError();
8384
8385 // Transform the body of the switch statement.
8386 StmtResult Body = getDerived().TransformStmt(S->getBody());
8387 if (Body.isInvalid())
8388 return StmtError();
8389
8390 // Complete the switch statement.
8391 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8392 Body.get());
8393}
8394
8395template<typename Derived>
8396StmtResult
8397TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8398 // Transform the condition
8399 Sema::ConditionResult Cond = getDerived().TransformCondition(
8400 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8401 Sema::ConditionKind::Boolean);
8402 if (Cond.isInvalid())
8403 return StmtError();
8404
8405 // OpenACC Restricts a while-loop inside of certain construct/clause
8406 // combinations, so diagnose that here in OpenACC mode.
8407 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8408 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8409
8410 // Transform the body
8411 StmtResult Body = getDerived().TransformStmt(S->getBody());
8412 if (Body.isInvalid())
8413 return StmtError();
8414
8415 if (!getDerived().AlwaysRebuild() &&
8416 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8417 Body.get() == S->getBody())
8418 return Owned(S);
8419
8420 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8421 Cond, S->getRParenLoc(), Body.get());
8422}
8423
8424template<typename Derived>
8425StmtResult
8426TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8427 // OpenACC Restricts a do-loop inside of certain construct/clause
8428 // combinations, so diagnose that here in OpenACC mode.
8429 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8430 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8431
8432 // Transform the body
8433 StmtResult Body = getDerived().TransformStmt(S->getBody());
8434 if (Body.isInvalid())
8435 return StmtError();
8436
8437 // Transform the condition
8438 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8439 if (Cond.isInvalid())
8440 return StmtError();
8441
8442 if (!getDerived().AlwaysRebuild() &&
8443 Cond.get() == S->getCond() &&
8444 Body.get() == S->getBody())
8445 return S;
8446
8447 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8448 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8449 S->getRParenLoc());
8450}
8451
8452template<typename Derived>
8453StmtResult
8454TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8455 if (getSema().getLangOpts().OpenMP)
8456 getSema().OpenMP().startOpenMPLoop();
8457
8458 // Transform the initialization statement
8459 StmtResult Init = getDerived().TransformStmt(S->getInit());
8460 if (Init.isInvalid())
8461 return StmtError();
8462
8463 // In OpenMP loop region loop control variable must be captured and be
8464 // private. Perform analysis of first part (if any).
8465 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8466 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8467 Init.get());
8468
8469 // Transform the condition
8470 Sema::ConditionResult Cond = getDerived().TransformCondition(
8471 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8472 Sema::ConditionKind::Boolean);
8473 if (Cond.isInvalid())
8474 return StmtError();
8475
8476 // Transform the increment
8477 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8478 if (Inc.isInvalid())
8479 return StmtError();
8480
8481 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8482 if (S->getInc() && !FullInc.get())
8483 return StmtError();
8484
8485 // OpenACC Restricts a for-loop inside of certain construct/clause
8486 // combinations, so diagnose that here in OpenACC mode.
8487 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8488 SemaRef.OpenACC().ActOnForStmtBegin(
8489 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8490 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8491
8492 // Transform the body
8493 StmtResult Body = getDerived().TransformStmt(S->getBody());
8494 if (Body.isInvalid())
8495 return StmtError();
8496
8497 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8498
8499 if (!getDerived().AlwaysRebuild() &&
8500 Init.get() == S->getInit() &&
8501 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8502 Inc.get() == S->getInc() &&
8503 Body.get() == S->getBody())
8504 return S;
8505
8506 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8507 Init.get(), Cond, FullInc,
8508 S->getRParenLoc(), Body.get());
8509}
8510
8511template<typename Derived>
8512StmtResult
8513TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8514 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8515 S->getLabel());
8516 if (!LD)
8517 return StmtError();
8518
8519 // Goto statements must always be rebuilt, to resolve the label.
8520 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8521 cast<LabelDecl>(Val: LD));
8522}
8523
8524template<typename Derived>
8525StmtResult
8526TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8527 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8528 if (Target.isInvalid())
8529 return StmtError();
8530 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8531
8532 if (!getDerived().AlwaysRebuild() &&
8533 Target.get() == S->getTarget())
8534 return S;
8535
8536 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8537 Target.get());
8538}
8539
8540template<typename Derived>
8541StmtResult
8542TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8543 return S;
8544}
8545
8546template<typename Derived>
8547StmtResult
8548TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8549 return S;
8550}
8551
8552template<typename Derived>
8553StmtResult
8554TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8555 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8556 /*NotCopyInit*/false);
8557 if (Result.isInvalid())
8558 return StmtError();
8559
8560 // FIXME: We always rebuild the return statement because there is no way
8561 // to tell whether the return type of the function has changed.
8562 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8563}
8564
8565template<typename Derived>
8566StmtResult
8567TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8568 bool DeclChanged = false;
8569 SmallVector<Decl *, 4> Decls;
8570 LambdaScopeInfo *LSI = getSema().getCurLambda();
8571 for (auto *D : S->decls()) {
8572 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8573 if (!Transformed)
8574 return StmtError();
8575
8576 if (Transformed != D)
8577 DeclChanged = true;
8578
8579 if (LSI) {
8580 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed))
8581 LSI->ContainsUnexpandedParameterPack |=
8582 getSema()
8583 .getASTContext()
8584 .getTypeDeclType(TD)
8585 .getSingleStepDesugaredType(getSema().getASTContext())
8586 ->containsUnexpandedParameterPack();
8587
8588 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8589 LSI->ContainsUnexpandedParameterPack |=
8590 VD->getType()->containsUnexpandedParameterPack();
8591 }
8592
8593 Decls.push_back(Elt: Transformed);
8594 }
8595
8596 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8597 return S;
8598
8599 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8600}
8601
8602template<typename Derived>
8603StmtResult
8604TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8605
8606 SmallVector<Expr*, 8> Constraints;
8607 SmallVector<Expr*, 8> Exprs;
8608 SmallVector<IdentifierInfo *, 4> Names;
8609
8610 SmallVector<Expr*, 8> Clobbers;
8611
8612 bool ExprsChanged = false;
8613
8614 auto RebuildString = [&](Expr *E) {
8615 ExprResult Result = getDerived().TransformExpr(E);
8616 if (!Result.isUsable())
8617 return Result;
8618 if (Result.get() != E) {
8619 ExprsChanged = true;
8620 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8621 }
8622 return Result;
8623 };
8624
8625 // Go through the outputs.
8626 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8627 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8628
8629 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8630 if (Result.isInvalid())
8631 return StmtError();
8632
8633 Constraints.push_back(Elt: Result.get());
8634
8635 // Transform the output expr.
8636 Expr *OutputExpr = S->getOutputExpr(i: I);
8637 Result = getDerived().TransformExpr(OutputExpr);
8638 if (Result.isInvalid())
8639 return StmtError();
8640
8641 ExprsChanged |= Result.get() != OutputExpr;
8642
8643 Exprs.push_back(Elt: Result.get());
8644 }
8645
8646 // Go through the inputs.
8647 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8648 Names.push_back(Elt: S->getInputIdentifier(i: I));
8649
8650 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8651 if (Result.isInvalid())
8652 return StmtError();
8653
8654 Constraints.push_back(Elt: Result.get());
8655
8656 // Transform the input expr.
8657 Expr *InputExpr = S->getInputExpr(i: I);
8658 Result = getDerived().TransformExpr(InputExpr);
8659 if (Result.isInvalid())
8660 return StmtError();
8661
8662 ExprsChanged |= Result.get() != InputExpr;
8663
8664 Exprs.push_back(Elt: Result.get());
8665 }
8666
8667 // Go through the Labels.
8668 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8669 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8670
8671 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8672 if (Result.isInvalid())
8673 return StmtError();
8674 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8675 Exprs.push_back(Elt: Result.get());
8676 }
8677
8678 // Go through the clobbers.
8679 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8680 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8681 if (Result.isInvalid())
8682 return StmtError();
8683 Clobbers.push_back(Elt: Result.get());
8684 }
8685
8686 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8687 if (AsmString.isInvalid())
8688 return StmtError();
8689
8690 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8691 return S;
8692
8693 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8694 S->isVolatile(), S->getNumOutputs(),
8695 S->getNumInputs(), Names.data(),
8696 Constraints, Exprs, AsmString.get(),
8697 Clobbers, S->getNumLabels(),
8698 S->getRParenLoc());
8699}
8700
8701template<typename Derived>
8702StmtResult
8703TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8704 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8705
8706 bool HadError = false, HadChange = false;
8707
8708 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8709 SmallVector<Expr*, 8> TransformedExprs;
8710 TransformedExprs.reserve(N: SrcExprs.size());
8711 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8712 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8713 if (!Result.isUsable()) {
8714 HadError = true;
8715 } else {
8716 HadChange |= (Result.get() != SrcExprs[i]);
8717 TransformedExprs.push_back(Elt: Result.get());
8718 }
8719 }
8720
8721 if (HadError) return StmtError();
8722 if (!HadChange && !getDerived().AlwaysRebuild())
8723 return Owned(S);
8724
8725 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8726 AsmToks, S->getAsmString(),
8727 S->getNumOutputs(), S->getNumInputs(),
8728 S->getAllConstraints(), S->getClobbers(),
8729 TransformedExprs, S->getEndLoc());
8730}
8731
8732// C++ Coroutines
8733template<typename Derived>
8734StmtResult
8735TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8736 auto *ScopeInfo = SemaRef.getCurFunction();
8737 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8738 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8739 ScopeInfo->NeedsCoroutineSuspends &&
8740 ScopeInfo->CoroutineSuspends.first == nullptr &&
8741 ScopeInfo->CoroutineSuspends.second == nullptr &&
8742 "expected clean scope info");
8743
8744 // Set that we have (possibly-invalid) suspend points before we do anything
8745 // that may fail.
8746 ScopeInfo->setNeedsCoroutineSuspends(false);
8747
8748 // We re-build the coroutine promise object (and the coroutine parameters its
8749 // type and constructor depend on) based on the types used in our current
8750 // function. We must do so, and set it on the current FunctionScopeInfo,
8751 // before attempting to transform the other parts of the coroutine body
8752 // statement, such as the implicit suspend statements (because those
8753 // statements reference the FunctionScopeInfo::CoroutinePromise).
8754 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8755 return StmtError();
8756 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8757 if (!Promise)
8758 return StmtError();
8759 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8760 ScopeInfo->CoroutinePromise = Promise;
8761
8762 // Transform the implicit coroutine statements constructed using dependent
8763 // types during the previous parse: initial and final suspensions, the return
8764 // object, and others. We also transform the coroutine function's body.
8765 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8766 if (InitSuspend.isInvalid())
8767 return StmtError();
8768 StmtResult FinalSuspend =
8769 getDerived().TransformStmt(S->getFinalSuspendStmt());
8770 if (FinalSuspend.isInvalid() ||
8771 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8772 return StmtError();
8773 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8774 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8775
8776 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8777 if (BodyRes.isInvalid())
8778 return StmtError();
8779
8780 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8781 if (Builder.isInvalid())
8782 return StmtError();
8783
8784 Expr *ReturnObject = S->getReturnValueInit();
8785 assert(ReturnObject && "the return object is expected to be valid");
8786 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8787 /*NoCopyInit*/ false);
8788 if (Res.isInvalid())
8789 return StmtError();
8790 Builder.ReturnValue = Res.get();
8791
8792 // If during the previous parse the coroutine still had a dependent promise
8793 // statement, we may need to build some implicit coroutine statements
8794 // (such as exception and fallthrough handlers) for the first time.
8795 if (S->hasDependentPromiseType()) {
8796 // We can only build these statements, however, if the current promise type
8797 // is not dependent.
8798 if (!Promise->getType()->isDependentType()) {
8799 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8800 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8801 "these nodes should not have been built yet");
8802 if (!Builder.buildDependentStatements())
8803 return StmtError();
8804 }
8805 } else {
8806 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8807 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8808 if (Res.isInvalid())
8809 return StmtError();
8810 Builder.OnFallthrough = Res.get();
8811 }
8812
8813 if (auto *OnException = S->getExceptionHandler()) {
8814 StmtResult Res = getDerived().TransformStmt(OnException);
8815 if (Res.isInvalid())
8816 return StmtError();
8817 Builder.OnException = Res.get();
8818 }
8819
8820 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8821 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8822 if (Res.isInvalid())
8823 return StmtError();
8824 Builder.ReturnStmtOnAllocFailure = Res.get();
8825 }
8826
8827 // Transform any additional statements we may have already built
8828 assert(S->getAllocate() && S->getDeallocate() &&
8829 "allocation and deallocation calls must already be built");
8830 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8831 if (AllocRes.isInvalid())
8832 return StmtError();
8833 Builder.Allocate = AllocRes.get();
8834
8835 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8836 if (DeallocRes.isInvalid())
8837 return StmtError();
8838 Builder.Deallocate = DeallocRes.get();
8839
8840 if (auto *ResultDecl = S->getResultDecl()) {
8841 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8842 if (Res.isInvalid())
8843 return StmtError();
8844 Builder.ResultDecl = Res.get();
8845 }
8846
8847 if (auto *ReturnStmt = S->getReturnStmt()) {
8848 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8849 if (Res.isInvalid())
8850 return StmtError();
8851 Builder.ReturnStmt = Res.get();
8852 }
8853 }
8854
8855 return getDerived().RebuildCoroutineBodyStmt(Builder);
8856}
8857
8858template<typename Derived>
8859StmtResult
8860TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8861 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8862 /*NotCopyInit*/false);
8863 if (Result.isInvalid())
8864 return StmtError();
8865
8866 // Always rebuild; we don't know if this needs to be injected into a new
8867 // context or if the promise type has changed.
8868 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8869 S->isImplicit());
8870}
8871
8872template <typename Derived>
8873ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8874 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8875 /*NotCopyInit*/ false);
8876 if (Operand.isInvalid())
8877 return ExprError();
8878
8879 // Rebuild the common-expr from the operand rather than transforming it
8880 // separately.
8881
8882 // FIXME: getCurScope() should not be used during template instantiation.
8883 // We should pick up the set of unqualified lookup results for operator
8884 // co_await during the initial parse.
8885 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8886 getSema().getCurScope(), E->getKeywordLoc());
8887
8888 // Always rebuild; we don't know if this needs to be injected into a new
8889 // context or if the promise type has changed.
8890 return getDerived().RebuildCoawaitExpr(
8891 E->getKeywordLoc(), Operand.get(),
8892 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8893}
8894
8895template <typename Derived>
8896ExprResult
8897TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8898 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8899 /*NotCopyInit*/ false);
8900 if (OperandResult.isInvalid())
8901 return ExprError();
8902
8903 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8904 E->getOperatorCoawaitLookup());
8905
8906 if (LookupResult.isInvalid())
8907 return ExprError();
8908
8909 // Always rebuild; we don't know if this needs to be injected into a new
8910 // context or if the promise type has changed.
8911 return getDerived().RebuildDependentCoawaitExpr(
8912 E->getKeywordLoc(), OperandResult.get(),
8913 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8914}
8915
8916template<typename Derived>
8917ExprResult
8918TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8919 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8920 /*NotCopyInit*/false);
8921 if (Result.isInvalid())
8922 return ExprError();
8923
8924 // Always rebuild; we don't know if this needs to be injected into a new
8925 // context or if the promise type has changed.
8926 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8927}
8928
8929// Objective-C Statements.
8930
8931template<typename Derived>
8932StmtResult
8933TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8934 // Transform the body of the @try.
8935 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8936 if (TryBody.isInvalid())
8937 return StmtError();
8938
8939 // Transform the @catch statements (if present).
8940 bool AnyCatchChanged = false;
8941 SmallVector<Stmt*, 8> CatchStmts;
8942 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8943 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8944 if (Catch.isInvalid())
8945 return StmtError();
8946 if (Catch.get() != S->getCatchStmt(I))
8947 AnyCatchChanged = true;
8948 CatchStmts.push_back(Elt: Catch.get());
8949 }
8950
8951 // Transform the @finally statement (if present).
8952 StmtResult Finally;
8953 if (S->getFinallyStmt()) {
8954 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8955 if (Finally.isInvalid())
8956 return StmtError();
8957 }
8958
8959 // If nothing changed, just retain this statement.
8960 if (!getDerived().AlwaysRebuild() &&
8961 TryBody.get() == S->getTryBody() &&
8962 !AnyCatchChanged &&
8963 Finally.get() == S->getFinallyStmt())
8964 return S;
8965
8966 // Build a new statement.
8967 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8968 CatchStmts, Finally.get());
8969}
8970
8971template<typename Derived>
8972StmtResult
8973TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8974 // Transform the @catch parameter, if there is one.
8975 VarDecl *Var = nullptr;
8976 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8977 TypeSourceInfo *TSInfo = nullptr;
8978 if (FromVar->getTypeSourceInfo()) {
8979 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8980 if (!TSInfo)
8981 return StmtError();
8982 }
8983
8984 QualType T;
8985 if (TSInfo)
8986 T = TSInfo->getType();
8987 else {
8988 T = getDerived().TransformType(FromVar->getType());
8989 if (T.isNull())
8990 return StmtError();
8991 }
8992
8993 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8994 if (!Var)
8995 return StmtError();
8996 }
8997
8998 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8999 if (Body.isInvalid())
9000 return StmtError();
9001
9002 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9003 S->getRParenLoc(),
9004 Var, Body.get());
9005}
9006
9007template<typename Derived>
9008StmtResult
9009TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9010 // Transform the body.
9011 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9012 if (Body.isInvalid())
9013 return StmtError();
9014
9015 // If nothing changed, just retain this statement.
9016 if (!getDerived().AlwaysRebuild() &&
9017 Body.get() == S->getFinallyBody())
9018 return S;
9019
9020 // Build a new statement.
9021 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9022 Body.get());
9023}
9024
9025template<typename Derived>
9026StmtResult
9027TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9028 ExprResult Operand;
9029 if (S->getThrowExpr()) {
9030 Operand = getDerived().TransformExpr(S->getThrowExpr());
9031 if (Operand.isInvalid())
9032 return StmtError();
9033 }
9034
9035 if (!getDerived().AlwaysRebuild() &&
9036 Operand.get() == S->getThrowExpr())
9037 return S;
9038
9039 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9040}
9041
9042template<typename Derived>
9043StmtResult
9044TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9045 ObjCAtSynchronizedStmt *S) {
9046 // Transform the object we are locking.
9047 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9048 if (Object.isInvalid())
9049 return StmtError();
9050 Object =
9051 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9052 Object.get());
9053 if (Object.isInvalid())
9054 return StmtError();
9055
9056 // Transform the body.
9057 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9058 if (Body.isInvalid())
9059 return StmtError();
9060
9061 // If nothing change, just retain the current statement.
9062 if (!getDerived().AlwaysRebuild() &&
9063 Object.get() == S->getSynchExpr() &&
9064 Body.get() == S->getSynchBody())
9065 return S;
9066
9067 // Build a new statement.
9068 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9069 Object.get(), Body.get());
9070}
9071
9072template<typename Derived>
9073StmtResult
9074TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9075 ObjCAutoreleasePoolStmt *S) {
9076 // Transform the body.
9077 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9078 if (Body.isInvalid())
9079 return StmtError();
9080
9081 // If nothing changed, just retain this statement.
9082 if (!getDerived().AlwaysRebuild() &&
9083 Body.get() == S->getSubStmt())
9084 return S;
9085
9086 // Build a new statement.
9087 return getDerived().RebuildObjCAutoreleasePoolStmt(
9088 S->getAtLoc(), Body.get());
9089}
9090
9091template<typename Derived>
9092StmtResult
9093TreeTransform<Derived>::TransformObjCForCollectionStmt(
9094 ObjCForCollectionStmt *S) {
9095 // Transform the element statement.
9096 StmtResult Element = getDerived().TransformStmt(
9097 S->getElement(), StmtDiscardKind::NotDiscarded);
9098 if (Element.isInvalid())
9099 return StmtError();
9100
9101 // Transform the collection expression.
9102 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9103 if (Collection.isInvalid())
9104 return StmtError();
9105
9106 // Transform the body.
9107 StmtResult Body = getDerived().TransformStmt(S->getBody());
9108 if (Body.isInvalid())
9109 return StmtError();
9110
9111 // If nothing changed, just retain this statement.
9112 if (!getDerived().AlwaysRebuild() &&
9113 Element.get() == S->getElement() &&
9114 Collection.get() == S->getCollection() &&
9115 Body.get() == S->getBody())
9116 return S;
9117
9118 // Build a new statement.
9119 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9120 Element.get(),
9121 Collection.get(),
9122 S->getRParenLoc(),
9123 Body.get());
9124}
9125
9126template <typename Derived>
9127StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9128 // Transform the exception declaration, if any.
9129 VarDecl *Var = nullptr;
9130 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9131 TypeSourceInfo *T =
9132 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9133 if (!T)
9134 return StmtError();
9135
9136 Var = getDerived().RebuildExceptionDecl(
9137 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9138 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9139 if (!Var || Var->isInvalidDecl())
9140 return StmtError();
9141 }
9142
9143 // Transform the actual exception handler.
9144 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9145 if (Handler.isInvalid())
9146 return StmtError();
9147
9148 if (!getDerived().AlwaysRebuild() && !Var &&
9149 Handler.get() == S->getHandlerBlock())
9150 return S;
9151
9152 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9153}
9154
9155template <typename Derived>
9156StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9157 // Transform the try block itself.
9158 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9159 if (TryBlock.isInvalid())
9160 return StmtError();
9161
9162 // Transform the handlers.
9163 bool HandlerChanged = false;
9164 SmallVector<Stmt *, 8> Handlers;
9165 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9166 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9167 if (Handler.isInvalid())
9168 return StmtError();
9169
9170 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9171 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9172 }
9173
9174 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9175
9176 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9177 !HandlerChanged)
9178 return S;
9179
9180 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9181 Handlers);
9182}
9183
9184template<typename Derived>
9185StmtResult
9186TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9187 EnterExpressionEvaluationContext ForRangeInitContext(
9188 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9189 /*LambdaContextDecl=*/nullptr,
9190 Sema::ExpressionEvaluationContextRecord::EK_Other,
9191 getSema().getLangOpts().CPlusPlus23);
9192
9193 // P2718R0 - Lifetime extension in range-based for loops.
9194 if (getSema().getLangOpts().CPlusPlus23) {
9195 auto &LastRecord = getSema().currentEvaluationContext();
9196 LastRecord.InLifetimeExtendingContext = true;
9197 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9198 }
9199 StmtResult Init =
9200 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9201 if (Init.isInvalid())
9202 return StmtError();
9203
9204 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9205 if (Range.isInvalid())
9206 return StmtError();
9207
9208 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9209 assert(getSema().getLangOpts().CPlusPlus23 ||
9210 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9211 auto ForRangeLifetimeExtendTemps =
9212 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9213
9214 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9215 if (Begin.isInvalid())
9216 return StmtError();
9217 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9218 if (End.isInvalid())
9219 return StmtError();
9220
9221 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9222 if (Cond.isInvalid())
9223 return StmtError();
9224 if (Cond.get())
9225 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9226 if (Cond.isInvalid())
9227 return StmtError();
9228 if (Cond.get())
9229 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9230
9231 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9232 if (Inc.isInvalid())
9233 return StmtError();
9234 if (Inc.get())
9235 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9236
9237 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9238 if (LoopVar.isInvalid())
9239 return StmtError();
9240
9241 StmtResult NewStmt = S;
9242 if (getDerived().AlwaysRebuild() ||
9243 Init.get() != S->getInit() ||
9244 Range.get() != S->getRangeStmt() ||
9245 Begin.get() != S->getBeginStmt() ||
9246 End.get() != S->getEndStmt() ||
9247 Cond.get() != S->getCond() ||
9248 Inc.get() != S->getInc() ||
9249 LoopVar.get() != S->getLoopVarStmt()) {
9250 NewStmt = getDerived().RebuildCXXForRangeStmt(
9251 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9252 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9253 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9254 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9255 // Might not have attached any initializer to the loop variable.
9256 getSema().ActOnInitializerError(
9257 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9258 return StmtError();
9259 }
9260 }
9261
9262 // OpenACC Restricts a while-loop inside of certain construct/clause
9263 // combinations, so diagnose that here in OpenACC mode.
9264 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9265 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9266
9267 StmtResult Body = getDerived().TransformStmt(S->getBody());
9268 if (Body.isInvalid())
9269 return StmtError();
9270
9271 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9272
9273 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9274 // it now so we have a new statement to attach the body to.
9275 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9276 NewStmt = getDerived().RebuildCXXForRangeStmt(
9277 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9278 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9279 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9280 if (NewStmt.isInvalid())
9281 return StmtError();
9282 }
9283
9284 if (NewStmt.get() == S)
9285 return S;
9286
9287 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9288}
9289
9290template<typename Derived>
9291StmtResult
9292TreeTransform<Derived>::TransformMSDependentExistsStmt(
9293 MSDependentExistsStmt *S) {
9294 // Transform the nested-name-specifier, if any.
9295 NestedNameSpecifierLoc QualifierLoc;
9296 if (S->getQualifierLoc()) {
9297 QualifierLoc
9298 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9299 if (!QualifierLoc)
9300 return StmtError();
9301 }
9302
9303 // Transform the declaration name.
9304 DeclarationNameInfo NameInfo = S->getNameInfo();
9305 if (NameInfo.getName()) {
9306 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9307 if (!NameInfo.getName())
9308 return StmtError();
9309 }
9310
9311 // Check whether anything changed.
9312 if (!getDerived().AlwaysRebuild() &&
9313 QualifierLoc == S->getQualifierLoc() &&
9314 NameInfo.getName() == S->getNameInfo().getName())
9315 return S;
9316
9317 // Determine whether this name exists, if we can.
9318 CXXScopeSpec SS;
9319 SS.Adopt(Other: QualifierLoc);
9320 bool Dependent = false;
9321 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9322 case IfExistsResult::Exists:
9323 if (S->isIfExists())
9324 break;
9325
9326 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9327
9328 case IfExistsResult::DoesNotExist:
9329 if (S->isIfNotExists())
9330 break;
9331
9332 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9333
9334 case IfExistsResult::Dependent:
9335 Dependent = true;
9336 break;
9337
9338 case IfExistsResult::Error:
9339 return StmtError();
9340 }
9341
9342 // We need to continue with the instantiation, so do so now.
9343 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9344 if (SubStmt.isInvalid())
9345 return StmtError();
9346
9347 // If we have resolved the name, just transform to the substatement.
9348 if (!Dependent)
9349 return SubStmt;
9350
9351 // The name is still dependent, so build a dependent expression again.
9352 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9353 S->isIfExists(),
9354 QualifierLoc,
9355 NameInfo,
9356 SubStmt.get());
9357}
9358
9359template<typename Derived>
9360ExprResult
9361TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9362 NestedNameSpecifierLoc QualifierLoc;
9363 if (E->getQualifierLoc()) {
9364 QualifierLoc
9365 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9366 if (!QualifierLoc)
9367 return ExprError();
9368 }
9369
9370 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9371 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9372 if (!PD)
9373 return ExprError();
9374
9375 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9376 if (Base.isInvalid())
9377 return ExprError();
9378
9379 return new (SemaRef.getASTContext())
9380 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9381 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9382 QualifierLoc, E->getMemberLoc());
9383}
9384
9385template <typename Derived>
9386ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9387 MSPropertySubscriptExpr *E) {
9388 auto BaseRes = getDerived().TransformExpr(E->getBase());
9389 if (BaseRes.isInvalid())
9390 return ExprError();
9391 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9392 if (IdxRes.isInvalid())
9393 return ExprError();
9394
9395 if (!getDerived().AlwaysRebuild() &&
9396 BaseRes.get() == E->getBase() &&
9397 IdxRes.get() == E->getIdx())
9398 return E;
9399
9400 return getDerived().RebuildArraySubscriptExpr(
9401 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9402}
9403
9404template <typename Derived>
9405StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9406 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9407 if (TryBlock.isInvalid())
9408 return StmtError();
9409
9410 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9411 if (Handler.isInvalid())
9412 return StmtError();
9413
9414 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9415 Handler.get() == S->getHandler())
9416 return S;
9417
9418 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9419 TryBlock.get(), Handler.get());
9420}
9421
9422template <typename Derived>
9423StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9424 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9425 if (Block.isInvalid())
9426 return StmtError();
9427
9428 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9429}
9430
9431template <typename Derived>
9432StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9433 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9434 if (FilterExpr.isInvalid())
9435 return StmtError();
9436
9437 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9438 if (Block.isInvalid())
9439 return StmtError();
9440
9441 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9442 Block.get());
9443}
9444
9445template <typename Derived>
9446StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9447 if (isa<SEHFinallyStmt>(Val: Handler))
9448 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9449 else
9450 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9451}
9452
9453template<typename Derived>
9454StmtResult
9455TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9456 return S;
9457}
9458
9459//===----------------------------------------------------------------------===//
9460// OpenMP directive transformation
9461//===----------------------------------------------------------------------===//
9462
9463template <typename Derived>
9464StmtResult
9465TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9466 // OMPCanonicalLoops are eliminated during transformation, since they will be
9467 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9468 // after transformation.
9469 return getDerived().TransformStmt(L->getLoopStmt());
9470}
9471
9472template <typename Derived>
9473StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9474 OMPExecutableDirective *D) {
9475
9476 // Transform the clauses
9477 llvm::SmallVector<OMPClause *, 16> TClauses;
9478 ArrayRef<OMPClause *> Clauses = D->clauses();
9479 TClauses.reserve(N: Clauses.size());
9480 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9481 I != E; ++I) {
9482 if (*I) {
9483 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9484 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9485 getDerived().getSema().OpenMP().EndOpenMPClause();
9486 if (Clause)
9487 TClauses.push_back(Elt: Clause);
9488 } else {
9489 TClauses.push_back(Elt: nullptr);
9490 }
9491 }
9492 StmtResult AssociatedStmt;
9493 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9494 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9495 D->getDirectiveKind(),
9496 /*CurScope=*/nullptr);
9497 StmtResult Body;
9498 {
9499 Sema::CompoundScopeRAII CompoundScope(getSema());
9500 Stmt *CS;
9501 if (D->getDirectiveKind() == OMPD_atomic ||
9502 D->getDirectiveKind() == OMPD_critical ||
9503 D->getDirectiveKind() == OMPD_section ||
9504 D->getDirectiveKind() == OMPD_master)
9505 CS = D->getAssociatedStmt();
9506 else
9507 CS = D->getRawStmt();
9508 Body = getDerived().TransformStmt(CS);
9509 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9510 getSema().getLangOpts().OpenMPIRBuilder)
9511 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9512 }
9513 AssociatedStmt =
9514 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9515 if (AssociatedStmt.isInvalid()) {
9516 return StmtError();
9517 }
9518 }
9519 if (TClauses.size() != Clauses.size()) {
9520 return StmtError();
9521 }
9522
9523 // Transform directive name for 'omp critical' directive.
9524 DeclarationNameInfo DirName;
9525 if (D->getDirectiveKind() == OMPD_critical) {
9526 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9527 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9528 }
9529 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9530 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9531 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9532 } else if (D->getDirectiveKind() == OMPD_cancel) {
9533 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9534 }
9535
9536 return getDerived().RebuildOMPExecutableDirective(
9537 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9538 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9539}
9540
9541/// This is mostly the same as above, but allows 'informational' class
9542/// directives when rebuilding the stmt. It still takes an
9543/// OMPExecutableDirective-type argument because we're reusing that as the
9544/// superclass for the 'assume' directive at present, instead of defining a
9545/// mostly-identical OMPInformationalDirective parent class.
9546template <typename Derived>
9547StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9548 OMPExecutableDirective *D) {
9549
9550 // Transform the clauses
9551 llvm::SmallVector<OMPClause *, 16> TClauses;
9552 ArrayRef<OMPClause *> Clauses = D->clauses();
9553 TClauses.reserve(N: Clauses.size());
9554 for (OMPClause *C : Clauses) {
9555 if (C) {
9556 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9557 OMPClause *Clause = getDerived().TransformOMPClause(C);
9558 getDerived().getSema().OpenMP().EndOpenMPClause();
9559 if (Clause)
9560 TClauses.push_back(Elt: Clause);
9561 } else {
9562 TClauses.push_back(Elt: nullptr);
9563 }
9564 }
9565 StmtResult AssociatedStmt;
9566 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9567 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9568 D->getDirectiveKind(),
9569 /*CurScope=*/nullptr);
9570 StmtResult Body;
9571 {
9572 Sema::CompoundScopeRAII CompoundScope(getSema());
9573 assert(D->getDirectiveKind() == OMPD_assume &&
9574 "Unexpected informational directive");
9575 Stmt *CS = D->getAssociatedStmt();
9576 Body = getDerived().TransformStmt(CS);
9577 }
9578 AssociatedStmt =
9579 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9580 if (AssociatedStmt.isInvalid())
9581 return StmtError();
9582 }
9583 if (TClauses.size() != Clauses.size())
9584 return StmtError();
9585
9586 DeclarationNameInfo DirName;
9587
9588 return getDerived().RebuildOMPInformationalDirective(
9589 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9590 D->getBeginLoc(), D->getEndLoc());
9591}
9592
9593template <typename Derived>
9594StmtResult
9595TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9596 // TODO: Fix This
9597 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9598 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9599 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9600 return StmtError();
9601}
9602
9603template <typename Derived>
9604StmtResult
9605TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9606 DeclarationNameInfo DirName;
9607 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9608 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9609 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9610 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9611 return Res;
9612}
9613
9614template <typename Derived>
9615StmtResult
9616TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9617 DeclarationNameInfo DirName;
9618 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9619 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9620 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9621 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9622 return Res;
9623}
9624
9625template <typename Derived>
9626StmtResult
9627TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9628 DeclarationNameInfo DirName;
9629 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9630 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9631 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9632 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9633 return Res;
9634}
9635
9636template <typename Derived>
9637StmtResult
9638TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9639 DeclarationNameInfo DirName;
9640 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9641 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9642 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9643 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9644 return Res;
9645}
9646
9647template <typename Derived>
9648StmtResult
9649TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9650 DeclarationNameInfo DirName;
9651 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9652 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9653 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9654 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9655 return Res;
9656}
9657
9658template <typename Derived>
9659StmtResult
9660TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9661 DeclarationNameInfo DirName;
9662 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9663 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9664 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9665 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9666 return Res;
9667}
9668
9669template <typename Derived>
9670StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9671 OMPInterchangeDirective *D) {
9672 DeclarationNameInfo DirName;
9673 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9674 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9675 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9676 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9677 return Res;
9678}
9679
9680template <typename Derived>
9681StmtResult
9682TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9683 DeclarationNameInfo DirName;
9684 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9685 OMPD_for, DirName, nullptr, D->getBeginLoc());
9686 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9687 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9688 return Res;
9689}
9690
9691template <typename Derived>
9692StmtResult
9693TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9694 DeclarationNameInfo DirName;
9695 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9696 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9697 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9698 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9699 return Res;
9700}
9701
9702template <typename Derived>
9703StmtResult
9704TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9705 DeclarationNameInfo DirName;
9706 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9707 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9708 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9709 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9710 return Res;
9711}
9712
9713template <typename Derived>
9714StmtResult
9715TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9716 DeclarationNameInfo DirName;
9717 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9718 OMPD_section, DirName, nullptr, D->getBeginLoc());
9719 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9720 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9721 return Res;
9722}
9723
9724template <typename Derived>
9725StmtResult
9726TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9727 DeclarationNameInfo DirName;
9728 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9729 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9730 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9731 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9732 return Res;
9733}
9734
9735template <typename Derived>
9736StmtResult
9737TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9738 DeclarationNameInfo DirName;
9739 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9740 OMPD_single, DirName, nullptr, D->getBeginLoc());
9741 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9742 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9743 return Res;
9744}
9745
9746template <typename Derived>
9747StmtResult
9748TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9749 DeclarationNameInfo DirName;
9750 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9751 OMPD_master, DirName, nullptr, D->getBeginLoc());
9752 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9753 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9754 return Res;
9755}
9756
9757template <typename Derived>
9758StmtResult
9759TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9760 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9761 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9762 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9763 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9764 return Res;
9765}
9766
9767template <typename Derived>
9768StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9769 OMPParallelForDirective *D) {
9770 DeclarationNameInfo DirName;
9771 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9772 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9773 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9774 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9775 return Res;
9776}
9777
9778template <typename Derived>
9779StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9780 OMPParallelForSimdDirective *D) {
9781 DeclarationNameInfo DirName;
9782 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9783 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9784 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9785 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9786 return Res;
9787}
9788
9789template <typename Derived>
9790StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9791 OMPParallelMasterDirective *D) {
9792 DeclarationNameInfo DirName;
9793 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9794 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9795 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9796 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9797 return Res;
9798}
9799
9800template <typename Derived>
9801StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9802 OMPParallelMaskedDirective *D) {
9803 DeclarationNameInfo DirName;
9804 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9805 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9806 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9807 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9808 return Res;
9809}
9810
9811template <typename Derived>
9812StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9813 OMPParallelSectionsDirective *D) {
9814 DeclarationNameInfo DirName;
9815 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9816 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9817 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9818 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9819 return Res;
9820}
9821
9822template <typename Derived>
9823StmtResult
9824TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9825 DeclarationNameInfo DirName;
9826 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9827 OMPD_task, DirName, nullptr, D->getBeginLoc());
9828 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9829 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9830 return Res;
9831}
9832
9833template <typename Derived>
9834StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9835 OMPTaskyieldDirective *D) {
9836 DeclarationNameInfo DirName;
9837 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9838 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9839 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9840 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9841 return Res;
9842}
9843
9844template <typename Derived>
9845StmtResult
9846TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9847 DeclarationNameInfo DirName;
9848 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9849 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9850 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9851 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9852 return Res;
9853}
9854
9855template <typename Derived>
9856StmtResult
9857TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9858 DeclarationNameInfo DirName;
9859 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9860 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9861 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9862 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9863 return Res;
9864}
9865
9866template <typename Derived>
9867StmtResult
9868TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9869 DeclarationNameInfo DirName;
9870 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9871 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9872 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9873 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9874 return Res;
9875}
9876
9877template <typename Derived>
9878StmtResult
9879TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9880 DeclarationNameInfo DirName;
9881 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9882 OMPD_error, DirName, nullptr, D->getBeginLoc());
9883 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9884 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9885 return Res;
9886}
9887
9888template <typename Derived>
9889StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9890 OMPTaskgroupDirective *D) {
9891 DeclarationNameInfo DirName;
9892 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9893 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9894 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9895 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9896 return Res;
9897}
9898
9899template <typename Derived>
9900StmtResult
9901TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9902 DeclarationNameInfo DirName;
9903 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9904 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9905 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9906 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9907 return Res;
9908}
9909
9910template <typename Derived>
9911StmtResult
9912TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9913 DeclarationNameInfo DirName;
9914 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9915 OMPD_depobj, 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>::TransformOMPScanDirective(OMPScanDirective *D) {
9924 DeclarationNameInfo DirName;
9925 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9926 OMPD_scan, 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>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9935 DeclarationNameInfo DirName;
9936 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9937 OMPD_ordered, 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>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9946 DeclarationNameInfo DirName;
9947 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9948 OMPD_atomic, 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>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9957 DeclarationNameInfo DirName;
9958 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9959 OMPD_target, 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 TreeTransform<Derived>::TransformOMPTargetDataDirective(
9967 OMPTargetDataDirective *D) {
9968 DeclarationNameInfo DirName;
9969 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9970 OMPD_target_data, 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>::TransformOMPTargetEnterDataDirective(
9978 OMPTargetEnterDataDirective *D) {
9979 DeclarationNameInfo DirName;
9980 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9981 OMPD_target_enter_data, 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 TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9989 OMPTargetExitDataDirective *D) {
9990 DeclarationNameInfo DirName;
9991 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9992 OMPD_target_exit_data, 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 TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10000 OMPTargetParallelDirective *D) {
10001 DeclarationNameInfo DirName;
10002 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10003 OMPD_target_parallel, 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 TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10011 OMPTargetParallelForDirective *D) {
10012 DeclarationNameInfo DirName;
10013 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10014 OMPD_target_parallel_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 TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10022 OMPTargetUpdateDirective *D) {
10023 DeclarationNameInfo DirName;
10024 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10025 OMPD_target_update, 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>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10034 DeclarationNameInfo DirName;
10035 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10036 OMPD_teams, 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 TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10044 OMPCancellationPointDirective *D) {
10045 DeclarationNameInfo DirName;
10046 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10047 OMPD_cancellation_point, 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>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10056 DeclarationNameInfo DirName;
10057 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10058 OMPD_cancel, 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>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10067 DeclarationNameInfo DirName;
10068 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10069 OMPD_taskloop, 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 TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10077 OMPTaskLoopSimdDirective *D) {
10078 DeclarationNameInfo DirName;
10079 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10080 OMPD_taskloop_simd, 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 TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10088 OMPMasterTaskLoopDirective *D) {
10089 DeclarationNameInfo DirName;
10090 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10091 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10092 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10093 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10094 return Res;
10095}
10096
10097template <typename Derived>
10098StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10099 OMPMaskedTaskLoopDirective *D) {
10100 DeclarationNameInfo DirName;
10101 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10102 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10103 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10104 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10105 return Res;
10106}
10107
10108template <typename Derived>
10109StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10110 OMPMasterTaskLoopSimdDirective *D) {
10111 DeclarationNameInfo DirName;
10112 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10113 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10114 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10115 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10116 return Res;
10117}
10118
10119template <typename Derived>
10120StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10121 OMPMaskedTaskLoopSimdDirective *D) {
10122 DeclarationNameInfo DirName;
10123 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10124 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10125 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10126 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10127 return Res;
10128}
10129
10130template <typename Derived>
10131StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10132 OMPParallelMasterTaskLoopDirective *D) {
10133 DeclarationNameInfo DirName;
10134 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10135 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10136 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10137 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10138 return Res;
10139}
10140
10141template <typename Derived>
10142StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10143 OMPParallelMaskedTaskLoopDirective *D) {
10144 DeclarationNameInfo DirName;
10145 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10146 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10147 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10148 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10149 return Res;
10150}
10151
10152template <typename Derived>
10153StmtResult
10154TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10155 OMPParallelMasterTaskLoopSimdDirective *D) {
10156 DeclarationNameInfo DirName;
10157 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10158 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10159 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10160 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10161 return Res;
10162}
10163
10164template <typename Derived>
10165StmtResult
10166TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10167 OMPParallelMaskedTaskLoopSimdDirective *D) {
10168 DeclarationNameInfo DirName;
10169 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10170 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10171 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10172 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10173 return Res;
10174}
10175
10176template <typename Derived>
10177StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10178 OMPDistributeDirective *D) {
10179 DeclarationNameInfo DirName;
10180 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10181 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10182 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10183 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10184 return Res;
10185}
10186
10187template <typename Derived>
10188StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10189 OMPDistributeParallelForDirective *D) {
10190 DeclarationNameInfo DirName;
10191 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10192 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10193 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10194 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10195 return Res;
10196}
10197
10198template <typename Derived>
10199StmtResult
10200TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10201 OMPDistributeParallelForSimdDirective *D) {
10202 DeclarationNameInfo DirName;
10203 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10204 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10205 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10206 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10207 return Res;
10208}
10209
10210template <typename Derived>
10211StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10212 OMPDistributeSimdDirective *D) {
10213 DeclarationNameInfo DirName;
10214 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10215 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10216 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10217 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10218 return Res;
10219}
10220
10221template <typename Derived>
10222StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10223 OMPTargetParallelForSimdDirective *D) {
10224 DeclarationNameInfo DirName;
10225 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10226 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10227 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10228 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10229 return Res;
10230}
10231
10232template <typename Derived>
10233StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10234 OMPTargetSimdDirective *D) {
10235 DeclarationNameInfo DirName;
10236 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10237 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10238 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10239 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10240 return Res;
10241}
10242
10243template <typename Derived>
10244StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10245 OMPTeamsDistributeDirective *D) {
10246 DeclarationNameInfo DirName;
10247 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10248 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10249 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10250 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10251 return Res;
10252}
10253
10254template <typename Derived>
10255StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10256 OMPTeamsDistributeSimdDirective *D) {
10257 DeclarationNameInfo DirName;
10258 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10259 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10260 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10261 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10262 return Res;
10263}
10264
10265template <typename Derived>
10266StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10267 OMPTeamsDistributeParallelForSimdDirective *D) {
10268 DeclarationNameInfo DirName;
10269 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10270 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10271 D->getBeginLoc());
10272 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10273 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10274 return Res;
10275}
10276
10277template <typename Derived>
10278StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10279 OMPTeamsDistributeParallelForDirective *D) {
10280 DeclarationNameInfo DirName;
10281 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10282 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10283 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10284 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10285 return Res;
10286}
10287
10288template <typename Derived>
10289StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10290 OMPTargetTeamsDirective *D) {
10291 DeclarationNameInfo DirName;
10292 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10293 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10294 auto Res = getDerived().TransformOMPExecutableDirective(D);
10295 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10296 return Res;
10297}
10298
10299template <typename Derived>
10300StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10301 OMPTargetTeamsDistributeDirective *D) {
10302 DeclarationNameInfo DirName;
10303 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10304 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10305 auto Res = getDerived().TransformOMPExecutableDirective(D);
10306 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10307 return Res;
10308}
10309
10310template <typename Derived>
10311StmtResult
10312TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10313 OMPTargetTeamsDistributeParallelForDirective *D) {
10314 DeclarationNameInfo DirName;
10315 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10316 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10317 D->getBeginLoc());
10318 auto Res = getDerived().TransformOMPExecutableDirective(D);
10319 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10320 return Res;
10321}
10322
10323template <typename Derived>
10324StmtResult TreeTransform<Derived>::
10325 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10326 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10327 DeclarationNameInfo DirName;
10328 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10329 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10330 D->getBeginLoc());
10331 auto Res = getDerived().TransformOMPExecutableDirective(D);
10332 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10333 return Res;
10334}
10335
10336template <typename Derived>
10337StmtResult
10338TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10339 OMPTargetTeamsDistributeSimdDirective *D) {
10340 DeclarationNameInfo DirName;
10341 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10342 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10343 auto Res = getDerived().TransformOMPExecutableDirective(D);
10344 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10345 return Res;
10346}
10347
10348template <typename Derived>
10349StmtResult
10350TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10351 DeclarationNameInfo DirName;
10352 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10353 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10354 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10355 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10356 return Res;
10357}
10358
10359template <typename Derived>
10360StmtResult
10361TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10362 DeclarationNameInfo DirName;
10363 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10364 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10365 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10366 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10367 return Res;
10368}
10369
10370template <typename Derived>
10371StmtResult
10372TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10373 DeclarationNameInfo DirName;
10374 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10375 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10376 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10377 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10378 return Res;
10379}
10380
10381template <typename Derived>
10382StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10383 OMPGenericLoopDirective *D) {
10384 DeclarationNameInfo DirName;
10385 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10386 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10387 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10388 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10389 return Res;
10390}
10391
10392template <typename Derived>
10393StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10394 OMPTeamsGenericLoopDirective *D) {
10395 DeclarationNameInfo DirName;
10396 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10397 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10398 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10399 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10400 return Res;
10401}
10402
10403template <typename Derived>
10404StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10405 OMPTargetTeamsGenericLoopDirective *D) {
10406 DeclarationNameInfo DirName;
10407 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10408 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10409 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10410 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10411 return Res;
10412}
10413
10414template <typename Derived>
10415StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10416 OMPParallelGenericLoopDirective *D) {
10417 DeclarationNameInfo DirName;
10418 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10419 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10420 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10421 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10422 return Res;
10423}
10424
10425template <typename Derived>
10426StmtResult
10427TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10428 OMPTargetParallelGenericLoopDirective *D) {
10429 DeclarationNameInfo DirName;
10430 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10431 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10432 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10433 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10434 return Res;
10435}
10436
10437//===----------------------------------------------------------------------===//
10438// OpenMP clause transformation
10439//===----------------------------------------------------------------------===//
10440template <typename Derived>
10441OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10442 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10443 if (Cond.isInvalid())
10444 return nullptr;
10445 return getDerived().RebuildOMPIfClause(
10446 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10447 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10448}
10449
10450template <typename Derived>
10451OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10452 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10453 if (Cond.isInvalid())
10454 return nullptr;
10455 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10456 C->getLParenLoc(), C->getEndLoc());
10457}
10458
10459template <typename Derived>
10460OMPClause *
10461TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10462 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10463 if (NumThreads.isInvalid())
10464 return nullptr;
10465 return getDerived().RebuildOMPNumThreadsClause(
10466 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10467 C->getModifierLoc(), C->getEndLoc());
10468}
10469
10470template <typename Derived>
10471OMPClause *
10472TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10473 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10474 if (E.isInvalid())
10475 return nullptr;
10476 return getDerived().RebuildOMPSafelenClause(
10477 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10478}
10479
10480template <typename Derived>
10481OMPClause *
10482TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10483 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10484 if (E.isInvalid())
10485 return nullptr;
10486 return getDerived().RebuildOMPAllocatorClause(
10487 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10488}
10489
10490template <typename Derived>
10491OMPClause *
10492TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10493 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10494 if (E.isInvalid())
10495 return nullptr;
10496 return getDerived().RebuildOMPSimdlenClause(
10497 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10498}
10499
10500template <typename Derived>
10501OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10502 SmallVector<Expr *, 4> TransformedSizes;
10503 TransformedSizes.reserve(N: C->getNumSizes());
10504 bool Changed = false;
10505 for (Expr *E : C->getSizesRefs()) {
10506 if (!E) {
10507 TransformedSizes.push_back(Elt: nullptr);
10508 continue;
10509 }
10510
10511 ExprResult T = getDerived().TransformExpr(E);
10512 if (T.isInvalid())
10513 return nullptr;
10514 if (E != T.get())
10515 Changed = true;
10516 TransformedSizes.push_back(Elt: T.get());
10517 }
10518
10519 if (!Changed && !getDerived().AlwaysRebuild())
10520 return C;
10521 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10522 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10523}
10524
10525template <typename Derived>
10526OMPClause *
10527TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10528 SmallVector<Expr *> TransformedArgs;
10529 TransformedArgs.reserve(N: C->getNumLoops());
10530 bool Changed = false;
10531 for (Expr *E : C->getArgsRefs()) {
10532 if (!E) {
10533 TransformedArgs.push_back(Elt: nullptr);
10534 continue;
10535 }
10536
10537 ExprResult T = getDerived().TransformExpr(E);
10538 if (T.isInvalid())
10539 return nullptr;
10540 if (E != T.get())
10541 Changed = true;
10542 TransformedArgs.push_back(Elt: T.get());
10543 }
10544
10545 if (!Changed && !getDerived().AlwaysRebuild())
10546 return C;
10547 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10548 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10549}
10550
10551template <typename Derived>
10552OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10553 if (!getDerived().AlwaysRebuild())
10554 return C;
10555 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10556}
10557
10558template <typename Derived>
10559OMPClause *
10560TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10561 ExprResult T = getDerived().TransformExpr(C->getFactor());
10562 if (T.isInvalid())
10563 return nullptr;
10564 Expr *Factor = T.get();
10565 bool Changed = Factor != C->getFactor();
10566
10567 if (!Changed && !getDerived().AlwaysRebuild())
10568 return C;
10569 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10570 EndLoc: C->getEndLoc());
10571}
10572
10573template <typename Derived>
10574OMPClause *
10575TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10576 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10577 if (E.isInvalid())
10578 return nullptr;
10579 return getDerived().RebuildOMPCollapseClause(
10580 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10581}
10582
10583template <typename Derived>
10584OMPClause *
10585TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10586 return getDerived().RebuildOMPDefaultClause(
10587 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10588 C->getLParenLoc(), C->getEndLoc());
10589}
10590
10591template <typename Derived>
10592OMPClause *
10593TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10594 return getDerived().RebuildOMPProcBindClause(
10595 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10596 C->getLParenLoc(), C->getEndLoc());
10597}
10598
10599template <typename Derived>
10600OMPClause *
10601TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10602 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10603 if (E.isInvalid())
10604 return nullptr;
10605 return getDerived().RebuildOMPScheduleClause(
10606 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10607 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10608 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10609 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10610}
10611
10612template <typename Derived>
10613OMPClause *
10614TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10615 ExprResult E;
10616 if (auto *Num = C->getNumForLoops()) {
10617 E = getDerived().TransformExpr(Num);
10618 if (E.isInvalid())
10619 return nullptr;
10620 }
10621 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10622 C->getLParenLoc(), E.get());
10623}
10624
10625template <typename Derived>
10626OMPClause *
10627TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10628 ExprResult E;
10629 if (Expr *Evt = C->getEventHandler()) {
10630 E = getDerived().TransformExpr(Evt);
10631 if (E.isInvalid())
10632 return nullptr;
10633 }
10634 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10635 C->getLParenLoc(), C->getEndLoc());
10636}
10637
10638template <typename Derived>
10639OMPClause *
10640TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10641 // No need to rebuild this clause, no template-dependent parameters.
10642 return C;
10643}
10644
10645template <typename Derived>
10646OMPClause *
10647TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10648 // No need to rebuild this clause, no template-dependent parameters.
10649 return C;
10650}
10651
10652template <typename Derived>
10653OMPClause *
10654TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10655 // No need to rebuild this clause, no template-dependent parameters.
10656 return C;
10657}
10658
10659template <typename Derived>
10660OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10661 // No need to rebuild this clause, no template-dependent parameters.
10662 return C;
10663}
10664
10665template <typename Derived>
10666OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10667 // No need to rebuild this clause, no template-dependent parameters.
10668 return C;
10669}
10670
10671template <typename Derived>
10672OMPClause *
10673TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10674 // No need to rebuild this clause, no template-dependent parameters.
10675 return C;
10676}
10677
10678template <typename Derived>
10679OMPClause *
10680TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10681 // No need to rebuild this clause, no template-dependent parameters.
10682 return C;
10683}
10684
10685template <typename Derived>
10686OMPClause *
10687TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10688 // No need to rebuild this clause, no template-dependent parameters.
10689 return C;
10690}
10691
10692template <typename Derived>
10693OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10694 // No need to rebuild this clause, no template-dependent parameters.
10695 return C;
10696}
10697
10698template <typename Derived>
10699OMPClause *
10700TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10701 return C;
10702}
10703
10704template <typename Derived>
10705OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10706 ExprResult E = getDerived().TransformExpr(C->getExpr());
10707 if (E.isInvalid())
10708 return nullptr;
10709 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10710 C->getLParenLoc(), C->getEndLoc());
10711}
10712
10713template <typename Derived>
10714OMPClause *
10715TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10716 return C;
10717}
10718
10719template <typename Derived>
10720OMPClause *
10721TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10722 return C;
10723}
10724template <typename Derived>
10725OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10726 OMPNoOpenMPRoutinesClause *C) {
10727 return C;
10728}
10729template <typename Derived>
10730OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10731 OMPNoOpenMPConstructsClause *C) {
10732 return C;
10733}
10734template <typename Derived>
10735OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10736 OMPNoParallelismClause *C) {
10737 return C;
10738}
10739
10740template <typename Derived>
10741OMPClause *
10742TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10743 // No need to rebuild this clause, no template-dependent parameters.
10744 return C;
10745}
10746
10747template <typename Derived>
10748OMPClause *
10749TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10750 // No need to rebuild this clause, no template-dependent parameters.
10751 return C;
10752}
10753
10754template <typename Derived>
10755OMPClause *
10756TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10757 // No need to rebuild this clause, no template-dependent parameters.
10758 return C;
10759}
10760
10761template <typename Derived>
10762OMPClause *
10763TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10764 // No need to rebuild this clause, no template-dependent parameters.
10765 return C;
10766}
10767
10768template <typename Derived>
10769OMPClause *
10770TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10771 // No need to rebuild this clause, no template-dependent parameters.
10772 return C;
10773}
10774
10775template <typename Derived>
10776OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10777 // No need to rebuild this clause, no template-dependent parameters.
10778 return C;
10779}
10780
10781template <typename Derived>
10782OMPClause *
10783TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10784 // No need to rebuild this clause, no template-dependent parameters.
10785 return C;
10786}
10787
10788template <typename Derived>
10789OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10790 // No need to rebuild this clause, no template-dependent parameters.
10791 return C;
10792}
10793
10794template <typename Derived>
10795OMPClause *
10796TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10797 // No need to rebuild this clause, no template-dependent parameters.
10798 return C;
10799}
10800
10801template <typename Derived>
10802OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10803 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10804 if (IVR.isInvalid())
10805 return nullptr;
10806
10807 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10808 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10809 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlist())) {
10810 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10811 if (ER.isInvalid())
10812 return nullptr;
10813 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10814 }
10815 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10816 C->getBeginLoc(), C->getLParenLoc(),
10817 C->getVarLoc(), C->getEndLoc());
10818}
10819
10820template <typename Derived>
10821OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10822 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10823 if (ER.isInvalid())
10824 return nullptr;
10825 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10826 C->getLParenLoc(), C->getVarLoc(),
10827 C->getEndLoc());
10828}
10829
10830template <typename Derived>
10831OMPClause *
10832TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10833 ExprResult ER;
10834 if (Expr *IV = C->getInteropVar()) {
10835 ER = getDerived().TransformExpr(IV);
10836 if (ER.isInvalid())
10837 return nullptr;
10838 }
10839 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10840 C->getLParenLoc(), C->getVarLoc(),
10841 C->getEndLoc());
10842}
10843
10844template <typename Derived>
10845OMPClause *
10846TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10847 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10848 if (Cond.isInvalid())
10849 return nullptr;
10850 return getDerived().RebuildOMPNovariantsClause(
10851 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10852}
10853
10854template <typename Derived>
10855OMPClause *
10856TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10857 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10858 if (Cond.isInvalid())
10859 return nullptr;
10860 return getDerived().RebuildOMPNocontextClause(
10861 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10862}
10863
10864template <typename Derived>
10865OMPClause *
10866TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10867 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10868 if (ThreadID.isInvalid())
10869 return nullptr;
10870 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10871 C->getLParenLoc(), C->getEndLoc());
10872}
10873
10874template <typename Derived>
10875OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10876 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10877 if (E.isInvalid())
10878 return nullptr;
10879 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10880 C->getLParenLoc(), C->getEndLoc());
10881}
10882
10883template <typename Derived>
10884OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10885 OMPUnifiedAddressClause *C) {
10886 llvm_unreachable("unified_address clause cannot appear in dependent context");
10887}
10888
10889template <typename Derived>
10890OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10891 OMPUnifiedSharedMemoryClause *C) {
10892 llvm_unreachable(
10893 "unified_shared_memory clause cannot appear in dependent context");
10894}
10895
10896template <typename Derived>
10897OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10898 OMPReverseOffloadClause *C) {
10899 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10900}
10901
10902template <typename Derived>
10903OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10904 OMPDynamicAllocatorsClause *C) {
10905 llvm_unreachable(
10906 "dynamic_allocators clause cannot appear in dependent context");
10907}
10908
10909template <typename Derived>
10910OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10911 OMPAtomicDefaultMemOrderClause *C) {
10912 llvm_unreachable(
10913 "atomic_default_mem_order clause cannot appear in dependent context");
10914}
10915
10916template <typename Derived>
10917OMPClause *
10918TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
10919 llvm_unreachable("self_maps clause cannot appear in dependent context");
10920}
10921
10922template <typename Derived>
10923OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10924 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10925 C->getBeginLoc(), C->getLParenLoc(),
10926 C->getEndLoc());
10927}
10928
10929template <typename Derived>
10930OMPClause *
10931TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10932 return getDerived().RebuildOMPSeverityClause(
10933 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10934 C->getLParenLoc(), C->getEndLoc());
10935}
10936
10937template <typename Derived>
10938OMPClause *
10939TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10940 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10941 if (E.isInvalid())
10942 return nullptr;
10943 return getDerived().RebuildOMPMessageClause(
10944 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10945 C->getEndLoc());
10946}
10947
10948template <typename Derived>
10949OMPClause *
10950TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10951 llvm::SmallVector<Expr *, 16> Vars;
10952 Vars.reserve(N: C->varlist_size());
10953 for (auto *VE : C->varlist()) {
10954 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10955 if (EVar.isInvalid())
10956 return nullptr;
10957 Vars.push_back(Elt: EVar.get());
10958 }
10959 return getDerived().RebuildOMPPrivateClause(
10960 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10961}
10962
10963template <typename Derived>
10964OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10965 OMPFirstprivateClause *C) {
10966 llvm::SmallVector<Expr *, 16> Vars;
10967 Vars.reserve(N: C->varlist_size());
10968 for (auto *VE : C->varlist()) {
10969 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10970 if (EVar.isInvalid())
10971 return nullptr;
10972 Vars.push_back(Elt: EVar.get());
10973 }
10974 return getDerived().RebuildOMPFirstprivateClause(
10975 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10976}
10977
10978template <typename Derived>
10979OMPClause *
10980TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10981 llvm::SmallVector<Expr *, 16> Vars;
10982 Vars.reserve(N: C->varlist_size());
10983 for (auto *VE : C->varlist()) {
10984 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10985 if (EVar.isInvalid())
10986 return nullptr;
10987 Vars.push_back(Elt: EVar.get());
10988 }
10989 return getDerived().RebuildOMPLastprivateClause(
10990 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10991 C->getLParenLoc(), C->getEndLoc());
10992}
10993
10994template <typename Derived>
10995OMPClause *
10996TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10997 llvm::SmallVector<Expr *, 16> Vars;
10998 Vars.reserve(N: C->varlist_size());
10999 for (auto *VE : C->varlist()) {
11000 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11001 if (EVar.isInvalid())
11002 return nullptr;
11003 Vars.push_back(Elt: EVar.get());
11004 }
11005 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11006 C->getLParenLoc(), C->getEndLoc());
11007}
11008
11009template <typename Derived>
11010OMPClause *
11011TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11012 llvm::SmallVector<Expr *, 16> Vars;
11013 Vars.reserve(N: C->varlist_size());
11014 for (auto *VE : C->varlist()) {
11015 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11016 if (EVar.isInvalid())
11017 return nullptr;
11018 Vars.push_back(Elt: EVar.get());
11019 }
11020 CXXScopeSpec ReductionIdScopeSpec;
11021 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11022
11023 DeclarationNameInfo NameInfo = C->getNameInfo();
11024 if (NameInfo.getName()) {
11025 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11026 if (!NameInfo.getName())
11027 return nullptr;
11028 }
11029 // Build a list of all UDR decls with the same names ranged by the Scopes.
11030 // The Scope boundary is a duplication of the previous decl.
11031 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11032 for (auto *E : C->reduction_ops()) {
11033 // Transform all the decls.
11034 if (E) {
11035 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11036 UnresolvedSet<8> Decls;
11037 for (auto *D : ULE->decls()) {
11038 NamedDecl *InstD =
11039 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11040 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11041 }
11042 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11043 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11044 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11045 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11046 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11047 } else
11048 UnresolvedReductions.push_back(Elt: nullptr);
11049 }
11050 return getDerived().RebuildOMPReductionClause(
11051 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11052 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11053 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11054}
11055
11056template <typename Derived>
11057OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11058 OMPTaskReductionClause *C) {
11059 llvm::SmallVector<Expr *, 16> Vars;
11060 Vars.reserve(N: C->varlist_size());
11061 for (auto *VE : C->varlist()) {
11062 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11063 if (EVar.isInvalid())
11064 return nullptr;
11065 Vars.push_back(Elt: EVar.get());
11066 }
11067 CXXScopeSpec ReductionIdScopeSpec;
11068 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11069
11070 DeclarationNameInfo NameInfo = C->getNameInfo();
11071 if (NameInfo.getName()) {
11072 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11073 if (!NameInfo.getName())
11074 return nullptr;
11075 }
11076 // Build a list of all UDR decls with the same names ranged by the Scopes.
11077 // The Scope boundary is a duplication of the previous decl.
11078 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11079 for (auto *E : C->reduction_ops()) {
11080 // Transform all the decls.
11081 if (E) {
11082 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11083 UnresolvedSet<8> Decls;
11084 for (auto *D : ULE->decls()) {
11085 NamedDecl *InstD =
11086 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11087 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11088 }
11089 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11090 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11091 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11092 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11093 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11094 } else
11095 UnresolvedReductions.push_back(Elt: nullptr);
11096 }
11097 return getDerived().RebuildOMPTaskReductionClause(
11098 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11099 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11100}
11101
11102template <typename Derived>
11103OMPClause *
11104TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11105 llvm::SmallVector<Expr *, 16> Vars;
11106 Vars.reserve(N: C->varlist_size());
11107 for (auto *VE : C->varlist()) {
11108 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11109 if (EVar.isInvalid())
11110 return nullptr;
11111 Vars.push_back(Elt: EVar.get());
11112 }
11113 CXXScopeSpec ReductionIdScopeSpec;
11114 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11115
11116 DeclarationNameInfo NameInfo = C->getNameInfo();
11117 if (NameInfo.getName()) {
11118 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11119 if (!NameInfo.getName())
11120 return nullptr;
11121 }
11122 // Build a list of all UDR decls with the same names ranged by the Scopes.
11123 // The Scope boundary is a duplication of the previous decl.
11124 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11125 for (auto *E : C->reduction_ops()) {
11126 // Transform all the decls.
11127 if (E) {
11128 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11129 UnresolvedSet<8> Decls;
11130 for (auto *D : ULE->decls()) {
11131 NamedDecl *InstD =
11132 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11133 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11134 }
11135 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11136 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11137 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11138 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11139 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11140 } else
11141 UnresolvedReductions.push_back(Elt: nullptr);
11142 }
11143 return getDerived().RebuildOMPInReductionClause(
11144 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11145 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11146}
11147
11148template <typename Derived>
11149OMPClause *
11150TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11151 llvm::SmallVector<Expr *, 16> Vars;
11152 Vars.reserve(N: C->varlist_size());
11153 for (auto *VE : C->varlist()) {
11154 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11155 if (EVar.isInvalid())
11156 return nullptr;
11157 Vars.push_back(Elt: EVar.get());
11158 }
11159 ExprResult Step = getDerived().TransformExpr(C->getStep());
11160 if (Step.isInvalid())
11161 return nullptr;
11162 return getDerived().RebuildOMPLinearClause(
11163 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11164 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11165 C->getEndLoc());
11166}
11167
11168template <typename Derived>
11169OMPClause *
11170TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11171 llvm::SmallVector<Expr *, 16> Vars;
11172 Vars.reserve(N: C->varlist_size());
11173 for (auto *VE : C->varlist()) {
11174 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11175 if (EVar.isInvalid())
11176 return nullptr;
11177 Vars.push_back(Elt: EVar.get());
11178 }
11179 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11180 if (Alignment.isInvalid())
11181 return nullptr;
11182 return getDerived().RebuildOMPAlignedClause(
11183 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11184 C->getColonLoc(), C->getEndLoc());
11185}
11186
11187template <typename Derived>
11188OMPClause *
11189TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11190 llvm::SmallVector<Expr *, 16> Vars;
11191 Vars.reserve(N: C->varlist_size());
11192 for (auto *VE : C->varlist()) {
11193 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11194 if (EVar.isInvalid())
11195 return nullptr;
11196 Vars.push_back(Elt: EVar.get());
11197 }
11198 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11199 C->getLParenLoc(), C->getEndLoc());
11200}
11201
11202template <typename Derived>
11203OMPClause *
11204TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11205 llvm::SmallVector<Expr *, 16> Vars;
11206 Vars.reserve(N: C->varlist_size());
11207 for (auto *VE : C->varlist()) {
11208 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11209 if (EVar.isInvalid())
11210 return nullptr;
11211 Vars.push_back(Elt: EVar.get());
11212 }
11213 return getDerived().RebuildOMPCopyprivateClause(
11214 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11215}
11216
11217template <typename Derived>
11218OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11219 llvm::SmallVector<Expr *, 16> Vars;
11220 Vars.reserve(N: C->varlist_size());
11221 for (auto *VE : C->varlist()) {
11222 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11223 if (EVar.isInvalid())
11224 return nullptr;
11225 Vars.push_back(Elt: EVar.get());
11226 }
11227 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11228 C->getLParenLoc(), C->getEndLoc());
11229}
11230
11231template <typename Derived>
11232OMPClause *
11233TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11234 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11235 if (E.isInvalid())
11236 return nullptr;
11237 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11238 C->getLParenLoc(), C->getEndLoc());
11239}
11240
11241template <typename Derived>
11242OMPClause *
11243TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11244 llvm::SmallVector<Expr *, 16> Vars;
11245 Expr *DepModifier = C->getModifier();
11246 if (DepModifier) {
11247 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11248 if (DepModRes.isInvalid())
11249 return nullptr;
11250 DepModifier = DepModRes.get();
11251 }
11252 Vars.reserve(N: C->varlist_size());
11253 for (auto *VE : C->varlist()) {
11254 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11255 if (EVar.isInvalid())
11256 return nullptr;
11257 Vars.push_back(Elt: EVar.get());
11258 }
11259 return getDerived().RebuildOMPDependClause(
11260 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11261 C->getOmpAllMemoryLoc()},
11262 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11263}
11264
11265template <typename Derived>
11266OMPClause *
11267TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11268 ExprResult E = getDerived().TransformExpr(C->getDevice());
11269 if (E.isInvalid())
11270 return nullptr;
11271 return getDerived().RebuildOMPDeviceClause(
11272 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11273 C->getModifierLoc(), C->getEndLoc());
11274}
11275
11276template <typename Derived, class T>
11277bool transformOMPMappableExprListClause(
11278 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11279 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11280 DeclarationNameInfo &MapperIdInfo,
11281 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11282 // Transform expressions in the list.
11283 Vars.reserve(N: C->varlist_size());
11284 for (auto *VE : C->varlist()) {
11285 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11286 if (EVar.isInvalid())
11287 return true;
11288 Vars.push_back(Elt: EVar.get());
11289 }
11290 // Transform mapper scope specifier and identifier.
11291 NestedNameSpecifierLoc QualifierLoc;
11292 if (C->getMapperQualifierLoc()) {
11293 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11294 C->getMapperQualifierLoc());
11295 if (!QualifierLoc)
11296 return true;
11297 }
11298 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11299 MapperIdInfo = C->getMapperIdInfo();
11300 if (MapperIdInfo.getName()) {
11301 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11302 if (!MapperIdInfo.getName())
11303 return true;
11304 }
11305 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11306 // the previous user-defined mapper lookup in dependent environment.
11307 for (auto *E : C->mapperlists()) {
11308 // Transform all the decls.
11309 if (E) {
11310 auto *ULE = cast<UnresolvedLookupExpr>(E);
11311 UnresolvedSet<8> Decls;
11312 for (auto *D : ULE->decls()) {
11313 NamedDecl *InstD =
11314 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11315 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11316 }
11317 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11318 TT.getSema().Context, /*NamingClass=*/nullptr,
11319 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11320 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11321 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11322 } else {
11323 UnresolvedMappers.push_back(Elt: nullptr);
11324 }
11325 }
11326 return false;
11327}
11328
11329template <typename Derived>
11330OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11331 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11332 llvm::SmallVector<Expr *, 16> Vars;
11333 Expr *IteratorModifier = C->getIteratorModifier();
11334 if (IteratorModifier) {
11335 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11336 if (MapModRes.isInvalid())
11337 return nullptr;
11338 IteratorModifier = MapModRes.get();
11339 }
11340 CXXScopeSpec MapperIdScopeSpec;
11341 DeclarationNameInfo MapperIdInfo;
11342 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11343 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11344 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11345 return nullptr;
11346 return getDerived().RebuildOMPMapClause(
11347 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11348 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11349 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11350}
11351
11352template <typename Derived>
11353OMPClause *
11354TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11355 Expr *Allocator = C->getAllocator();
11356 if (Allocator) {
11357 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11358 if (AllocatorRes.isInvalid())
11359 return nullptr;
11360 Allocator = AllocatorRes.get();
11361 }
11362 Expr *Alignment = C->getAlignment();
11363 if (Alignment) {
11364 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11365 if (AlignmentRes.isInvalid())
11366 return nullptr;
11367 Alignment = AlignmentRes.get();
11368 }
11369 llvm::SmallVector<Expr *, 16> Vars;
11370 Vars.reserve(N: C->varlist_size());
11371 for (auto *VE : C->varlist()) {
11372 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11373 if (EVar.isInvalid())
11374 return nullptr;
11375 Vars.push_back(Elt: EVar.get());
11376 }
11377 return getDerived().RebuildOMPAllocateClause(
11378 Allocator, Alignment, C->getFirstAllocateModifier(),
11379 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11380 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11381 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11382}
11383
11384template <typename Derived>
11385OMPClause *
11386TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11387 llvm::SmallVector<Expr *, 3> Vars;
11388 Vars.reserve(N: C->varlist_size());
11389 for (auto *VE : C->varlist()) {
11390 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11391 if (EVar.isInvalid())
11392 return nullptr;
11393 Vars.push_back(Elt: EVar.get());
11394 }
11395 return getDerived().RebuildOMPNumTeamsClause(
11396 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11397}
11398
11399template <typename Derived>
11400OMPClause *
11401TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11402 llvm::SmallVector<Expr *, 3> Vars;
11403 Vars.reserve(N: C->varlist_size());
11404 for (auto *VE : C->varlist()) {
11405 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11406 if (EVar.isInvalid())
11407 return nullptr;
11408 Vars.push_back(Elt: EVar.get());
11409 }
11410 return getDerived().RebuildOMPThreadLimitClause(
11411 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11412}
11413
11414template <typename Derived>
11415OMPClause *
11416TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11417 ExprResult E = getDerived().TransformExpr(C->getPriority());
11418 if (E.isInvalid())
11419 return nullptr;
11420 return getDerived().RebuildOMPPriorityClause(
11421 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11422}
11423
11424template <typename Derived>
11425OMPClause *
11426TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11427 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11428 if (E.isInvalid())
11429 return nullptr;
11430 return getDerived().RebuildOMPGrainsizeClause(
11431 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11432 C->getModifierLoc(), C->getEndLoc());
11433}
11434
11435template <typename Derived>
11436OMPClause *
11437TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11438 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11439 if (E.isInvalid())
11440 return nullptr;
11441 return getDerived().RebuildOMPNumTasksClause(
11442 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11443 C->getModifierLoc(), C->getEndLoc());
11444}
11445
11446template <typename Derived>
11447OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11448 ExprResult E = getDerived().TransformExpr(C->getHint());
11449 if (E.isInvalid())
11450 return nullptr;
11451 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11452 C->getLParenLoc(), C->getEndLoc());
11453}
11454
11455template <typename Derived>
11456OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11457 OMPDistScheduleClause *C) {
11458 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11459 if (E.isInvalid())
11460 return nullptr;
11461 return getDerived().RebuildOMPDistScheduleClause(
11462 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11463 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11464}
11465
11466template <typename Derived>
11467OMPClause *
11468TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11469 // Rebuild Defaultmap Clause since we need to invoke the checking of
11470 // defaultmap(none:variable-category) after template initialization.
11471 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11472 C->getDefaultmapKind(),
11473 C->getBeginLoc(),
11474 C->getLParenLoc(),
11475 C->getDefaultmapModifierLoc(),
11476 C->getDefaultmapKindLoc(),
11477 C->getEndLoc());
11478}
11479
11480template <typename Derived>
11481OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11482 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11483 llvm::SmallVector<Expr *, 16> Vars;
11484 CXXScopeSpec MapperIdScopeSpec;
11485 DeclarationNameInfo MapperIdInfo;
11486 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11487 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11488 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11489 return nullptr;
11490 return getDerived().RebuildOMPToClause(
11491 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11492 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11493}
11494
11495template <typename Derived>
11496OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11497 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11498 llvm::SmallVector<Expr *, 16> Vars;
11499 CXXScopeSpec MapperIdScopeSpec;
11500 DeclarationNameInfo MapperIdInfo;
11501 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11502 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11503 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11504 return nullptr;
11505 return getDerived().RebuildOMPFromClause(
11506 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11507 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11508}
11509
11510template <typename Derived>
11511OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11512 OMPUseDevicePtrClause *C) {
11513 llvm::SmallVector<Expr *, 16> Vars;
11514 Vars.reserve(N: C->varlist_size());
11515 for (auto *VE : C->varlist()) {
11516 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11517 if (EVar.isInvalid())
11518 return nullptr;
11519 Vars.push_back(Elt: EVar.get());
11520 }
11521 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11522 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11523}
11524
11525template <typename Derived>
11526OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11527 OMPUseDeviceAddrClause *C) {
11528 llvm::SmallVector<Expr *, 16> Vars;
11529 Vars.reserve(N: C->varlist_size());
11530 for (auto *VE : C->varlist()) {
11531 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11532 if (EVar.isInvalid())
11533 return nullptr;
11534 Vars.push_back(Elt: EVar.get());
11535 }
11536 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11537 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11538}
11539
11540template <typename Derived>
11541OMPClause *
11542TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11543 llvm::SmallVector<Expr *, 16> Vars;
11544 Vars.reserve(N: C->varlist_size());
11545 for (auto *VE : C->varlist()) {
11546 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11547 if (EVar.isInvalid())
11548 return nullptr;
11549 Vars.push_back(Elt: EVar.get());
11550 }
11551 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11552 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11553}
11554
11555template <typename Derived>
11556OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11557 OMPHasDeviceAddrClause *C) {
11558 llvm::SmallVector<Expr *, 16> Vars;
11559 Vars.reserve(N: C->varlist_size());
11560 for (auto *VE : C->varlist()) {
11561 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11562 if (EVar.isInvalid())
11563 return nullptr;
11564 Vars.push_back(Elt: EVar.get());
11565 }
11566 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11567 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11568}
11569
11570template <typename Derived>
11571OMPClause *
11572TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11573 llvm::SmallVector<Expr *, 16> Vars;
11574 Vars.reserve(N: C->varlist_size());
11575 for (auto *VE : C->varlist()) {
11576 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11577 if (EVar.isInvalid())
11578 return nullptr;
11579 Vars.push_back(Elt: EVar.get());
11580 }
11581 return getDerived().RebuildOMPNontemporalClause(
11582 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11583}
11584
11585template <typename Derived>
11586OMPClause *
11587TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11588 llvm::SmallVector<Expr *, 16> Vars;
11589 Vars.reserve(N: C->varlist_size());
11590 for (auto *VE : C->varlist()) {
11591 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11592 if (EVar.isInvalid())
11593 return nullptr;
11594 Vars.push_back(Elt: EVar.get());
11595 }
11596 return getDerived().RebuildOMPInclusiveClause(
11597 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11598}
11599
11600template <typename Derived>
11601OMPClause *
11602TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11603 llvm::SmallVector<Expr *, 16> Vars;
11604 Vars.reserve(N: C->varlist_size());
11605 for (auto *VE : C->varlist()) {
11606 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11607 if (EVar.isInvalid())
11608 return nullptr;
11609 Vars.push_back(Elt: EVar.get());
11610 }
11611 return getDerived().RebuildOMPExclusiveClause(
11612 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11613}
11614
11615template <typename Derived>
11616OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11617 OMPUsesAllocatorsClause *C) {
11618 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11619 Data.reserve(N: C->getNumberOfAllocators());
11620 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11621 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11622 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11623 if (Allocator.isInvalid())
11624 continue;
11625 ExprResult AllocatorTraits;
11626 if (Expr *AT = D.AllocatorTraits) {
11627 AllocatorTraits = getDerived().TransformExpr(AT);
11628 if (AllocatorTraits.isInvalid())
11629 continue;
11630 }
11631 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11632 NewD.Allocator = Allocator.get();
11633 NewD.AllocatorTraits = AllocatorTraits.get();
11634 NewD.LParenLoc = D.LParenLoc;
11635 NewD.RParenLoc = D.RParenLoc;
11636 }
11637 return getDerived().RebuildOMPUsesAllocatorsClause(
11638 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11639}
11640
11641template <typename Derived>
11642OMPClause *
11643TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11644 SmallVector<Expr *, 4> Locators;
11645 Locators.reserve(N: C->varlist_size());
11646 ExprResult ModifierRes;
11647 if (Expr *Modifier = C->getModifier()) {
11648 ModifierRes = getDerived().TransformExpr(Modifier);
11649 if (ModifierRes.isInvalid())
11650 return nullptr;
11651 }
11652 for (Expr *E : C->varlist()) {
11653 ExprResult Locator = getDerived().TransformExpr(E);
11654 if (Locator.isInvalid())
11655 continue;
11656 Locators.push_back(Elt: Locator.get());
11657 }
11658 return getDerived().RebuildOMPAffinityClause(
11659 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11660 ModifierRes.get(), Locators);
11661}
11662
11663template <typename Derived>
11664OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11665 return getDerived().RebuildOMPOrderClause(
11666 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11667 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11668}
11669
11670template <typename Derived>
11671OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11672 return getDerived().RebuildOMPBindClause(
11673 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11674 C->getLParenLoc(), C->getEndLoc());
11675}
11676
11677template <typename Derived>
11678OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11679 OMPXDynCGroupMemClause *C) {
11680 ExprResult Size = getDerived().TransformExpr(C->getSize());
11681 if (Size.isInvalid())
11682 return nullptr;
11683 return getDerived().RebuildOMPXDynCGroupMemClause(
11684 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11685}
11686
11687template <typename Derived>
11688OMPClause *
11689TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11690 llvm::SmallVector<Expr *, 16> Vars;
11691 Vars.reserve(N: C->varlist_size());
11692 for (auto *VE : C->varlist()) {
11693 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11694 if (EVar.isInvalid())
11695 return nullptr;
11696 Vars.push_back(Elt: EVar.get());
11697 }
11698 return getDerived().RebuildOMPDoacrossClause(
11699 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11700 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11701}
11702
11703template <typename Derived>
11704OMPClause *
11705TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11706 SmallVector<const Attr *> NewAttrs;
11707 for (auto *A : C->getAttrs())
11708 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11709 return getDerived().RebuildOMPXAttributeClause(
11710 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11711}
11712
11713template <typename Derived>
11714OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11715 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11716}
11717
11718//===----------------------------------------------------------------------===//
11719// OpenACC transformation
11720//===----------------------------------------------------------------------===//
11721namespace {
11722template <typename Derived>
11723class OpenACCClauseTransform final
11724 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11725 TreeTransform<Derived> &Self;
11726 ArrayRef<const OpenACCClause *> ExistingClauses;
11727 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11728 OpenACCClause *NewClause = nullptr;
11729
11730 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11731 llvm::SmallVector<Expr *> InstantiatedVarList;
11732 for (Expr *CurVar : VarList) {
11733 ExprResult Res = Self.TransformExpr(CurVar);
11734
11735 if (!Res.isUsable())
11736 continue;
11737
11738 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11739 ParsedClause.getClauseKind(),
11740 Res.get());
11741
11742 if (Res.isUsable())
11743 InstantiatedVarList.push_back(Elt: Res.get());
11744 }
11745
11746 return InstantiatedVarList;
11747 }
11748
11749public:
11750 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11751 ArrayRef<const OpenACCClause *> ExistingClauses,
11752 SemaOpenACC::OpenACCParsedClause &PC)
11753 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11754
11755 OpenACCClause *CreatedClause() const { return NewClause; }
11756
11757#define VISIT_CLAUSE(CLAUSE_NAME) \
11758 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11759#include "clang/Basic/OpenACCClauses.def"
11760};
11761
11762template <typename Derived>
11763void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11764 const OpenACCDefaultClause &C) {
11765 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11766
11767 NewClause = OpenACCDefaultClause::Create(
11768 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11769 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11770 EndLoc: ParsedClause.getEndLoc());
11771}
11772
11773template <typename Derived>
11774void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11775 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11776 assert(Cond && "If constructed with invalid Condition");
11777 Sema::ConditionResult Res = Self.TransformCondition(
11778 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11779
11780 if (Res.isInvalid() || !Res.get().second)
11781 return;
11782
11783 ParsedClause.setConditionDetails(Res.get().second);
11784
11785 NewClause = OpenACCIfClause::Create(
11786 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11787 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11788 EndLoc: ParsedClause.getEndLoc());
11789}
11790
11791template <typename Derived>
11792void OpenACCClauseTransform<Derived>::VisitSelfClause(
11793 const OpenACCSelfClause &C) {
11794
11795 // If this is an 'update' 'self' clause, this is actually a var list instead.
11796 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11797 llvm::SmallVector<Expr *> InstantiatedVarList;
11798 for (Expr *CurVar : C.getVarList()) {
11799 ExprResult Res = Self.TransformExpr(CurVar);
11800
11801 if (!Res.isUsable())
11802 continue;
11803
11804 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11805 ParsedClause.getClauseKind(),
11806 Res.get());
11807
11808 if (Res.isUsable())
11809 InstantiatedVarList.push_back(Elt: Res.get());
11810 }
11811
11812 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
11813 ModKind: OpenACCModifierKind::Invalid);
11814
11815 NewClause = OpenACCSelfClause::Create(
11816 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11817 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11818 ParsedClause.getEndLoc());
11819 } else {
11820
11821 if (C.hasConditionExpr()) {
11822 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11823 Sema::ConditionResult Res =
11824 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11825 Sema::ConditionKind::Boolean);
11826
11827 if (Res.isInvalid() || !Res.get().second)
11828 return;
11829
11830 ParsedClause.setConditionDetails(Res.get().second);
11831 }
11832
11833 NewClause = OpenACCSelfClause::Create(
11834 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11835 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11836 ParsedClause.getEndLoc());
11837 }
11838}
11839
11840template <typename Derived>
11841void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11842 const OpenACCNumGangsClause &C) {
11843 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11844
11845 for (Expr *CurIntExpr : C.getIntExprs()) {
11846 ExprResult Res = Self.TransformExpr(CurIntExpr);
11847
11848 if (!Res.isUsable())
11849 return;
11850
11851 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11852 C.getClauseKind(),
11853 C.getBeginLoc(), Res.get());
11854 if (!Res.isUsable())
11855 return;
11856
11857 InstantiatedIntExprs.push_back(Elt: Res.get());
11858 }
11859
11860 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11861 NewClause = OpenACCNumGangsClause::Create(
11862 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11863 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
11864 EndLoc: ParsedClause.getEndLoc());
11865}
11866
11867template <typename Derived>
11868void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11869 const OpenACCPrivateClause &C) {
11870 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11871 OpenACCModifierKind::Invalid);
11872
11873 NewClause = OpenACCPrivateClause::Create(
11874 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11875 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11876 EndLoc: ParsedClause.getEndLoc());
11877}
11878
11879template <typename Derived>
11880void OpenACCClauseTransform<Derived>::VisitHostClause(
11881 const OpenACCHostClause &C) {
11882 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11883 OpenACCModifierKind::Invalid);
11884
11885 NewClause = OpenACCHostClause::Create(
11886 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11887 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11888 EndLoc: ParsedClause.getEndLoc());
11889}
11890
11891template <typename Derived>
11892void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11893 const OpenACCDeviceClause &C) {
11894 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11895 OpenACCModifierKind::Invalid);
11896
11897 NewClause = OpenACCDeviceClause::Create(
11898 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11899 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11900 EndLoc: ParsedClause.getEndLoc());
11901}
11902
11903template <typename Derived>
11904void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11905 const OpenACCFirstPrivateClause &C) {
11906 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11907 OpenACCModifierKind::Invalid);
11908
11909 NewClause = OpenACCFirstPrivateClause::Create(
11910 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11911 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11912 EndLoc: ParsedClause.getEndLoc());
11913}
11914
11915template <typename Derived>
11916void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11917 const OpenACCNoCreateClause &C) {
11918 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11919 OpenACCModifierKind::Invalid);
11920
11921 NewClause = OpenACCNoCreateClause::Create(
11922 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11923 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11924 EndLoc: ParsedClause.getEndLoc());
11925}
11926
11927template <typename Derived>
11928void OpenACCClauseTransform<Derived>::VisitPresentClause(
11929 const OpenACCPresentClause &C) {
11930 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11931 OpenACCModifierKind::Invalid);
11932
11933 NewClause = OpenACCPresentClause::Create(
11934 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11935 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11936 EndLoc: ParsedClause.getEndLoc());
11937}
11938
11939template <typename Derived>
11940void OpenACCClauseTransform<Derived>::VisitCopyClause(
11941 const OpenACCCopyClause &C) {
11942 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11943 C.getModifierList());
11944
11945 NewClause = OpenACCCopyClause::Create(
11946 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11947 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11948 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11949 EndLoc: ParsedClause.getEndLoc());
11950}
11951
11952template <typename Derived>
11953void OpenACCClauseTransform<Derived>::VisitLinkClause(
11954 const OpenACCLinkClause &C) {
11955 llvm_unreachable("link clause not valid unless a decl transform");
11956}
11957
11958template <typename Derived>
11959void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
11960 const OpenACCDeviceResidentClause &C) {
11961 llvm_unreachable("device_resident clause not valid unless a decl transform");
11962}
11963template <typename Derived>
11964void OpenACCClauseTransform<Derived>::VisitNoHostClause(
11965 const OpenACCNoHostClause &C) {
11966 llvm_unreachable("nohost clause not valid unless a decl transform");
11967}
11968template <typename Derived>
11969void OpenACCClauseTransform<Derived>::VisitBindClause(
11970 const OpenACCBindClause &C) {
11971 llvm_unreachable("bind clause not valid unless a decl transform");
11972}
11973
11974template <typename Derived>
11975void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11976 const OpenACCCopyInClause &C) {
11977 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11978 C.getModifierList());
11979
11980 NewClause = OpenACCCopyInClause::Create(
11981 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11982 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11983 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11984 EndLoc: ParsedClause.getEndLoc());
11985}
11986
11987template <typename Derived>
11988void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11989 const OpenACCCopyOutClause &C) {
11990 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11991 C.getModifierList());
11992
11993 NewClause = OpenACCCopyOutClause::Create(
11994 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11995 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11996 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11997 EndLoc: ParsedClause.getEndLoc());
11998}
11999
12000template <typename Derived>
12001void OpenACCClauseTransform<Derived>::VisitCreateClause(
12002 const OpenACCCreateClause &C) {
12003 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12004 C.getModifierList());
12005
12006 NewClause = OpenACCCreateClause::Create(
12007 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12008 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12009 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12010 EndLoc: ParsedClause.getEndLoc());
12011}
12012template <typename Derived>
12013void OpenACCClauseTransform<Derived>::VisitAttachClause(
12014 const OpenACCAttachClause &C) {
12015 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12016
12017 // Ensure each var is a pointer type.
12018 llvm::erase_if(VarList, [&](Expr *E) {
12019 return Self.getSema().OpenACC().CheckVarIsPointerType(
12020 OpenACCClauseKind::Attach, E);
12021 });
12022
12023 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12024 NewClause = OpenACCAttachClause::Create(
12025 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12026 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12027 EndLoc: ParsedClause.getEndLoc());
12028}
12029
12030template <typename Derived>
12031void OpenACCClauseTransform<Derived>::VisitDetachClause(
12032 const OpenACCDetachClause &C) {
12033 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12034
12035 // Ensure each var is a pointer type.
12036 llvm::erase_if(VarList, [&](Expr *E) {
12037 return Self.getSema().OpenACC().CheckVarIsPointerType(
12038 OpenACCClauseKind::Detach, E);
12039 });
12040
12041 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12042 NewClause = OpenACCDetachClause::Create(
12043 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12044 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12045 EndLoc: ParsedClause.getEndLoc());
12046}
12047
12048template <typename Derived>
12049void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12050 const OpenACCDeleteClause &C) {
12051 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12052 OpenACCModifierKind::Invalid);
12053 NewClause = OpenACCDeleteClause::Create(
12054 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12055 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12056 EndLoc: ParsedClause.getEndLoc());
12057}
12058
12059template <typename Derived>
12060void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12061 const OpenACCUseDeviceClause &C) {
12062 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12063 OpenACCModifierKind::Invalid);
12064 NewClause = OpenACCUseDeviceClause::Create(
12065 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12066 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12067 EndLoc: ParsedClause.getEndLoc());
12068}
12069
12070template <typename Derived>
12071void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12072 const OpenACCDevicePtrClause &C) {
12073 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12074
12075 // Ensure each var is a pointer type.
12076 llvm::erase_if(VarList, [&](Expr *E) {
12077 return Self.getSema().OpenACC().CheckVarIsPointerType(
12078 OpenACCClauseKind::DevicePtr, E);
12079 });
12080
12081 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12082 NewClause = OpenACCDevicePtrClause::Create(
12083 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12084 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12085 EndLoc: ParsedClause.getEndLoc());
12086}
12087
12088template <typename Derived>
12089void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12090 const OpenACCNumWorkersClause &C) {
12091 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12092 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12093
12094 ExprResult Res = Self.TransformExpr(IntExpr);
12095 if (!Res.isUsable())
12096 return;
12097
12098 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12099 C.getClauseKind(),
12100 C.getBeginLoc(), Res.get());
12101 if (!Res.isUsable())
12102 return;
12103
12104 ParsedClause.setIntExprDetails(Res.get());
12105 NewClause = OpenACCNumWorkersClause::Create(
12106 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12107 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12108 EndLoc: ParsedClause.getEndLoc());
12109}
12110
12111template <typename Derived>
12112void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12113 const OpenACCDeviceNumClause &C) {
12114 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12115 assert(IntExpr && "device_num clause constructed with invalid int expr");
12116
12117 ExprResult Res = Self.TransformExpr(IntExpr);
12118 if (!Res.isUsable())
12119 return;
12120
12121 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12122 C.getClauseKind(),
12123 C.getBeginLoc(), Res.get());
12124 if (!Res.isUsable())
12125 return;
12126
12127 ParsedClause.setIntExprDetails(Res.get());
12128 NewClause = OpenACCDeviceNumClause::Create(
12129 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12130 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12131 EndLoc: ParsedClause.getEndLoc());
12132}
12133
12134template <typename Derived>
12135void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12136 const OpenACCDefaultAsyncClause &C) {
12137 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12138 assert(IntExpr && "default_async clause constructed with invalid int expr");
12139
12140 ExprResult Res = Self.TransformExpr(IntExpr);
12141 if (!Res.isUsable())
12142 return;
12143
12144 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12145 C.getClauseKind(),
12146 C.getBeginLoc(), Res.get());
12147 if (!Res.isUsable())
12148 return;
12149
12150 ParsedClause.setIntExprDetails(Res.get());
12151 NewClause = OpenACCDefaultAsyncClause::Create(
12152 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12153 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12154 EndLoc: ParsedClause.getEndLoc());
12155}
12156
12157template <typename Derived>
12158void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12159 const OpenACCVectorLengthClause &C) {
12160 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12161 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12162
12163 ExprResult Res = Self.TransformExpr(IntExpr);
12164 if (!Res.isUsable())
12165 return;
12166
12167 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12168 C.getClauseKind(),
12169 C.getBeginLoc(), Res.get());
12170 if (!Res.isUsable())
12171 return;
12172
12173 ParsedClause.setIntExprDetails(Res.get());
12174 NewClause = OpenACCVectorLengthClause::Create(
12175 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12176 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12177 EndLoc: ParsedClause.getEndLoc());
12178}
12179
12180template <typename Derived>
12181void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12182 const OpenACCAsyncClause &C) {
12183 if (C.hasIntExpr()) {
12184 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12185 if (!Res.isUsable())
12186 return;
12187
12188 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12189 C.getClauseKind(),
12190 C.getBeginLoc(), Res.get());
12191 if (!Res.isUsable())
12192 return;
12193 ParsedClause.setIntExprDetails(Res.get());
12194 }
12195
12196 NewClause = OpenACCAsyncClause::Create(
12197 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12198 LParenLoc: ParsedClause.getLParenLoc(),
12199 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12200 : nullptr,
12201 EndLoc: ParsedClause.getEndLoc());
12202}
12203
12204template <typename Derived>
12205void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12206 const OpenACCWorkerClause &C) {
12207 if (C.hasIntExpr()) {
12208 // restrictions on this expression are all "does it exist in certain
12209 // situations" that are not possible to be dependent, so the only check we
12210 // have is that it transforms, and is an int expression.
12211 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12212 if (!Res.isUsable())
12213 return;
12214
12215 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12216 C.getClauseKind(),
12217 C.getBeginLoc(), Res.get());
12218 if (!Res.isUsable())
12219 return;
12220 ParsedClause.setIntExprDetails(Res.get());
12221 }
12222
12223 NewClause = OpenACCWorkerClause::Create(
12224 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12225 LParenLoc: ParsedClause.getLParenLoc(),
12226 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12227 : nullptr,
12228 EndLoc: ParsedClause.getEndLoc());
12229}
12230
12231template <typename Derived>
12232void OpenACCClauseTransform<Derived>::VisitVectorClause(
12233 const OpenACCVectorClause &C) {
12234 if (C.hasIntExpr()) {
12235 // restrictions on this expression are all "does it exist in certain
12236 // situations" that are not possible to be dependent, so the only check we
12237 // have is that it transforms, and is an int expression.
12238 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12239 if (!Res.isUsable())
12240 return;
12241
12242 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12243 C.getClauseKind(),
12244 C.getBeginLoc(), Res.get());
12245 if (!Res.isUsable())
12246 return;
12247 ParsedClause.setIntExprDetails(Res.get());
12248 }
12249
12250 NewClause = OpenACCVectorClause::Create(
12251 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12252 LParenLoc: ParsedClause.getLParenLoc(),
12253 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12254 : nullptr,
12255 EndLoc: ParsedClause.getEndLoc());
12256}
12257
12258template <typename Derived>
12259void OpenACCClauseTransform<Derived>::VisitWaitClause(
12260 const OpenACCWaitClause &C) {
12261 if (C.hasExprs()) {
12262 Expr *DevNumExpr = nullptr;
12263 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12264
12265 // Instantiate devnum expr if it exists.
12266 if (C.getDevNumExpr()) {
12267 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12268 if (!Res.isUsable())
12269 return;
12270 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12271 C.getClauseKind(),
12272 C.getBeginLoc(), Res.get());
12273 if (!Res.isUsable())
12274 return;
12275
12276 DevNumExpr = Res.get();
12277 }
12278
12279 // Instantiate queue ids.
12280 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12281 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12282 if (!Res.isUsable())
12283 return;
12284 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12285 C.getClauseKind(),
12286 C.getBeginLoc(), Res.get());
12287 if (!Res.isUsable())
12288 return;
12289
12290 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12291 }
12292
12293 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12294 IntExprs: std::move(InstantiatedQueueIdExprs));
12295 }
12296
12297 NewClause = OpenACCWaitClause::Create(
12298 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12299 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12300 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12301 EndLoc: ParsedClause.getEndLoc());
12302}
12303
12304template <typename Derived>
12305void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12306 const OpenACCDeviceTypeClause &C) {
12307 // Nothing to transform here, just create a new version of 'C'.
12308 NewClause = OpenACCDeviceTypeClause::Create(
12309 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12310 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12311 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12312}
12313
12314template <typename Derived>
12315void OpenACCClauseTransform<Derived>::VisitAutoClause(
12316 const OpenACCAutoClause &C) {
12317 // Nothing to do, so just create a new node.
12318 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12319 BeginLoc: ParsedClause.getBeginLoc(),
12320 EndLoc: ParsedClause.getEndLoc());
12321}
12322
12323template <typename Derived>
12324void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12325 const OpenACCIndependentClause &C) {
12326 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12327 BeginLoc: ParsedClause.getBeginLoc(),
12328 EndLoc: ParsedClause.getEndLoc());
12329}
12330
12331template <typename Derived>
12332void OpenACCClauseTransform<Derived>::VisitSeqClause(
12333 const OpenACCSeqClause &C) {
12334 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12335 BeginLoc: ParsedClause.getBeginLoc(),
12336 EndLoc: ParsedClause.getEndLoc());
12337}
12338template <typename Derived>
12339void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12340 const OpenACCFinalizeClause &C) {
12341 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12342 BeginLoc: ParsedClause.getBeginLoc(),
12343 EndLoc: ParsedClause.getEndLoc());
12344}
12345
12346template <typename Derived>
12347void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12348 const OpenACCIfPresentClause &C) {
12349 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12350 BeginLoc: ParsedClause.getBeginLoc(),
12351 EndLoc: ParsedClause.getEndLoc());
12352}
12353
12354template <typename Derived>
12355void OpenACCClauseTransform<Derived>::VisitReductionClause(
12356 const OpenACCReductionClause &C) {
12357 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12358 SmallVector<Expr *> ValidVars;
12359
12360 for (Expr *Var : TransformedVars) {
12361 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12362 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12363 if (Res.isUsable())
12364 ValidVars.push_back(Elt: Res.get());
12365 }
12366
12367 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12368 ExistingClauses, ParsedClause.getDirectiveKind(),
12369 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12370 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12371}
12372
12373template <typename Derived>
12374void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12375 const OpenACCCollapseClause &C) {
12376 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12377 assert(LoopCount && "collapse clause constructed with invalid loop count");
12378
12379 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12380
12381 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12382 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12383 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12384
12385 NewLoopCount =
12386 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12387
12388 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12389 NewClause = OpenACCCollapseClause::Create(
12390 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12391 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12392 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12393}
12394
12395template <typename Derived>
12396void OpenACCClauseTransform<Derived>::VisitTileClause(
12397 const OpenACCTileClause &C) {
12398
12399 llvm::SmallVector<Expr *> TransformedExprs;
12400
12401 for (Expr *E : C.getSizeExprs()) {
12402 ExprResult NewSizeExpr = Self.TransformExpr(E);
12403
12404 if (!NewSizeExpr.isUsable())
12405 return;
12406
12407 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12408 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12409 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12410
12411 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12412
12413 if (!NewSizeExpr.isUsable())
12414 return;
12415 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12416 }
12417
12418 ParsedClause.setIntExprDetails(TransformedExprs);
12419 NewClause = OpenACCTileClause::Create(
12420 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12421 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12422 EndLoc: ParsedClause.getEndLoc());
12423}
12424template <typename Derived>
12425void OpenACCClauseTransform<Derived>::VisitGangClause(
12426 const OpenACCGangClause &C) {
12427 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12428 llvm::SmallVector<Expr *> TransformedIntExprs;
12429
12430 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12431 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12432 if (!ER.isUsable())
12433 continue;
12434
12435 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12436 ParsedClause.getDirectiveKind(),
12437 C.getExpr(I).first, ER.get());
12438 if (!ER.isUsable())
12439 continue;
12440 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12441 TransformedIntExprs.push_back(Elt: ER.get());
12442 }
12443
12444 NewClause = Self.getSema().OpenACC().CheckGangClause(
12445 ParsedClause.getDirectiveKind(), ExistingClauses,
12446 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12447 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12448}
12449} // namespace
12450template <typename Derived>
12451OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12452 ArrayRef<const OpenACCClause *> ExistingClauses,
12453 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12454
12455 SemaOpenACC::OpenACCParsedClause ParsedClause(
12456 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12457 ParsedClause.setEndLoc(OldClause->getEndLoc());
12458
12459 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12460 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12461
12462 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12463 ParsedClause};
12464 Transform.Visit(OldClause);
12465
12466 return Transform.CreatedClause();
12467}
12468
12469template <typename Derived>
12470llvm::SmallVector<OpenACCClause *>
12471TreeTransform<Derived>::TransformOpenACCClauseList(
12472 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12473 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12474 for (const auto *Clause : OldClauses) {
12475 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12476 TransformedClauses, DirKind, Clause))
12477 TransformedClauses.push_back(Elt: TransformedClause);
12478 }
12479 return TransformedClauses;
12480}
12481
12482template <typename Derived>
12483StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12484 OpenACCComputeConstruct *C) {
12485 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12486
12487 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12488 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12489 C->clauses());
12490
12491 if (getSema().OpenACC().ActOnStartStmtDirective(
12492 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12493 return StmtError();
12494
12495 // Transform Structured Block.
12496 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12497 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12498 C->clauses(), TransformedClauses);
12499 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12500 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12501 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12502
12503 return getDerived().RebuildOpenACCComputeConstruct(
12504 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12505 C->getEndLoc(), TransformedClauses, StrBlock);
12506}
12507
12508template <typename Derived>
12509StmtResult
12510TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12511
12512 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12513
12514 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12515 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12516 C->clauses());
12517
12518 if (getSema().OpenACC().ActOnStartStmtDirective(
12519 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12520 return StmtError();
12521
12522 // Transform Loop.
12523 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12524 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12525 C->clauses(), TransformedClauses);
12526 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12527 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12528 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12529
12530 return getDerived().RebuildOpenACCLoopConstruct(
12531 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12532 TransformedClauses, Loop);
12533}
12534
12535template <typename Derived>
12536StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12537 OpenACCCombinedConstruct *C) {
12538 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12539
12540 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12541 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12542 C->clauses());
12543
12544 if (getSema().OpenACC().ActOnStartStmtDirective(
12545 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12546 return StmtError();
12547
12548 // Transform Loop.
12549 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12550 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12551 C->clauses(), TransformedClauses);
12552 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12553 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12554 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12555
12556 return getDerived().RebuildOpenACCCombinedConstruct(
12557 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12558 C->getEndLoc(), TransformedClauses, Loop);
12559}
12560
12561template <typename Derived>
12562StmtResult
12563TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12564 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12565
12566 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12567 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12568 C->clauses());
12569 if (getSema().OpenACC().ActOnStartStmtDirective(
12570 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12571 return StmtError();
12572
12573 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12574 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12575 C->clauses(), TransformedClauses);
12576 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12577 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12578 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12579
12580 return getDerived().RebuildOpenACCDataConstruct(
12581 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12582 TransformedClauses, StrBlock);
12583}
12584
12585template <typename Derived>
12586StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12587 OpenACCEnterDataConstruct *C) {
12588 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12589
12590 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12591 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12592 C->clauses());
12593 if (getSema().OpenACC().ActOnStartStmtDirective(
12594 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12595 return StmtError();
12596
12597 return getDerived().RebuildOpenACCEnterDataConstruct(
12598 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12599 TransformedClauses);
12600}
12601
12602template <typename Derived>
12603StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12604 OpenACCExitDataConstruct *C) {
12605 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12606
12607 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12608 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12609 C->clauses());
12610 if (getSema().OpenACC().ActOnStartStmtDirective(
12611 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12612 return StmtError();
12613
12614 return getDerived().RebuildOpenACCExitDataConstruct(
12615 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12616 TransformedClauses);
12617}
12618
12619template <typename Derived>
12620StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12621 OpenACCHostDataConstruct *C) {
12622 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12623
12624 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12625 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12626 C->clauses());
12627 if (getSema().OpenACC().ActOnStartStmtDirective(
12628 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12629 return StmtError();
12630
12631 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12632 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12633 C->clauses(), TransformedClauses);
12634 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12635 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12636 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12637
12638 return getDerived().RebuildOpenACCHostDataConstruct(
12639 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12640 TransformedClauses, StrBlock);
12641}
12642
12643template <typename Derived>
12644StmtResult
12645TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12646 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12647
12648 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12649 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12650 C->clauses());
12651 if (getSema().OpenACC().ActOnStartStmtDirective(
12652 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12653 return StmtError();
12654
12655 return getDerived().RebuildOpenACCInitConstruct(
12656 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12657 TransformedClauses);
12658}
12659
12660template <typename Derived>
12661StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12662 OpenACCShutdownConstruct *C) {
12663 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12664
12665 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12666 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12667 C->clauses());
12668 if (getSema().OpenACC().ActOnStartStmtDirective(
12669 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12670 return StmtError();
12671
12672 return getDerived().RebuildOpenACCShutdownConstruct(
12673 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12674 TransformedClauses);
12675}
12676template <typename Derived>
12677StmtResult
12678TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12679 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12680
12681 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12682 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12683 C->clauses());
12684 if (getSema().OpenACC().ActOnStartStmtDirective(
12685 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12686 return StmtError();
12687
12688 return getDerived().RebuildOpenACCSetConstruct(
12689 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12690 TransformedClauses);
12691}
12692
12693template <typename Derived>
12694StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12695 OpenACCUpdateConstruct *C) {
12696 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12697
12698 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12699 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12700 C->clauses());
12701 if (getSema().OpenACC().ActOnStartStmtDirective(
12702 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12703 return StmtError();
12704
12705 return getDerived().RebuildOpenACCUpdateConstruct(
12706 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12707 TransformedClauses);
12708}
12709
12710template <typename Derived>
12711StmtResult
12712TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12713 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12714
12715 ExprResult DevNumExpr;
12716 if (C->hasDevNumExpr()) {
12717 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12718
12719 if (DevNumExpr.isUsable())
12720 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12721 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12722 C->getBeginLoc(), DevNumExpr.get());
12723 }
12724
12725 llvm::SmallVector<Expr *> QueueIdExprs;
12726
12727 for (Expr *QE : C->getQueueIdExprs()) {
12728 assert(QE && "Null queue id expr?");
12729 ExprResult NewEQ = getDerived().TransformExpr(QE);
12730
12731 if (!NewEQ.isUsable())
12732 break;
12733 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12734 OpenACCClauseKind::Invalid,
12735 C->getBeginLoc(), NewEQ.get());
12736 if (NewEQ.isUsable())
12737 QueueIdExprs.push_back(Elt: NewEQ.get());
12738 }
12739
12740 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12741 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12742 C->clauses());
12743
12744 if (getSema().OpenACC().ActOnStartStmtDirective(
12745 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12746 return StmtError();
12747
12748 return getDerived().RebuildOpenACCWaitConstruct(
12749 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12750 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12751 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12752}
12753template <typename Derived>
12754StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12755 OpenACCCacheConstruct *C) {
12756 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12757
12758 llvm::SmallVector<Expr *> TransformedVarList;
12759 for (Expr *Var : C->getVarList()) {
12760 assert(Var && "Null var listexpr?");
12761
12762 ExprResult NewVar = getDerived().TransformExpr(Var);
12763
12764 if (!NewVar.isUsable())
12765 break;
12766
12767 NewVar = getSema().OpenACC().ActOnVar(
12768 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12769 if (!NewVar.isUsable())
12770 break;
12771
12772 TransformedVarList.push_back(Elt: NewVar.get());
12773 }
12774
12775 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12776 C->getBeginLoc(), {}))
12777 return StmtError();
12778
12779 return getDerived().RebuildOpenACCCacheConstruct(
12780 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12781 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
12782 C->getEndLoc());
12783}
12784
12785template <typename Derived>
12786StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
12787 OpenACCAtomicConstruct *C) {
12788 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12789
12790 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12791 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12792 C->clauses());
12793
12794 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12795 C->getBeginLoc(), {}))
12796 return StmtError();
12797
12798 // Transform Associated Stmt.
12799 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12800 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
12801
12802 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
12803 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
12804 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
12805 AssocStmt);
12806
12807 return getDerived().RebuildOpenACCAtomicConstruct(
12808 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
12809 C->getEndLoc(), TransformedClauses, AssocStmt);
12810}
12811
12812template <typename Derived>
12813ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12814 OpenACCAsteriskSizeExpr *E) {
12815 if (getDerived().AlwaysRebuild())
12816 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12817 // Nothing can ever change, so there is never anything to transform.
12818 return E;
12819}
12820
12821//===----------------------------------------------------------------------===//
12822// Expression transformation
12823//===----------------------------------------------------------------------===//
12824template<typename Derived>
12825ExprResult
12826TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12827 return TransformExpr(E: E->getSubExpr());
12828}
12829
12830template <typename Derived>
12831ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12832 SYCLUniqueStableNameExpr *E) {
12833 if (!E->isTypeDependent())
12834 return E;
12835
12836 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12837
12838 if (!NewT)
12839 return ExprError();
12840
12841 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12842 return E;
12843
12844 return getDerived().RebuildSYCLUniqueStableNameExpr(
12845 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12846}
12847
12848template<typename Derived>
12849ExprResult
12850TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12851 if (!E->isTypeDependent())
12852 return E;
12853
12854 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12855 E->getIdentKind());
12856}
12857
12858template<typename Derived>
12859ExprResult
12860TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12861 NestedNameSpecifierLoc QualifierLoc;
12862 if (E->getQualifierLoc()) {
12863 QualifierLoc
12864 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12865 if (!QualifierLoc)
12866 return ExprError();
12867 }
12868
12869 ValueDecl *ND
12870 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12871 E->getDecl()));
12872 if (!ND || ND->isInvalidDecl())
12873 return ExprError();
12874
12875 NamedDecl *Found = ND;
12876 if (E->getFoundDecl() != E->getDecl()) {
12877 Found = cast_or_null<NamedDecl>(
12878 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12879 if (!Found)
12880 return ExprError();
12881 }
12882
12883 DeclarationNameInfo NameInfo = E->getNameInfo();
12884 if (NameInfo.getName()) {
12885 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12886 if (!NameInfo.getName())
12887 return ExprError();
12888 }
12889
12890 if (!getDerived().AlwaysRebuild() &&
12891 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12892 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12893 Found == E->getFoundDecl() &&
12894 NameInfo.getName() == E->getDecl()->getDeclName() &&
12895 !E->hasExplicitTemplateArgs()) {
12896
12897 // Mark it referenced in the new context regardless.
12898 // FIXME: this is a bit instantiation-specific.
12899 SemaRef.MarkDeclRefReferenced(E);
12900
12901 return E;
12902 }
12903
12904 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12905 if (E->hasExplicitTemplateArgs()) {
12906 TemplateArgs = &TransArgs;
12907 TransArgs.setLAngleLoc(E->getLAngleLoc());
12908 TransArgs.setRAngleLoc(E->getRAngleLoc());
12909 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12910 E->getNumTemplateArgs(),
12911 TransArgs))
12912 return ExprError();
12913 }
12914
12915 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12916 Found, TemplateArgs);
12917}
12918
12919template<typename Derived>
12920ExprResult
12921TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12922 return E;
12923}
12924
12925template <typename Derived>
12926ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12927 FixedPointLiteral *E) {
12928 return E;
12929}
12930
12931template<typename Derived>
12932ExprResult
12933TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12934 return E;
12935}
12936
12937template<typename Derived>
12938ExprResult
12939TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12940 return E;
12941}
12942
12943template<typename Derived>
12944ExprResult
12945TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12946 return E;
12947}
12948
12949template<typename Derived>
12950ExprResult
12951TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12952 return E;
12953}
12954
12955template<typename Derived>
12956ExprResult
12957TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12958 return getDerived().TransformCallExpr(E);
12959}
12960
12961template<typename Derived>
12962ExprResult
12963TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12964 ExprResult ControllingExpr;
12965 TypeSourceInfo *ControllingType = nullptr;
12966 if (E->isExprPredicate())
12967 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12968 else
12969 ControllingType = getDerived().TransformType(E->getControllingType());
12970
12971 if (ControllingExpr.isInvalid() && !ControllingType)
12972 return ExprError();
12973
12974 SmallVector<Expr *, 4> AssocExprs;
12975 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12976 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12977 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12978 if (TSI) {
12979 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12980 if (!AssocType)
12981 return ExprError();
12982 AssocTypes.push_back(Elt: AssocType);
12983 } else {
12984 AssocTypes.push_back(Elt: nullptr);
12985 }
12986
12987 ExprResult AssocExpr =
12988 getDerived().TransformExpr(Assoc.getAssociationExpr());
12989 if (AssocExpr.isInvalid())
12990 return ExprError();
12991 AssocExprs.push_back(Elt: AssocExpr.get());
12992 }
12993
12994 if (!ControllingType)
12995 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12996 E->getDefaultLoc(),
12997 E->getRParenLoc(),
12998 ControllingExpr.get(),
12999 AssocTypes,
13000 AssocExprs);
13001 return getDerived().RebuildGenericSelectionExpr(
13002 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13003 ControllingType, AssocTypes, AssocExprs);
13004}
13005
13006template<typename Derived>
13007ExprResult
13008TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13009 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13010 if (SubExpr.isInvalid())
13011 return ExprError();
13012
13013 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13014 return E;
13015
13016 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13017 E->getRParen());
13018}
13019
13020/// The operand of a unary address-of operator has special rules: it's
13021/// allowed to refer to a non-static member of a class even if there's no 'this'
13022/// object available.
13023template<typename Derived>
13024ExprResult
13025TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13026 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13027 return getDerived().TransformDependentScopeDeclRefExpr(
13028 DRE, /*IsAddressOfOperand=*/true, nullptr);
13029 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13030 return getDerived().TransformUnresolvedLookupExpr(
13031 ULE, /*IsAddressOfOperand=*/true);
13032 else
13033 return getDerived().TransformExpr(E);
13034}
13035
13036template<typename Derived>
13037ExprResult
13038TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13039 ExprResult SubExpr;
13040 if (E->getOpcode() == UO_AddrOf)
13041 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13042 else
13043 SubExpr = TransformExpr(E: E->getSubExpr());
13044 if (SubExpr.isInvalid())
13045 return ExprError();
13046
13047 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13048 return E;
13049
13050 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13051 E->getOpcode(),
13052 SubExpr.get());
13053}
13054
13055template<typename Derived>
13056ExprResult
13057TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13058 // Transform the type.
13059 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13060 if (!Type)
13061 return ExprError();
13062
13063 // Transform all of the components into components similar to what the
13064 // parser uses.
13065 // FIXME: It would be slightly more efficient in the non-dependent case to
13066 // just map FieldDecls, rather than requiring the rebuilder to look for
13067 // the fields again. However, __builtin_offsetof is rare enough in
13068 // template code that we don't care.
13069 bool ExprChanged = false;
13070 typedef Sema::OffsetOfComponent Component;
13071 SmallVector<Component, 4> Components;
13072 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13073 const OffsetOfNode &ON = E->getComponent(Idx: I);
13074 Component Comp;
13075 Comp.isBrackets = true;
13076 Comp.LocStart = ON.getSourceRange().getBegin();
13077 Comp.LocEnd = ON.getSourceRange().getEnd();
13078 switch (ON.getKind()) {
13079 case OffsetOfNode::Array: {
13080 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13081 ExprResult Index = getDerived().TransformExpr(FromIndex);
13082 if (Index.isInvalid())
13083 return ExprError();
13084
13085 ExprChanged = ExprChanged || Index.get() != FromIndex;
13086 Comp.isBrackets = true;
13087 Comp.U.E = Index.get();
13088 break;
13089 }
13090
13091 case OffsetOfNode::Field:
13092 case OffsetOfNode::Identifier:
13093 Comp.isBrackets = false;
13094 Comp.U.IdentInfo = ON.getFieldName();
13095 if (!Comp.U.IdentInfo)
13096 continue;
13097
13098 break;
13099
13100 case OffsetOfNode::Base:
13101 // Will be recomputed during the rebuild.
13102 continue;
13103 }
13104
13105 Components.push_back(Elt: Comp);
13106 }
13107
13108 // If nothing changed, retain the existing expression.
13109 if (!getDerived().AlwaysRebuild() &&
13110 Type == E->getTypeSourceInfo() &&
13111 !ExprChanged)
13112 return E;
13113
13114 // Build a new offsetof expression.
13115 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13116 Components, E->getRParenLoc());
13117}
13118
13119template<typename Derived>
13120ExprResult
13121TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13122 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13123 "opaque value expression requires transformation");
13124 return E;
13125}
13126
13127template <typename Derived>
13128ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13129 llvm::SmallVector<Expr *, 8> Children;
13130 bool Changed = false;
13131 for (Expr *C : E->subExpressions()) {
13132 ExprResult NewC = getDerived().TransformExpr(C);
13133 if (NewC.isInvalid())
13134 return ExprError();
13135 Children.push_back(Elt: NewC.get());
13136
13137 Changed |= NewC.get() != C;
13138 }
13139 if (!getDerived().AlwaysRebuild() && !Changed)
13140 return E;
13141 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13142 Children, E->getType());
13143}
13144
13145template<typename Derived>
13146ExprResult
13147TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13148 // Rebuild the syntactic form. The original syntactic form has
13149 // opaque-value expressions in it, so strip those away and rebuild
13150 // the result. This is a really awful way of doing this, but the
13151 // better solution (rebuilding the semantic expressions and
13152 // rebinding OVEs as necessary) doesn't work; we'd need
13153 // TreeTransform to not strip away implicit conversions.
13154 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13155 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13156 if (result.isInvalid()) return ExprError();
13157
13158 // If that gives us a pseudo-object result back, the pseudo-object
13159 // expression must have been an lvalue-to-rvalue conversion which we
13160 // should reapply.
13161 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13162 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13163
13164 return result;
13165}
13166
13167template<typename Derived>
13168ExprResult
13169TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13170 UnaryExprOrTypeTraitExpr *E) {
13171 if (E->isArgumentType()) {
13172 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13173
13174 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13175 if (!NewT)
13176 return ExprError();
13177
13178 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13179 return E;
13180
13181 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13182 E->getKind(),
13183 E->getSourceRange());
13184 }
13185
13186 // C++0x [expr.sizeof]p1:
13187 // The operand is either an expression, which is an unevaluated operand
13188 // [...]
13189 EnterExpressionEvaluationContext Unevaluated(
13190 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13191 Sema::ReuseLambdaContextDecl);
13192
13193 // Try to recover if we have something like sizeof(T::X) where X is a type.
13194 // Notably, there must be *exactly* one set of parens if X is a type.
13195 TypeSourceInfo *RecoveryTSI = nullptr;
13196 ExprResult SubExpr;
13197 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13198 if (auto *DRE =
13199 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13200 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13201 PE, DRE, false, &RecoveryTSI);
13202 else
13203 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13204
13205 if (RecoveryTSI) {
13206 return getDerived().RebuildUnaryExprOrTypeTrait(
13207 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13208 } else if (SubExpr.isInvalid())
13209 return ExprError();
13210
13211 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13212 return E;
13213
13214 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13215 E->getOperatorLoc(),
13216 E->getKind(),
13217 E->getSourceRange());
13218}
13219
13220template<typename Derived>
13221ExprResult
13222TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13223 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13224 if (LHS.isInvalid())
13225 return ExprError();
13226
13227 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13228 if (RHS.isInvalid())
13229 return ExprError();
13230
13231
13232 if (!getDerived().AlwaysRebuild() &&
13233 LHS.get() == E->getLHS() &&
13234 RHS.get() == E->getRHS())
13235 return E;
13236
13237 return getDerived().RebuildArraySubscriptExpr(
13238 LHS.get(),
13239 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13240}
13241
13242template <typename Derived>
13243ExprResult
13244TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13245 ExprResult Base = getDerived().TransformExpr(E->getBase());
13246 if (Base.isInvalid())
13247 return ExprError();
13248
13249 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13250 if (RowIdx.isInvalid())
13251 return ExprError();
13252
13253 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13254 if (ColumnIdx.isInvalid())
13255 return ExprError();
13256
13257 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13258 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13259 return E;
13260
13261 return getDerived().RebuildMatrixSubscriptExpr(
13262 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13263}
13264
13265template <typename Derived>
13266ExprResult
13267TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13268 ExprResult Base = getDerived().TransformExpr(E->getBase());
13269 if (Base.isInvalid())
13270 return ExprError();
13271
13272 ExprResult LowerBound;
13273 if (E->getLowerBound()) {
13274 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13275 if (LowerBound.isInvalid())
13276 return ExprError();
13277 }
13278
13279 ExprResult Length;
13280 if (E->getLength()) {
13281 Length = getDerived().TransformExpr(E->getLength());
13282 if (Length.isInvalid())
13283 return ExprError();
13284 }
13285
13286 ExprResult Stride;
13287 if (E->isOMPArraySection()) {
13288 if (Expr *Str = E->getStride()) {
13289 Stride = getDerived().TransformExpr(Str);
13290 if (Stride.isInvalid())
13291 return ExprError();
13292 }
13293 }
13294
13295 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13296 LowerBound.get() == E->getLowerBound() &&
13297 Length.get() == E->getLength() &&
13298 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13299 return E;
13300
13301 return getDerived().RebuildArraySectionExpr(
13302 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13303 LowerBound.get(), E->getColonLocFirst(),
13304 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13305 Length.get(), Stride.get(), E->getRBracketLoc());
13306}
13307
13308template <typename Derived>
13309ExprResult
13310TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13311 ExprResult Base = getDerived().TransformExpr(E->getBase());
13312 if (Base.isInvalid())
13313 return ExprError();
13314
13315 SmallVector<Expr *, 4> Dims;
13316 bool ErrorFound = false;
13317 for (Expr *Dim : E->getDimensions()) {
13318 ExprResult DimRes = getDerived().TransformExpr(Dim);
13319 if (DimRes.isInvalid()) {
13320 ErrorFound = true;
13321 continue;
13322 }
13323 Dims.push_back(Elt: DimRes.get());
13324 }
13325
13326 if (ErrorFound)
13327 return ExprError();
13328 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13329 E->getRParenLoc(), Dims,
13330 E->getBracketsRanges());
13331}
13332
13333template <typename Derived>
13334ExprResult
13335TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13336 unsigned NumIterators = E->numOfIterators();
13337 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13338
13339 bool ErrorFound = false;
13340 bool NeedToRebuild = getDerived().AlwaysRebuild();
13341 for (unsigned I = 0; I < NumIterators; ++I) {
13342 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13343 Data[I].DeclIdent = D->getIdentifier();
13344 Data[I].DeclIdentLoc = D->getLocation();
13345 if (D->getLocation() == D->getBeginLoc()) {
13346 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13347 "Implicit type must be int.");
13348 } else {
13349 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13350 QualType DeclTy = getDerived().TransformType(D->getType());
13351 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13352 }
13353 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13354 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13355 ExprResult End = getDerived().TransformExpr(Range.End);
13356 ExprResult Step = getDerived().TransformExpr(Range.Step);
13357 ErrorFound = ErrorFound ||
13358 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13359 !Data[I].Type.get().isNull())) ||
13360 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13361 if (ErrorFound)
13362 continue;
13363 Data[I].Range.Begin = Begin.get();
13364 Data[I].Range.End = End.get();
13365 Data[I].Range.Step = Step.get();
13366 Data[I].AssignLoc = E->getAssignLoc(I);
13367 Data[I].ColonLoc = E->getColonLoc(I);
13368 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13369 NeedToRebuild =
13370 NeedToRebuild ||
13371 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13372 D->getType().getTypePtrOrNull()) ||
13373 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13374 Range.Step != Data[I].Range.Step;
13375 }
13376 if (ErrorFound)
13377 return ExprError();
13378 if (!NeedToRebuild)
13379 return E;
13380
13381 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13382 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13383 if (!Res.isUsable())
13384 return Res;
13385 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13386 for (unsigned I = 0; I < NumIterators; ++I)
13387 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13388 IE->getIteratorDecl(I));
13389 return Res;
13390}
13391
13392template<typename Derived>
13393ExprResult
13394TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13395 // Transform the callee.
13396 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13397 if (Callee.isInvalid())
13398 return ExprError();
13399
13400 // Transform arguments.
13401 bool ArgChanged = false;
13402 SmallVector<Expr*, 8> Args;
13403 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13404 &ArgChanged))
13405 return ExprError();
13406
13407 if (!getDerived().AlwaysRebuild() &&
13408 Callee.get() == E->getCallee() &&
13409 !ArgChanged)
13410 return SemaRef.MaybeBindToTemporary(E);
13411
13412 // FIXME: Wrong source location information for the '('.
13413 SourceLocation FakeLParenLoc
13414 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13415
13416 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13417 if (E->hasStoredFPFeatures()) {
13418 FPOptionsOverride NewOverrides = E->getFPFeatures();
13419 getSema().CurFPFeatures =
13420 NewOverrides.applyOverrides(getSema().getLangOpts());
13421 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13422 }
13423
13424 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13425 Args,
13426 E->getRParenLoc());
13427}
13428
13429template<typename Derived>
13430ExprResult
13431TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13432 ExprResult Base = getDerived().TransformExpr(E->getBase());
13433 if (Base.isInvalid())
13434 return ExprError();
13435
13436 NestedNameSpecifierLoc QualifierLoc;
13437 if (E->hasQualifier()) {
13438 QualifierLoc
13439 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13440
13441 if (!QualifierLoc)
13442 return ExprError();
13443 }
13444 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13445
13446 ValueDecl *Member
13447 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13448 E->getMemberDecl()));
13449 if (!Member)
13450 return ExprError();
13451
13452 NamedDecl *FoundDecl = E->getFoundDecl();
13453 if (FoundDecl == E->getMemberDecl()) {
13454 FoundDecl = Member;
13455 } else {
13456 FoundDecl = cast_or_null<NamedDecl>(
13457 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13458 if (!FoundDecl)
13459 return ExprError();
13460 }
13461
13462 if (!getDerived().AlwaysRebuild() &&
13463 Base.get() == E->getBase() &&
13464 QualifierLoc == E->getQualifierLoc() &&
13465 Member == E->getMemberDecl() &&
13466 FoundDecl == E->getFoundDecl() &&
13467 !E->hasExplicitTemplateArgs()) {
13468
13469 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13470 // for Openmp where the field need to be privatizized in the case.
13471 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13472 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13473 cast<ValueDecl>(Val: Member)))) {
13474 // Mark it referenced in the new context regardless.
13475 // FIXME: this is a bit instantiation-specific.
13476 SemaRef.MarkMemberReferenced(E);
13477 return E;
13478 }
13479 }
13480
13481 TemplateArgumentListInfo TransArgs;
13482 if (E->hasExplicitTemplateArgs()) {
13483 TransArgs.setLAngleLoc(E->getLAngleLoc());
13484 TransArgs.setRAngleLoc(E->getRAngleLoc());
13485 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13486 E->getNumTemplateArgs(),
13487 TransArgs))
13488 return ExprError();
13489 }
13490
13491 // FIXME: Bogus source location for the operator
13492 SourceLocation FakeOperatorLoc =
13493 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13494
13495 // FIXME: to do this check properly, we will need to preserve the
13496 // first-qualifier-in-scope here, just in case we had a dependent
13497 // base (and therefore couldn't do the check) and a
13498 // nested-name-qualifier (and therefore could do the lookup).
13499 NamedDecl *FirstQualifierInScope = nullptr;
13500 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13501 if (MemberNameInfo.getName()) {
13502 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13503 if (!MemberNameInfo.getName())
13504 return ExprError();
13505 }
13506
13507 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13508 E->isArrow(),
13509 QualifierLoc,
13510 TemplateKWLoc,
13511 MemberNameInfo,
13512 Member,
13513 FoundDecl,
13514 (E->hasExplicitTemplateArgs()
13515 ? &TransArgs : nullptr),
13516 FirstQualifierInScope);
13517}
13518
13519template<typename Derived>
13520ExprResult
13521TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13522 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13523 if (LHS.isInvalid())
13524 return ExprError();
13525
13526 ExprResult RHS =
13527 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13528 if (RHS.isInvalid())
13529 return ExprError();
13530
13531 if (!getDerived().AlwaysRebuild() &&
13532 LHS.get() == E->getLHS() &&
13533 RHS.get() == E->getRHS())
13534 return E;
13535
13536 if (E->isCompoundAssignmentOp())
13537 // FPFeatures has already been established from trailing storage
13538 return getDerived().RebuildBinaryOperator(
13539 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13540 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13541 FPOptionsOverride NewOverrides(E->getFPFeatures());
13542 getSema().CurFPFeatures =
13543 NewOverrides.applyOverrides(getSema().getLangOpts());
13544 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13545 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13546 LHS.get(), RHS.get());
13547}
13548
13549template <typename Derived>
13550ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13551 CXXRewrittenBinaryOperator *E) {
13552 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13553
13554 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13555 if (LHS.isInvalid())
13556 return ExprError();
13557
13558 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13559 if (RHS.isInvalid())
13560 return ExprError();
13561
13562 // Extract the already-resolved callee declarations so that we can restrict
13563 // ourselves to using them as the unqualified lookup results when rebuilding.
13564 UnresolvedSet<2> UnqualLookups;
13565 bool ChangedAnyLookups = false;
13566 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13567 const_cast<Expr *>(Decomp.InnerBinOp)};
13568 for (Expr *PossibleBinOp : PossibleBinOps) {
13569 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13570 if (!Op)
13571 continue;
13572 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13573 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13574 continue;
13575
13576 // Transform the callee in case we built a call to a local extern
13577 // declaration.
13578 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13579 E->getOperatorLoc(), Callee->getFoundDecl()));
13580 if (!Found)
13581 return ExprError();
13582 if (Found != Callee->getFoundDecl())
13583 ChangedAnyLookups = true;
13584 UnqualLookups.addDecl(D: Found);
13585 }
13586
13587 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13588 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13589 // Mark all functions used in the rewrite as referenced. Note that when
13590 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13591 // function calls, and/or there might be a user-defined conversion sequence
13592 // applied to the operands of the <.
13593 // FIXME: this is a bit instantiation-specific.
13594 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13595 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13596 return E;
13597 }
13598
13599 return getDerived().RebuildCXXRewrittenBinaryOperator(
13600 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13601}
13602
13603template<typename Derived>
13604ExprResult
13605TreeTransform<Derived>::TransformCompoundAssignOperator(
13606 CompoundAssignOperator *E) {
13607 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13608 FPOptionsOverride NewOverrides(E->getFPFeatures());
13609 getSema().CurFPFeatures =
13610 NewOverrides.applyOverrides(getSema().getLangOpts());
13611 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13612 return getDerived().TransformBinaryOperator(E);
13613}
13614
13615template<typename Derived>
13616ExprResult TreeTransform<Derived>::
13617TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13618 // Just rebuild the common and RHS expressions and see whether we
13619 // get any changes.
13620
13621 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13622 if (commonExpr.isInvalid())
13623 return ExprError();
13624
13625 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13626 if (rhs.isInvalid())
13627 return ExprError();
13628
13629 if (!getDerived().AlwaysRebuild() &&
13630 commonExpr.get() == e->getCommon() &&
13631 rhs.get() == e->getFalseExpr())
13632 return e;
13633
13634 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13635 e->getQuestionLoc(),
13636 nullptr,
13637 e->getColonLoc(),
13638 rhs.get());
13639}
13640
13641template<typename Derived>
13642ExprResult
13643TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13644 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13645 if (Cond.isInvalid())
13646 return ExprError();
13647
13648 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13649 if (LHS.isInvalid())
13650 return ExprError();
13651
13652 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13653 if (RHS.isInvalid())
13654 return ExprError();
13655
13656 if (!getDerived().AlwaysRebuild() &&
13657 Cond.get() == E->getCond() &&
13658 LHS.get() == E->getLHS() &&
13659 RHS.get() == E->getRHS())
13660 return E;
13661
13662 return getDerived().RebuildConditionalOperator(Cond.get(),
13663 E->getQuestionLoc(),
13664 LHS.get(),
13665 E->getColonLoc(),
13666 RHS.get());
13667}
13668
13669template<typename Derived>
13670ExprResult
13671TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13672 // Implicit casts are eliminated during transformation, since they
13673 // will be recomputed by semantic analysis after transformation.
13674 return getDerived().TransformExpr(E->getSubExprAsWritten());
13675}
13676
13677template<typename Derived>
13678ExprResult
13679TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13680 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13681 if (!Type)
13682 return ExprError();
13683
13684 ExprResult SubExpr
13685 = getDerived().TransformExpr(E->getSubExprAsWritten());
13686 if (SubExpr.isInvalid())
13687 return ExprError();
13688
13689 if (!getDerived().AlwaysRebuild() &&
13690 Type == E->getTypeInfoAsWritten() &&
13691 SubExpr.get() == E->getSubExpr())
13692 return E;
13693
13694 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13695 Type,
13696 E->getRParenLoc(),
13697 SubExpr.get());
13698}
13699
13700template<typename Derived>
13701ExprResult
13702TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13703 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13704 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13705 if (!NewT)
13706 return ExprError();
13707
13708 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13709 if (Init.isInvalid())
13710 return ExprError();
13711
13712 if (!getDerived().AlwaysRebuild() &&
13713 OldT == NewT &&
13714 Init.get() == E->getInitializer())
13715 return SemaRef.MaybeBindToTemporary(E);
13716
13717 // Note: the expression type doesn't necessarily match the
13718 // type-as-written, but that's okay, because it should always be
13719 // derivable from the initializer.
13720
13721 return getDerived().RebuildCompoundLiteralExpr(
13722 E->getLParenLoc(), NewT,
13723 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13724}
13725
13726template<typename Derived>
13727ExprResult
13728TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13729 ExprResult Base = getDerived().TransformExpr(E->getBase());
13730 if (Base.isInvalid())
13731 return ExprError();
13732
13733 if (!getDerived().AlwaysRebuild() &&
13734 Base.get() == E->getBase())
13735 return E;
13736
13737 // FIXME: Bad source location
13738 SourceLocation FakeOperatorLoc =
13739 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
13740 return getDerived().RebuildExtVectorElementExpr(
13741 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13742 E->getAccessor());
13743}
13744
13745template<typename Derived>
13746ExprResult
13747TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13748 if (InitListExpr *Syntactic = E->getSyntacticForm())
13749 E = Syntactic;
13750
13751 bool InitChanged = false;
13752
13753 EnterExpressionEvaluationContext Context(
13754 getSema(), EnterExpressionEvaluationContext::InitList);
13755
13756 SmallVector<Expr*, 4> Inits;
13757 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13758 Inits, &InitChanged))
13759 return ExprError();
13760
13761 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13762 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13763 // in some cases. We can't reuse it in general, because the syntactic and
13764 // semantic forms are linked, and we can't know that semantic form will
13765 // match even if the syntactic form does.
13766 }
13767
13768 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13769 E->getRBraceLoc());
13770}
13771
13772template<typename Derived>
13773ExprResult
13774TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13775 Designation Desig;
13776
13777 // transform the initializer value
13778 ExprResult Init = getDerived().TransformExpr(E->getInit());
13779 if (Init.isInvalid())
13780 return ExprError();
13781
13782 // transform the designators.
13783 SmallVector<Expr*, 4> ArrayExprs;
13784 bool ExprChanged = false;
13785 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13786 if (D.isFieldDesignator()) {
13787 if (D.getFieldDecl()) {
13788 FieldDecl *Field = cast_or_null<FieldDecl>(
13789 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13790 if (Field != D.getFieldDecl())
13791 // Rebuild the expression when the transformed FieldDecl is
13792 // different to the already assigned FieldDecl.
13793 ExprChanged = true;
13794 if (Field->isAnonymousStructOrUnion())
13795 continue;
13796 } else {
13797 // Ensure that the designator expression is rebuilt when there isn't
13798 // a resolved FieldDecl in the designator as we don't want to assign
13799 // a FieldDecl to a pattern designator that will be instantiated again.
13800 ExprChanged = true;
13801 }
13802 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
13803 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
13804 continue;
13805 }
13806
13807 if (D.isArrayDesignator()) {
13808 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13809 if (Index.isInvalid())
13810 return ExprError();
13811
13812 Desig.AddDesignator(
13813 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
13814
13815 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
13816 ArrayExprs.push_back(Elt: Index.get());
13817 continue;
13818 }
13819
13820 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13821 ExprResult Start
13822 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13823 if (Start.isInvalid())
13824 return ExprError();
13825
13826 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13827 if (End.isInvalid())
13828 return ExprError();
13829
13830 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
13831 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
13832
13833 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13834 End.get() != E->getArrayRangeEnd(D);
13835
13836 ArrayExprs.push_back(Elt: Start.get());
13837 ArrayExprs.push_back(Elt: End.get());
13838 }
13839
13840 if (!getDerived().AlwaysRebuild() &&
13841 Init.get() == E->getInit() &&
13842 !ExprChanged)
13843 return E;
13844
13845 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13846 E->getEqualOrColonLoc(),
13847 E->usesGNUSyntax(), Init.get());
13848}
13849
13850// Seems that if TransformInitListExpr() only works on the syntactic form of an
13851// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13852template<typename Derived>
13853ExprResult
13854TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13855 DesignatedInitUpdateExpr *E) {
13856 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13857 "initializer");
13858 return ExprError();
13859}
13860
13861template<typename Derived>
13862ExprResult
13863TreeTransform<Derived>::TransformNoInitExpr(
13864 NoInitExpr *E) {
13865 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13866 return ExprError();
13867}
13868
13869template<typename Derived>
13870ExprResult
13871TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13872 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13873 return ExprError();
13874}
13875
13876template<typename Derived>
13877ExprResult
13878TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13879 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13880 return ExprError();
13881}
13882
13883template<typename Derived>
13884ExprResult
13885TreeTransform<Derived>::TransformImplicitValueInitExpr(
13886 ImplicitValueInitExpr *E) {
13887 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13888
13889 // FIXME: Will we ever have proper type location here? Will we actually
13890 // need to transform the type?
13891 QualType T = getDerived().TransformType(E->getType());
13892 if (T.isNull())
13893 return ExprError();
13894
13895 if (!getDerived().AlwaysRebuild() &&
13896 T == E->getType())
13897 return E;
13898
13899 return getDerived().RebuildImplicitValueInitExpr(T);
13900}
13901
13902template<typename Derived>
13903ExprResult
13904TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13905 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13906 if (!TInfo)
13907 return ExprError();
13908
13909 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13910 if (SubExpr.isInvalid())
13911 return ExprError();
13912
13913 if (!getDerived().AlwaysRebuild() &&
13914 TInfo == E->getWrittenTypeInfo() &&
13915 SubExpr.get() == E->getSubExpr())
13916 return E;
13917
13918 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13919 TInfo, E->getRParenLoc());
13920}
13921
13922template<typename Derived>
13923ExprResult
13924TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13925 bool ArgumentChanged = false;
13926 SmallVector<Expr*, 4> Inits;
13927 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
13928 ArgChanged: &ArgumentChanged))
13929 return ExprError();
13930
13931 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13932 Inits,
13933 E->getRParenLoc());
13934}
13935
13936/// Transform an address-of-label expression.
13937///
13938/// By default, the transformation of an address-of-label expression always
13939/// rebuilds the expression, so that the label identifier can be resolved to
13940/// the corresponding label statement by semantic analysis.
13941template<typename Derived>
13942ExprResult
13943TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13944 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13945 E->getLabel());
13946 if (!LD)
13947 return ExprError();
13948
13949 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13950 cast<LabelDecl>(Val: LD));
13951}
13952
13953template<typename Derived>
13954ExprResult
13955TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13956 SemaRef.ActOnStartStmtExpr();
13957 StmtResult SubStmt
13958 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13959 if (SubStmt.isInvalid()) {
13960 SemaRef.ActOnStmtExprError();
13961 return ExprError();
13962 }
13963
13964 unsigned OldDepth = E->getTemplateDepth();
13965 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13966
13967 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13968 SubStmt.get() == E->getSubStmt()) {
13969 // Calling this an 'error' is unintuitive, but it does the right thing.
13970 SemaRef.ActOnStmtExprError();
13971 return SemaRef.MaybeBindToTemporary(E);
13972 }
13973
13974 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13975 E->getRParenLoc(), NewDepth);
13976}
13977
13978template<typename Derived>
13979ExprResult
13980TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13981 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13982 if (Cond.isInvalid())
13983 return ExprError();
13984
13985 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13986 if (LHS.isInvalid())
13987 return ExprError();
13988
13989 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13990 if (RHS.isInvalid())
13991 return ExprError();
13992
13993 if (!getDerived().AlwaysRebuild() &&
13994 Cond.get() == E->getCond() &&
13995 LHS.get() == E->getLHS() &&
13996 RHS.get() == E->getRHS())
13997 return E;
13998
13999 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14000 Cond.get(), LHS.get(), RHS.get(),
14001 E->getRParenLoc());
14002}
14003
14004template<typename Derived>
14005ExprResult
14006TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14007 return E;
14008}
14009
14010template<typename Derived>
14011ExprResult
14012TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14013 switch (E->getOperator()) {
14014 case OO_New:
14015 case OO_Delete:
14016 case OO_Array_New:
14017 case OO_Array_Delete:
14018 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14019
14020 case OO_Subscript:
14021 case OO_Call: {
14022 // This is a call to an object's operator().
14023 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14024
14025 // Transform the object itself.
14026 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14027 if (Object.isInvalid())
14028 return ExprError();
14029
14030 // FIXME: Poor location information
14031 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
14032 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
14033
14034 // Transform the call arguments.
14035 SmallVector<Expr*, 8> Args;
14036 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14037 Args))
14038 return ExprError();
14039
14040 if (E->getOperator() == OO_Subscript)
14041 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14042 Args, E->getEndLoc());
14043
14044 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14045 E->getEndLoc());
14046 }
14047
14048#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14049 case OO_##Name: \
14050 break;
14051
14052#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14053#include "clang/Basic/OperatorKinds.def"
14054
14055 case OO_Conditional:
14056 llvm_unreachable("conditional operator is not actually overloadable");
14057
14058 case OO_None:
14059 case NUM_OVERLOADED_OPERATORS:
14060 llvm_unreachable("not an overloaded operator?");
14061 }
14062
14063 ExprResult First;
14064 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14065 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14066 else
14067 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14068 if (First.isInvalid())
14069 return ExprError();
14070
14071 ExprResult Second;
14072 if (E->getNumArgs() == 2) {
14073 Second =
14074 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14075 if (Second.isInvalid())
14076 return ExprError();
14077 }
14078
14079 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14080 FPOptionsOverride NewOverrides(E->getFPFeatures());
14081 getSema().CurFPFeatures =
14082 NewOverrides.applyOverrides(getSema().getLangOpts());
14083 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14084
14085 Expr *Callee = E->getCallee();
14086 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14087 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14088 Sema::LookupOrdinaryName);
14089 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14090 return ExprError();
14091
14092 return getDerived().RebuildCXXOperatorCallExpr(
14093 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14094 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14095 }
14096
14097 UnresolvedSet<1> Functions;
14098 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14099 Callee = ICE->getSubExprAsWritten();
14100 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14101 ValueDecl *VD = cast_or_null<ValueDecl>(
14102 getDerived().TransformDecl(DR->getLocation(), DR));
14103 if (!VD)
14104 return ExprError();
14105
14106 if (!isa<CXXMethodDecl>(Val: VD))
14107 Functions.addDecl(D: VD);
14108
14109 return getDerived().RebuildCXXOperatorCallExpr(
14110 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14111 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14112}
14113
14114template<typename Derived>
14115ExprResult
14116TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14117 return getDerived().TransformCallExpr(E);
14118}
14119
14120template <typename Derived>
14121ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14122 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14123 getSema().CurContext != E->getParentContext();
14124
14125 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14126 return E;
14127
14128 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14129 E->getBeginLoc(), E->getEndLoc(),
14130 getSema().CurContext);
14131}
14132
14133template <typename Derived>
14134ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14135 return E;
14136}
14137
14138template<typename Derived>
14139ExprResult
14140TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14141 // Transform the callee.
14142 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14143 if (Callee.isInvalid())
14144 return ExprError();
14145
14146 // Transform exec config.
14147 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14148 if (EC.isInvalid())
14149 return ExprError();
14150
14151 // Transform arguments.
14152 bool ArgChanged = false;
14153 SmallVector<Expr*, 8> Args;
14154 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14155 &ArgChanged))
14156 return ExprError();
14157
14158 if (!getDerived().AlwaysRebuild() &&
14159 Callee.get() == E->getCallee() &&
14160 !ArgChanged)
14161 return SemaRef.MaybeBindToTemporary(E);
14162
14163 // FIXME: Wrong source location information for the '('.
14164 SourceLocation FakeLParenLoc
14165 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14166 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14167 Args,
14168 E->getRParenLoc(), EC.get());
14169}
14170
14171template<typename Derived>
14172ExprResult
14173TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14174 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14175 if (!Type)
14176 return ExprError();
14177
14178 ExprResult SubExpr
14179 = getDerived().TransformExpr(E->getSubExprAsWritten());
14180 if (SubExpr.isInvalid())
14181 return ExprError();
14182
14183 if (!getDerived().AlwaysRebuild() &&
14184 Type == E->getTypeInfoAsWritten() &&
14185 SubExpr.get() == E->getSubExpr())
14186 return E;
14187 return getDerived().RebuildCXXNamedCastExpr(
14188 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14189 Type, E->getAngleBrackets().getEnd(),
14190 // FIXME. this should be '(' location
14191 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14192}
14193
14194template<typename Derived>
14195ExprResult
14196TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14197 TypeSourceInfo *TSI =
14198 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14199 if (!TSI)
14200 return ExprError();
14201
14202 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14203 if (Sub.isInvalid())
14204 return ExprError();
14205
14206 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14207 Sub.get(), BCE->getEndLoc());
14208}
14209
14210template<typename Derived>
14211ExprResult
14212TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14213 return getDerived().TransformCXXNamedCastExpr(E);
14214}
14215
14216template<typename Derived>
14217ExprResult
14218TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14219 return getDerived().TransformCXXNamedCastExpr(E);
14220}
14221
14222template<typename Derived>
14223ExprResult
14224TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14225 CXXReinterpretCastExpr *E) {
14226 return getDerived().TransformCXXNamedCastExpr(E);
14227}
14228
14229template<typename Derived>
14230ExprResult
14231TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14232 return getDerived().TransformCXXNamedCastExpr(E);
14233}
14234
14235template<typename Derived>
14236ExprResult
14237TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14238 return getDerived().TransformCXXNamedCastExpr(E);
14239}
14240
14241template<typename Derived>
14242ExprResult
14243TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14244 CXXFunctionalCastExpr *E) {
14245 TypeSourceInfo *Type =
14246 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14247 if (!Type)
14248 return ExprError();
14249
14250 ExprResult SubExpr
14251 = getDerived().TransformExpr(E->getSubExprAsWritten());
14252 if (SubExpr.isInvalid())
14253 return ExprError();
14254
14255 if (!getDerived().AlwaysRebuild() &&
14256 Type == E->getTypeInfoAsWritten() &&
14257 SubExpr.get() == E->getSubExpr())
14258 return E;
14259
14260 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14261 E->getLParenLoc(),
14262 SubExpr.get(),
14263 E->getRParenLoc(),
14264 E->isListInitialization());
14265}
14266
14267template<typename Derived>
14268ExprResult
14269TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14270 if (E->isTypeOperand()) {
14271 TypeSourceInfo *TInfo
14272 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14273 if (!TInfo)
14274 return ExprError();
14275
14276 if (!getDerived().AlwaysRebuild() &&
14277 TInfo == E->getTypeOperandSourceInfo())
14278 return E;
14279
14280 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14281 TInfo, E->getEndLoc());
14282 }
14283
14284 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14285 // type. We must not unilaterally enter unevaluated context here, as then
14286 // semantic processing can re-transform an already transformed operand.
14287 Expr *Op = E->getExprOperand();
14288 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14289 if (E->isGLValue())
14290 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14291 if (cast<CXXRecordDecl>(Val: RecordT->getDecl())->isPolymorphic())
14292 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14293
14294 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14295 Sema::ReuseLambdaContextDecl);
14296
14297 ExprResult SubExpr = getDerived().TransformExpr(Op);
14298 if (SubExpr.isInvalid())
14299 return ExprError();
14300
14301 if (!getDerived().AlwaysRebuild() &&
14302 SubExpr.get() == E->getExprOperand())
14303 return E;
14304
14305 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14306 SubExpr.get(), E->getEndLoc());
14307}
14308
14309template<typename Derived>
14310ExprResult
14311TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14312 if (E->isTypeOperand()) {
14313 TypeSourceInfo *TInfo
14314 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14315 if (!TInfo)
14316 return ExprError();
14317
14318 if (!getDerived().AlwaysRebuild() &&
14319 TInfo == E->getTypeOperandSourceInfo())
14320 return E;
14321
14322 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14323 TInfo, E->getEndLoc());
14324 }
14325
14326 EnterExpressionEvaluationContext Unevaluated(
14327 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14328
14329 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14330 if (SubExpr.isInvalid())
14331 return ExprError();
14332
14333 if (!getDerived().AlwaysRebuild() &&
14334 SubExpr.get() == E->getExprOperand())
14335 return E;
14336
14337 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14338 SubExpr.get(), E->getEndLoc());
14339}
14340
14341template<typename Derived>
14342ExprResult
14343TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14344 return E;
14345}
14346
14347template<typename Derived>
14348ExprResult
14349TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14350 CXXNullPtrLiteralExpr *E) {
14351 return E;
14352}
14353
14354template<typename Derived>
14355ExprResult
14356TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14357
14358 // In lambdas, the qualifiers of the type depends of where in
14359 // the call operator `this` appear, and we do not have a good way to
14360 // rebuild this information, so we transform the type.
14361 //
14362 // In other contexts, the type of `this` may be overrided
14363 // for type deduction, so we need to recompute it.
14364 //
14365 // Always recompute the type if we're in the body of a lambda, and
14366 // 'this' is dependent on a lambda's explicit object parameter.
14367 QualType T = [&]() {
14368 auto &S = getSema();
14369 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14370 return S.getCurrentThisType();
14371 if (S.getCurLambda())
14372 return getDerived().TransformType(E->getType());
14373 return S.getCurrentThisType();
14374 }();
14375
14376 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14377 // Mark it referenced in the new context regardless.
14378 // FIXME: this is a bit instantiation-specific.
14379 getSema().MarkThisReferenced(E);
14380 return E;
14381 }
14382
14383 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14384}
14385
14386template<typename Derived>
14387ExprResult
14388TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14389 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14390 if (SubExpr.isInvalid())
14391 return ExprError();
14392
14393 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14394
14395 if (!getDerived().AlwaysRebuild() &&
14396 SubExpr.get() == E->getSubExpr())
14397 return E;
14398
14399 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14400 E->isThrownVariableInScope());
14401}
14402
14403template<typename Derived>
14404ExprResult
14405TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14406 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14407 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14408 if (!Param)
14409 return ExprError();
14410
14411 ExprResult InitRes;
14412 if (E->hasRewrittenInit()) {
14413 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14414 if (InitRes.isInvalid())
14415 return ExprError();
14416 }
14417
14418 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14419 E->getUsedContext() == SemaRef.CurContext &&
14420 InitRes.get() == E->getRewrittenExpr())
14421 return E;
14422
14423 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14424 InitRes.get());
14425}
14426
14427template<typename Derived>
14428ExprResult
14429TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14430 FieldDecl *Field = cast_or_null<FieldDecl>(
14431 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14432 if (!Field)
14433 return ExprError();
14434
14435 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14436 E->getUsedContext() == SemaRef.CurContext)
14437 return E;
14438
14439 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14440}
14441
14442template<typename Derived>
14443ExprResult
14444TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14445 CXXScalarValueInitExpr *E) {
14446 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14447 if (!T)
14448 return ExprError();
14449
14450 if (!getDerived().AlwaysRebuild() &&
14451 T == E->getTypeSourceInfo())
14452 return E;
14453
14454 return getDerived().RebuildCXXScalarValueInitExpr(T,
14455 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14456 E->getRParenLoc());
14457}
14458
14459template<typename Derived>
14460ExprResult
14461TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14462 // Transform the type that we're allocating
14463 TypeSourceInfo *AllocTypeInfo =
14464 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14465 if (!AllocTypeInfo)
14466 return ExprError();
14467
14468 // Transform the size of the array we're allocating (if any).
14469 std::optional<Expr *> ArraySize;
14470 if (E->isArray()) {
14471 ExprResult NewArraySize;
14472 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14473 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14474 if (NewArraySize.isInvalid())
14475 return ExprError();
14476 }
14477 ArraySize = NewArraySize.get();
14478 }
14479
14480 // Transform the placement arguments (if any).
14481 bool ArgumentChanged = false;
14482 SmallVector<Expr*, 8> PlacementArgs;
14483 if (getDerived().TransformExprs(E->getPlacementArgs(),
14484 E->getNumPlacementArgs(), true,
14485 PlacementArgs, &ArgumentChanged))
14486 return ExprError();
14487
14488 // Transform the initializer (if any).
14489 Expr *OldInit = E->getInitializer();
14490 ExprResult NewInit;
14491 if (OldInit)
14492 NewInit = getDerived().TransformInitializer(OldInit, true);
14493 if (NewInit.isInvalid())
14494 return ExprError();
14495
14496 // Transform new operator and delete operator.
14497 FunctionDecl *OperatorNew = nullptr;
14498 if (E->getOperatorNew()) {
14499 OperatorNew = cast_or_null<FunctionDecl>(
14500 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14501 if (!OperatorNew)
14502 return ExprError();
14503 }
14504
14505 FunctionDecl *OperatorDelete = nullptr;
14506 if (E->getOperatorDelete()) {
14507 OperatorDelete = cast_or_null<FunctionDecl>(
14508 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14509 if (!OperatorDelete)
14510 return ExprError();
14511 }
14512
14513 if (!getDerived().AlwaysRebuild() &&
14514 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14515 ArraySize == E->getArraySize() &&
14516 NewInit.get() == OldInit &&
14517 OperatorNew == E->getOperatorNew() &&
14518 OperatorDelete == E->getOperatorDelete() &&
14519 !ArgumentChanged) {
14520 // Mark any declarations we need as referenced.
14521 // FIXME: instantiation-specific.
14522 if (OperatorNew)
14523 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14524 if (OperatorDelete)
14525 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14526
14527 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14528 QualType ElementType
14529 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14530 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14531 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: RecordT->getDecl());
14532 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
14533 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14534 }
14535 }
14536 }
14537
14538 return E;
14539 }
14540
14541 QualType AllocType = AllocTypeInfo->getType();
14542 if (!ArraySize) {
14543 // If no array size was specified, but the new expression was
14544 // instantiated with an array type (e.g., "new T" where T is
14545 // instantiated with "int[4]"), extract the outer bound from the
14546 // array type as our array size. We do this with constant and
14547 // dependently-sized array types.
14548 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14549 if (!ArrayT) {
14550 // Do nothing
14551 } else if (const ConstantArrayType *ConsArrayT
14552 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14553 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14554 type: SemaRef.Context.getSizeType(),
14555 /*FIXME:*/ l: E->getBeginLoc());
14556 AllocType = ConsArrayT->getElementType();
14557 } else if (const DependentSizedArrayType *DepArrayT
14558 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14559 if (DepArrayT->getSizeExpr()) {
14560 ArraySize = DepArrayT->getSizeExpr();
14561 AllocType = DepArrayT->getElementType();
14562 }
14563 }
14564 }
14565
14566 return getDerived().RebuildCXXNewExpr(
14567 E->getBeginLoc(), E->isGlobalNew(),
14568 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14569 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14570 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14571}
14572
14573template<typename Derived>
14574ExprResult
14575TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14576 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14577 if (Operand.isInvalid())
14578 return ExprError();
14579
14580 // Transform the delete operator, if known.
14581 FunctionDecl *OperatorDelete = nullptr;
14582 if (E->getOperatorDelete()) {
14583 OperatorDelete = cast_or_null<FunctionDecl>(
14584 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14585 if (!OperatorDelete)
14586 return ExprError();
14587 }
14588
14589 if (!getDerived().AlwaysRebuild() &&
14590 Operand.get() == E->getArgument() &&
14591 OperatorDelete == E->getOperatorDelete()) {
14592 // Mark any declarations we need as referenced.
14593 // FIXME: instantiation-specific.
14594 if (OperatorDelete)
14595 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14596
14597 if (!E->getArgument()->isTypeDependent()) {
14598 QualType Destroyed = SemaRef.Context.getBaseElementType(
14599 QT: E->getDestroyedType());
14600 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14601 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: DestroyedRec->getDecl());
14602 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14603 Func: SemaRef.LookupDestructor(Class: Record));
14604 }
14605 }
14606
14607 return E;
14608 }
14609
14610 return getDerived().RebuildCXXDeleteExpr(
14611 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14612}
14613
14614template<typename Derived>
14615ExprResult
14616TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14617 CXXPseudoDestructorExpr *E) {
14618 ExprResult Base = getDerived().TransformExpr(E->getBase());
14619 if (Base.isInvalid())
14620 return ExprError();
14621
14622 ParsedType ObjectTypePtr;
14623 bool MayBePseudoDestructor = false;
14624 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14625 OpLoc: E->getOperatorLoc(),
14626 OpKind: E->isArrow()? tok::arrow : tok::period,
14627 ObjectType&: ObjectTypePtr,
14628 MayBePseudoDestructor);
14629 if (Base.isInvalid())
14630 return ExprError();
14631
14632 QualType ObjectType = ObjectTypePtr.get();
14633 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14634 if (QualifierLoc) {
14635 QualifierLoc
14636 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14637 if (!QualifierLoc)
14638 return ExprError();
14639 }
14640 CXXScopeSpec SS;
14641 SS.Adopt(Other: QualifierLoc);
14642
14643 PseudoDestructorTypeStorage Destroyed;
14644 if (E->getDestroyedTypeInfo()) {
14645 TypeSourceInfo *DestroyedTypeInfo
14646 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14647 ObjectType, nullptr, SS);
14648 if (!DestroyedTypeInfo)
14649 return ExprError();
14650 Destroyed = DestroyedTypeInfo;
14651 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14652 // We aren't likely to be able to resolve the identifier down to a type
14653 // now anyway, so just retain the identifier.
14654 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14655 E->getDestroyedTypeLoc());
14656 } else {
14657 // Look for a destructor known with the given name.
14658 ParsedType T = SemaRef.getDestructorName(
14659 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14660 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14661 if (!T)
14662 return ExprError();
14663
14664 Destroyed
14665 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14666 Loc: E->getDestroyedTypeLoc());
14667 }
14668
14669 TypeSourceInfo *ScopeTypeInfo = nullptr;
14670 if (E->getScopeTypeInfo()) {
14671 CXXScopeSpec EmptySS;
14672 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14673 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14674 if (!ScopeTypeInfo)
14675 return ExprError();
14676 }
14677
14678 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14679 E->getOperatorLoc(),
14680 E->isArrow(),
14681 SS,
14682 ScopeTypeInfo,
14683 E->getColonColonLoc(),
14684 E->getTildeLoc(),
14685 Destroyed);
14686}
14687
14688template <typename Derived>
14689bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14690 bool RequiresADL,
14691 LookupResult &R) {
14692 // Transform all the decls.
14693 bool AllEmptyPacks = true;
14694 for (auto *OldD : Old->decls()) {
14695 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14696 if (!InstD) {
14697 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14698 // This can happen because of dependent hiding.
14699 if (isa<UsingShadowDecl>(Val: OldD))
14700 continue;
14701 else {
14702 R.clear();
14703 return true;
14704 }
14705 }
14706
14707 // Expand using pack declarations.
14708 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
14709 ArrayRef<NamedDecl*> Decls = SingleDecl;
14710 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
14711 Decls = UPD->expansions();
14712
14713 // Expand using declarations.
14714 for (auto *D : Decls) {
14715 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
14716 for (auto *SD : UD->shadows())
14717 R.addDecl(D: SD);
14718 } else {
14719 R.addDecl(D);
14720 }
14721 }
14722
14723 AllEmptyPacks &= Decls.empty();
14724 }
14725
14726 // C++ [temp.res]/8.4.2:
14727 // The program is ill-formed, no diagnostic required, if [...] lookup for
14728 // a name in the template definition found a using-declaration, but the
14729 // lookup in the corresponding scope in the instantiation odoes not find
14730 // any declarations because the using-declaration was a pack expansion and
14731 // the corresponding pack is empty
14732 if (AllEmptyPacks && !RequiresADL) {
14733 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14734 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
14735 return true;
14736 }
14737
14738 // Resolve a kind, but don't do any further analysis. If it's
14739 // ambiguous, the callee needs to deal with it.
14740 R.resolveKind();
14741
14742 if (Old->hasTemplateKeyword() && !R.empty()) {
14743 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14744 getSema().FilterAcceptableTemplateNames(R,
14745 /*AllowFunctionTemplates=*/true,
14746 /*AllowDependent=*/true);
14747 if (R.empty()) {
14748 // If a 'template' keyword was used, a lookup that finds only non-template
14749 // names is an error.
14750 getSema().Diag(R.getNameLoc(),
14751 diag::err_template_kw_refers_to_non_template)
14752 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14753 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14754 getSema().Diag(FoundDecl->getLocation(),
14755 diag::note_template_kw_refers_to_non_template)
14756 << R.getLookupName();
14757 return true;
14758 }
14759 }
14760
14761 return false;
14762}
14763
14764template <typename Derived>
14765ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14766 UnresolvedLookupExpr *Old) {
14767 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14768}
14769
14770template <typename Derived>
14771ExprResult
14772TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14773 bool IsAddressOfOperand) {
14774 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14775 Sema::LookupOrdinaryName);
14776
14777 // Transform the declaration set.
14778 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
14779 return ExprError();
14780
14781 // Rebuild the nested-name qualifier, if present.
14782 CXXScopeSpec SS;
14783 if (Old->getQualifierLoc()) {
14784 NestedNameSpecifierLoc QualifierLoc
14785 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14786 if (!QualifierLoc)
14787 return ExprError();
14788
14789 SS.Adopt(Other: QualifierLoc);
14790 }
14791
14792 if (Old->getNamingClass()) {
14793 CXXRecordDecl *NamingClass
14794 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14795 Old->getNameLoc(),
14796 Old->getNamingClass()));
14797 if (!NamingClass) {
14798 R.clear();
14799 return ExprError();
14800 }
14801
14802 R.setNamingClass(NamingClass);
14803 }
14804
14805 // Rebuild the template arguments, if any.
14806 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14807 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14808 if (Old->hasExplicitTemplateArgs() &&
14809 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14810 Old->getNumTemplateArgs(),
14811 TransArgs)) {
14812 R.clear();
14813 return ExprError();
14814 }
14815
14816 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14817 // a non-static data member is named in an unevaluated operand, or when
14818 // a member is named in a dependent class scope function template explicit
14819 // specialization that is neither declared static nor with an explicit object
14820 // parameter.
14821 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14822 return SemaRef.BuildPossibleImplicitMemberExpr(
14823 SS, TemplateKWLoc, R,
14824 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14825 /*S=*/S: nullptr);
14826
14827 // If we have neither explicit template arguments, nor the template keyword,
14828 // it's a normal declaration name or member reference.
14829 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14830 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14831
14832 // If we have template arguments, then rebuild the template-id expression.
14833 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14834 Old->requiresADL(), &TransArgs);
14835}
14836
14837template<typename Derived>
14838ExprResult
14839TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14840 bool ArgChanged = false;
14841 SmallVector<TypeSourceInfo *, 4> Args;
14842 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14843 TypeSourceInfo *From = E->getArg(I);
14844 TypeLoc FromTL = From->getTypeLoc();
14845 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14846 TypeLocBuilder TLB;
14847 TLB.reserve(Requested: FromTL.getFullDataSize());
14848 QualType To = getDerived().TransformType(TLB, FromTL);
14849 if (To.isNull())
14850 return ExprError();
14851
14852 if (To == From->getType())
14853 Args.push_back(Elt: From);
14854 else {
14855 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14856 ArgChanged = true;
14857 }
14858 continue;
14859 }
14860
14861 ArgChanged = true;
14862
14863 // We have a pack expansion. Instantiate it.
14864 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14865 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14866 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14867 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
14868
14869 // Determine whether the set of unexpanded parameter packs can and should
14870 // be expanded.
14871 bool Expand = true;
14872 bool RetainExpansion = false;
14873 UnsignedOrNone OrigNumExpansions =
14874 ExpansionTL.getTypePtr()->getNumExpansions();
14875 UnsignedOrNone NumExpansions = OrigNumExpansions;
14876 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14877 PatternTL.getSourceRange(),
14878 Unexpanded,
14879 Expand, RetainExpansion,
14880 NumExpansions))
14881 return ExprError();
14882
14883 if (!Expand) {
14884 // The transform has determined that we should perform a simple
14885 // transformation on the pack expansion, producing another pack
14886 // expansion.
14887 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
14888
14889 TypeLocBuilder TLB;
14890 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14891
14892 QualType To = getDerived().TransformType(TLB, PatternTL);
14893 if (To.isNull())
14894 return ExprError();
14895
14896 To = getDerived().RebuildPackExpansionType(To,
14897 PatternTL.getSourceRange(),
14898 ExpansionTL.getEllipsisLoc(),
14899 NumExpansions);
14900 if (To.isNull())
14901 return ExprError();
14902
14903 PackExpansionTypeLoc ToExpansionTL
14904 = TLB.push<PackExpansionTypeLoc>(T: To);
14905 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14906 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14907 continue;
14908 }
14909
14910 // Expand the pack expansion by substituting for each argument in the
14911 // pack(s).
14912 for (unsigned I = 0; I != *NumExpansions; ++I) {
14913 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
14914 TypeLocBuilder TLB;
14915 TLB.reserve(Requested: PatternTL.getFullDataSize());
14916 QualType To = getDerived().TransformType(TLB, PatternTL);
14917 if (To.isNull())
14918 return ExprError();
14919
14920 if (To->containsUnexpandedParameterPack()) {
14921 To = getDerived().RebuildPackExpansionType(To,
14922 PatternTL.getSourceRange(),
14923 ExpansionTL.getEllipsisLoc(),
14924 NumExpansions);
14925 if (To.isNull())
14926 return ExprError();
14927
14928 PackExpansionTypeLoc ToExpansionTL
14929 = TLB.push<PackExpansionTypeLoc>(T: To);
14930 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14931 }
14932
14933 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14934 }
14935
14936 if (!RetainExpansion)
14937 continue;
14938
14939 // If we're supposed to retain a pack expansion, do so by temporarily
14940 // forgetting the partially-substituted parameter pack.
14941 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14942
14943 TypeLocBuilder TLB;
14944 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14945
14946 QualType To = getDerived().TransformType(TLB, PatternTL);
14947 if (To.isNull())
14948 return ExprError();
14949
14950 To = getDerived().RebuildPackExpansionType(To,
14951 PatternTL.getSourceRange(),
14952 ExpansionTL.getEllipsisLoc(),
14953 NumExpansions);
14954 if (To.isNull())
14955 return ExprError();
14956
14957 PackExpansionTypeLoc ToExpansionTL
14958 = TLB.push<PackExpansionTypeLoc>(T: To);
14959 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14960 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14961 }
14962
14963 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14964 return E;
14965
14966 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14967 E->getEndLoc());
14968}
14969
14970template<typename Derived>
14971ExprResult
14972TreeTransform<Derived>::TransformConceptSpecializationExpr(
14973 ConceptSpecializationExpr *E) {
14974 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14975 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14976 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14977 Old->NumTemplateArgs, TransArgs))
14978 return ExprError();
14979
14980 return getDerived().RebuildConceptSpecializationExpr(
14981 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14982 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14983 &TransArgs);
14984}
14985
14986template<typename Derived>
14987ExprResult
14988TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14989 SmallVector<ParmVarDecl*, 4> TransParams;
14990 SmallVector<QualType, 4> TransParamTypes;
14991 Sema::ExtParameterInfoBuilder ExtParamInfos;
14992
14993 // C++2a [expr.prim.req]p2
14994 // Expressions appearing within a requirement-body are unevaluated operands.
14995 EnterExpressionEvaluationContext Ctx(
14996 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
14997 Sema::ReuseLambdaContextDecl);
14998
14999 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15000 C&: getSema().Context, DC: getSema().CurContext,
15001 StartLoc: E->getBody()->getBeginLoc());
15002
15003 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15004
15005 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15006 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15007 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15008
15009 for (ParmVarDecl *Param : TransParams)
15010 if (Param)
15011 Param->setDeclContext(Body);
15012
15013 // On failure to transform, TransformRequiresTypeParams returns an expression
15014 // in the event that the transformation of the type params failed in some way.
15015 // It is expected that this will result in a 'not satisfied' Requires clause
15016 // when instantiating.
15017 if (!TypeParamResult.isUnset())
15018 return TypeParamResult;
15019
15020 SmallVector<concepts::Requirement *, 4> TransReqs;
15021 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15022 TransReqs))
15023 return ExprError();
15024
15025 for (concepts::Requirement *Req : TransReqs) {
15026 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15027 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15028 ER->getReturnTypeRequirement()
15029 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15030 ->setDeclContext(Body);
15031 }
15032 }
15033 }
15034
15035 return getDerived().RebuildRequiresExpr(
15036 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15037 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15038}
15039
15040template<typename Derived>
15041bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15042 ArrayRef<concepts::Requirement *> Reqs,
15043 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15044 for (concepts::Requirement *Req : Reqs) {
15045 concepts::Requirement *TransReq = nullptr;
15046 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15047 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15048 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15049 TransReq = getDerived().TransformExprRequirement(ExprReq);
15050 else
15051 TransReq = getDerived().TransformNestedRequirement(
15052 cast<concepts::NestedRequirement>(Val: Req));
15053 if (!TransReq)
15054 return true;
15055 Transformed.push_back(Elt: TransReq);
15056 }
15057 return false;
15058}
15059
15060template<typename Derived>
15061concepts::TypeRequirement *
15062TreeTransform<Derived>::TransformTypeRequirement(
15063 concepts::TypeRequirement *Req) {
15064 if (Req->isSubstitutionFailure()) {
15065 if (getDerived().AlwaysRebuild())
15066 return getDerived().RebuildTypeRequirement(
15067 Req->getSubstitutionDiagnostic());
15068 return Req;
15069 }
15070 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15071 if (!TransType)
15072 return nullptr;
15073 return getDerived().RebuildTypeRequirement(TransType);
15074}
15075
15076template<typename Derived>
15077concepts::ExprRequirement *
15078TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15079 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15080 if (Req->isExprSubstitutionFailure())
15081 TransExpr = Req->getExprSubstitutionDiagnostic();
15082 else {
15083 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15084 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15085 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15086 if (TransExprRes.isInvalid())
15087 return nullptr;
15088 TransExpr = TransExprRes.get();
15089 }
15090
15091 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15092 const auto &RetReq = Req->getReturnTypeRequirement();
15093 if (RetReq.isEmpty())
15094 TransRetReq.emplace();
15095 else if (RetReq.isSubstitutionFailure())
15096 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15097 else if (RetReq.isTypeConstraint()) {
15098 TemplateParameterList *OrigTPL =
15099 RetReq.getTypeConstraintTemplateParameterList();
15100 TemplateParameterList *TPL =
15101 getDerived().TransformTemplateParameterList(OrigTPL);
15102 if (!TPL)
15103 return nullptr;
15104 TransRetReq.emplace(args&: TPL);
15105 }
15106 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15107 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15108 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15109 Req->getNoexceptLoc(),
15110 std::move(*TransRetReq));
15111 return getDerived().RebuildExprRequirement(
15112 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15113 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15114}
15115
15116template<typename Derived>
15117concepts::NestedRequirement *
15118TreeTransform<Derived>::TransformNestedRequirement(
15119 concepts::NestedRequirement *Req) {
15120 if (Req->hasInvalidConstraint()) {
15121 if (getDerived().AlwaysRebuild())
15122 return getDerived().RebuildNestedRequirement(
15123 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15124 return Req;
15125 }
15126 ExprResult TransConstraint =
15127 getDerived().TransformExpr(Req->getConstraintExpr());
15128 if (TransConstraint.isInvalid())
15129 return nullptr;
15130 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15131}
15132
15133template<typename Derived>
15134ExprResult
15135TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15136 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15137 if (!T)
15138 return ExprError();
15139
15140 if (!getDerived().AlwaysRebuild() &&
15141 T == E->getQueriedTypeSourceInfo())
15142 return E;
15143
15144 ExprResult SubExpr;
15145 {
15146 EnterExpressionEvaluationContext Unevaluated(
15147 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15148 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15149 if (SubExpr.isInvalid())
15150 return ExprError();
15151 }
15152
15153 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15154 SubExpr.get(), E->getEndLoc());
15155}
15156
15157template<typename Derived>
15158ExprResult
15159TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15160 ExprResult SubExpr;
15161 {
15162 EnterExpressionEvaluationContext Unevaluated(
15163 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15164 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15165 if (SubExpr.isInvalid())
15166 return ExprError();
15167
15168 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15169 return E;
15170 }
15171
15172 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15173 SubExpr.get(), E->getEndLoc());
15174}
15175
15176template <typename Derived>
15177ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15178 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15179 TypeSourceInfo **RecoveryTSI) {
15180 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15181 DRE, AddrTaken, RecoveryTSI);
15182
15183 // Propagate both errors and recovered types, which return ExprEmpty.
15184 if (!NewDRE.isUsable())
15185 return NewDRE;
15186
15187 // We got an expr, wrap it up in parens.
15188 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15189 return PE;
15190 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15191 PE->getRParen());
15192}
15193
15194template <typename Derived>
15195ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15196 DependentScopeDeclRefExpr *E) {
15197 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15198 nullptr);
15199}
15200
15201template <typename Derived>
15202ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15203 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15204 TypeSourceInfo **RecoveryTSI) {
15205 assert(E->getQualifierLoc());
15206 NestedNameSpecifierLoc QualifierLoc =
15207 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15208 if (!QualifierLoc)
15209 return ExprError();
15210 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15211
15212 // TODO: If this is a conversion-function-id, verify that the
15213 // destination type name (if present) resolves the same way after
15214 // instantiation as it did in the local scope.
15215
15216 DeclarationNameInfo NameInfo =
15217 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15218 if (!NameInfo.getName())
15219 return ExprError();
15220
15221 if (!E->hasExplicitTemplateArgs()) {
15222 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15223 // Note: it is sufficient to compare the Name component of NameInfo:
15224 // if name has not changed, DNLoc has not changed either.
15225 NameInfo.getName() == E->getDeclName())
15226 return E;
15227
15228 return getDerived().RebuildDependentScopeDeclRefExpr(
15229 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15230 IsAddressOfOperand, RecoveryTSI);
15231 }
15232
15233 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15234 if (getDerived().TransformTemplateArguments(
15235 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15236 return ExprError();
15237
15238 return getDerived().RebuildDependentScopeDeclRefExpr(
15239 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15240 RecoveryTSI);
15241}
15242
15243template<typename Derived>
15244ExprResult
15245TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15246 // CXXConstructExprs other than for list-initialization and
15247 // CXXTemporaryObjectExpr are always implicit, so when we have
15248 // a 1-argument construction we just transform that argument.
15249 if (getDerived().AllowSkippingCXXConstructExpr() &&
15250 ((E->getNumArgs() == 1 ||
15251 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15252 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15253 !E->isListInitialization()))
15254 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15255 /*DirectInit*/ false);
15256
15257 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15258
15259 QualType T = getDerived().TransformType(E->getType());
15260 if (T.isNull())
15261 return ExprError();
15262
15263 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15264 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15265 if (!Constructor)
15266 return ExprError();
15267
15268 bool ArgumentChanged = false;
15269 SmallVector<Expr*, 8> Args;
15270 {
15271 EnterExpressionEvaluationContext Context(
15272 getSema(), EnterExpressionEvaluationContext::InitList,
15273 E->isListInitialization());
15274 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15275 &ArgumentChanged))
15276 return ExprError();
15277 }
15278
15279 if (!getDerived().AlwaysRebuild() &&
15280 T == E->getType() &&
15281 Constructor == E->getConstructor() &&
15282 !ArgumentChanged) {
15283 // Mark the constructor as referenced.
15284 // FIXME: Instantiation-specific
15285 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15286 return E;
15287 }
15288
15289 return getDerived().RebuildCXXConstructExpr(
15290 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15291 E->hadMultipleCandidates(), E->isListInitialization(),
15292 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15293 E->getConstructionKind(), E->getParenOrBraceRange());
15294}
15295
15296template<typename Derived>
15297ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15298 CXXInheritedCtorInitExpr *E) {
15299 QualType T = getDerived().TransformType(E->getType());
15300 if (T.isNull())
15301 return ExprError();
15302
15303 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15304 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15305 if (!Constructor)
15306 return ExprError();
15307
15308 if (!getDerived().AlwaysRebuild() &&
15309 T == E->getType() &&
15310 Constructor == E->getConstructor()) {
15311 // Mark the constructor as referenced.
15312 // FIXME: Instantiation-specific
15313 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15314 return E;
15315 }
15316
15317 return getDerived().RebuildCXXInheritedCtorInitExpr(
15318 T, E->getLocation(), Constructor,
15319 E->constructsVBase(), E->inheritedFromVBase());
15320}
15321
15322/// Transform a C++ temporary-binding expression.
15323///
15324/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15325/// transform the subexpression and return that.
15326template<typename Derived>
15327ExprResult
15328TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15329 if (auto *Dtor = E->getTemporary()->getDestructor())
15330 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15331 Func: const_cast<CXXDestructorDecl *>(Dtor));
15332 return getDerived().TransformExpr(E->getSubExpr());
15333}
15334
15335/// Transform a C++ expression that contains cleanups that should
15336/// be run after the expression is evaluated.
15337///
15338/// Since ExprWithCleanups nodes are implicitly generated, we
15339/// just transform the subexpression and return that.
15340template<typename Derived>
15341ExprResult
15342TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15343 return getDerived().TransformExpr(E->getSubExpr());
15344}
15345
15346template<typename Derived>
15347ExprResult
15348TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15349 CXXTemporaryObjectExpr *E) {
15350 TypeSourceInfo *T =
15351 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15352 if (!T)
15353 return ExprError();
15354
15355 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15356 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15357 if (!Constructor)
15358 return ExprError();
15359
15360 bool ArgumentChanged = false;
15361 SmallVector<Expr*, 8> Args;
15362 Args.reserve(N: E->getNumArgs());
15363 {
15364 EnterExpressionEvaluationContext Context(
15365 getSema(), EnterExpressionEvaluationContext::InitList,
15366 E->isListInitialization());
15367 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15368 ArgChanged: &ArgumentChanged))
15369 return ExprError();
15370
15371 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15372 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15373 if (Res.isInvalid())
15374 return ExprError();
15375 Args = {Res.get()};
15376 }
15377 }
15378
15379 if (!getDerived().AlwaysRebuild() &&
15380 T == E->getTypeSourceInfo() &&
15381 Constructor == E->getConstructor() &&
15382 !ArgumentChanged) {
15383 // FIXME: Instantiation-specific
15384 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15385 return SemaRef.MaybeBindToTemporary(E);
15386 }
15387
15388 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15389 return getDerived().RebuildCXXTemporaryObjectExpr(
15390 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15391}
15392
15393template<typename Derived>
15394ExprResult
15395TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15396 // Transform any init-capture expressions before entering the scope of the
15397 // lambda body, because they are not semantically within that scope.
15398 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15399 struct TransformedInitCapture {
15400 // The location of the ... if the result is retaining a pack expansion.
15401 SourceLocation EllipsisLoc;
15402 // Zero or more expansions of the init-capture.
15403 SmallVector<InitCaptureInfoTy, 4> Expansions;
15404 };
15405 SmallVector<TransformedInitCapture, 4> InitCaptures;
15406 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15407 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15408 CEnd = E->capture_end();
15409 C != CEnd; ++C) {
15410 if (!E->isInitCapture(Capture: C))
15411 continue;
15412
15413 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15414 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15415
15416 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15417 UnsignedOrNone NumExpansions) {
15418 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15419 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15420
15421 if (NewExprInitResult.isInvalid()) {
15422 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15423 return;
15424 }
15425 Expr *NewExprInit = NewExprInitResult.get();
15426
15427 QualType NewInitCaptureType =
15428 getSema().buildLambdaInitCaptureInitialization(
15429 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15430 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15431 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15432 VarDecl::CInit,
15433 NewExprInit);
15434 Result.Expansions.push_back(
15435 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15436 };
15437
15438 // If this is an init-capture pack, consider expanding the pack now.
15439 if (OldVD->isParameterPack()) {
15440 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15441 ->getTypeLoc()
15442 .castAs<PackExpansionTypeLoc>();
15443 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15444 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15445
15446 // Determine whether the set of unexpanded parameter packs can and should
15447 // be expanded.
15448 bool Expand = true;
15449 bool RetainExpansion = false;
15450 UnsignedOrNone OrigNumExpansions =
15451 ExpansionTL.getTypePtr()->getNumExpansions();
15452 UnsignedOrNone NumExpansions = OrigNumExpansions;
15453 if (getDerived().TryExpandParameterPacks(
15454 ExpansionTL.getEllipsisLoc(),
15455 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15456 RetainExpansion, NumExpansions))
15457 return ExprError();
15458 assert(!RetainExpansion && "Should not need to retain expansion after a "
15459 "capture since it cannot be extended");
15460 if (Expand) {
15461 for (unsigned I = 0; I != *NumExpansions; ++I) {
15462 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15463 SubstInitCapture(SourceLocation(), std::nullopt);
15464 }
15465 } else {
15466 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15467 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15468 }
15469 } else {
15470 SubstInitCapture(SourceLocation(), std::nullopt);
15471 }
15472 }
15473
15474 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15475 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15476
15477 // Create the local class that will describe the lambda.
15478
15479 // FIXME: DependencyKind below is wrong when substituting inside a templated
15480 // context that isn't a DeclContext (such as a variable template), or when
15481 // substituting an unevaluated lambda inside of a function's parameter's type
15482 // - as parameter types are not instantiated from within a function's DC. We
15483 // use evaluation contexts to distinguish the function parameter case.
15484 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15485 CXXRecordDecl::LDK_Unknown;
15486 DeclContext *DC = getSema().CurContext;
15487 // A RequiresExprBodyDecl is not interesting for dependencies.
15488 // For the following case,
15489 //
15490 // template <typename>
15491 // concept C = requires { [] {}; };
15492 //
15493 // template <class F>
15494 // struct Widget;
15495 //
15496 // template <C F>
15497 // struct Widget<F> {};
15498 //
15499 // While we are substituting Widget<F>, the parent of DC would be
15500 // the template specialization itself. Thus, the lambda expression
15501 // will be deemed as dependent even if there are no dependent template
15502 // arguments.
15503 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15504 while (DC->isRequiresExprBody())
15505 DC = DC->getParent();
15506 if ((getSema().isUnevaluatedContext() ||
15507 getSema().isConstantEvaluatedContext()) &&
15508 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15509 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15510
15511 CXXRecordDecl *OldClass = E->getLambdaClass();
15512 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15513 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15514 E->getCaptureDefault());
15515 getDerived().transformedLocalDecl(OldClass, {Class});
15516
15517 CXXMethodDecl *NewCallOperator =
15518 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15519
15520 // Enter the scope of the lambda.
15521 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15522 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15523 E->hasExplicitParameters(), E->isMutable());
15524
15525 // Introduce the context of the call operator.
15526 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15527 /*NewThisContext*/false);
15528
15529 bool Invalid = false;
15530
15531 // Transform captures.
15532 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15533 CEnd = E->capture_end();
15534 C != CEnd; ++C) {
15535 // When we hit the first implicit capture, tell Sema that we've finished
15536 // the list of explicit captures.
15537 if (C->isImplicit())
15538 break;
15539
15540 // Capturing 'this' is trivial.
15541 if (C->capturesThis()) {
15542 // If this is a lambda that is part of a default member initialiser
15543 // and which we're instantiating outside the class that 'this' is
15544 // supposed to refer to, adjust the type of 'this' accordingly.
15545 //
15546 // Otherwise, leave the type of 'this' as-is.
15547 Sema::CXXThisScopeRAII ThisScope(
15548 getSema(),
15549 dyn_cast_if_present<CXXRecordDecl>(
15550 getSema().getFunctionLevelDeclContext()),
15551 Qualifiers());
15552 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15553 /*BuildAndDiagnose*/ true, nullptr,
15554 C->getCaptureKind() == LCK_StarThis);
15555 continue;
15556 }
15557 // Captured expression will be recaptured during captured variables
15558 // rebuilding.
15559 if (C->capturesVLAType())
15560 continue;
15561
15562 // Rebuild init-captures, including the implied field declaration.
15563 if (E->isInitCapture(Capture: C)) {
15564 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15565
15566 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15567 llvm::SmallVector<Decl*, 4> NewVDs;
15568
15569 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15570 ExprResult Init = Info.first;
15571 QualType InitQualType = Info.second;
15572 if (Init.isInvalid() || InitQualType.isNull()) {
15573 Invalid = true;
15574 break;
15575 }
15576 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15577 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15578 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15579 getSema().CurContext);
15580 if (!NewVD) {
15581 Invalid = true;
15582 break;
15583 }
15584 NewVDs.push_back(Elt: NewVD);
15585 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15586 // Cases we want to tackle:
15587 // ([C(Pack)] {}, ...)
15588 // But rule out cases e.g.
15589 // [...C = Pack()] {}
15590 if (NewC.EllipsisLoc.isInvalid())
15591 LSI->ContainsUnexpandedParameterPack |=
15592 Init.get()->containsUnexpandedParameterPack();
15593 }
15594
15595 if (Invalid)
15596 break;
15597
15598 getDerived().transformedLocalDecl(OldVD, NewVDs);
15599 continue;
15600 }
15601
15602 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15603
15604 // Determine the capture kind for Sema.
15605 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15606 : C->getCaptureKind() == LCK_ByCopy
15607 ? TryCaptureKind::ExplicitByVal
15608 : TryCaptureKind::ExplicitByRef;
15609 SourceLocation EllipsisLoc;
15610 if (C->isPackExpansion()) {
15611 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15612 bool ShouldExpand = false;
15613 bool RetainExpansion = false;
15614 UnsignedOrNone NumExpansions = std::nullopt;
15615 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15616 C->getLocation(),
15617 Unexpanded,
15618 ShouldExpand, RetainExpansion,
15619 NumExpansions)) {
15620 Invalid = true;
15621 continue;
15622 }
15623
15624 if (ShouldExpand) {
15625 // The transform has determined that we should perform an expansion;
15626 // transform and capture each of the arguments.
15627 // expansion of the pattern. Do so.
15628 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
15629 for (unsigned I = 0; I != *NumExpansions; ++I) {
15630 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15631 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15632 getDerived().TransformDecl(C->getLocation(), Pack));
15633 if (!CapturedVar) {
15634 Invalid = true;
15635 continue;
15636 }
15637
15638 // Capture the transformed variable.
15639 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15640 }
15641
15642 // FIXME: Retain a pack expansion if RetainExpansion is true.
15643
15644 continue;
15645 }
15646
15647 EllipsisLoc = C->getEllipsisLoc();
15648 }
15649
15650 // Transform the captured variable.
15651 auto *CapturedVar = cast_or_null<ValueDecl>(
15652 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15653 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15654 Invalid = true;
15655 continue;
15656 }
15657
15658 // This is not an init-capture; however it contains an unexpanded pack e.g.
15659 // ([Pack] {}(), ...)
15660 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15661 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15662
15663 // Capture the transformed variable.
15664 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15665 EllipsisLoc);
15666 }
15667 getSema().finishLambdaExplicitCaptures(LSI);
15668
15669 // Transform the template parameters, and add them to the current
15670 // instantiation scope. The null case is handled correctly.
15671 auto TPL = getDerived().TransformTemplateParameterList(
15672 E->getTemplateParameterList());
15673 LSI->GLTemplateParameterList = TPL;
15674 if (TPL) {
15675 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15676 TPL);
15677 LSI->ContainsUnexpandedParameterPack |=
15678 TPL->containsUnexpandedParameterPack();
15679 }
15680
15681 TypeLocBuilder NewCallOpTLBuilder;
15682 TypeLoc OldCallOpTypeLoc =
15683 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15684 QualType NewCallOpType =
15685 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15686 if (NewCallOpType.isNull())
15687 return ExprError();
15688 LSI->ContainsUnexpandedParameterPack |=
15689 NewCallOpType->containsUnexpandedParameterPack();
15690 TypeSourceInfo *NewCallOpTSI =
15691 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
15692
15693 // The type may be an AttributedType or some other kind of sugar;
15694 // get the actual underlying FunctionProtoType.
15695 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15696 assert(FPTL && "Not a FunctionProtoType?");
15697
15698 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15699 if (!TRC.ArgPackSubstIndex)
15700 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15701
15702 getSema().CompleteLambdaCallOperator(
15703 NewCallOperator, E->getCallOperator()->getLocation(),
15704 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15705 E->getCallOperator()->getConstexprKind(),
15706 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15707 E->hasExplicitResultType());
15708
15709 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15710 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15711
15712 {
15713 // Number the lambda for linkage purposes if necessary.
15714 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15715
15716 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15717 if (getDerived().ReplacingOriginal()) {
15718 Numbering = OldClass->getLambdaNumbering();
15719 }
15720
15721 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15722 }
15723
15724 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15725 // evaluation context even if we're not transforming the function body.
15726 getSema().PushExpressionEvaluationContextForFunction(
15727 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
15728 E->getCallOperator());
15729
15730 Sema::CodeSynthesisContext C;
15731 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15732 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15733 getSema().pushCodeSynthesisContext(C);
15734
15735 // Instantiate the body of the lambda expression.
15736 StmtResult Body =
15737 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15738
15739 getSema().popCodeSynthesisContext();
15740
15741 // ActOnLambda* will pop the function scope for us.
15742 FuncScopeCleanup.disable();
15743
15744 if (Body.isInvalid()) {
15745 SavedContext.pop();
15746 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15747 /*IsInstantiation=*/true);
15748 return ExprError();
15749 }
15750
15751 // Copy the LSI before ActOnFinishFunctionBody removes it.
15752 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15753 // the call operator.
15754 auto LSICopy = *LSI;
15755 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15756 /*IsInstantiation*/ true);
15757 SavedContext.pop();
15758
15759 // Recompute the dependency of the lambda so that we can defer the lambda call
15760 // construction until after we have all the necessary template arguments. For
15761 // example, given
15762 //
15763 // template <class> struct S {
15764 // template <class U>
15765 // using Type = decltype([](U){}(42.0));
15766 // };
15767 // void foo() {
15768 // using T = S<int>::Type<float>;
15769 // ^~~~~~
15770 // }
15771 //
15772 // We would end up here from instantiating S<int> when ensuring its
15773 // completeness. That would transform the lambda call expression regardless of
15774 // the absence of the corresponding argument for U.
15775 //
15776 // Going ahead with unsubstituted type U makes things worse: we would soon
15777 // compare the argument type (which is float) against the parameter U
15778 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15779 // error suggesting unmatched types 'U' and 'float'!
15780 //
15781 // That said, everything will be fine if we defer that semantic checking.
15782 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15783 // dependent. Since the CallExpr's dependency boils down to the lambda's
15784 // dependency in this case, we can harness that by recomputing the dependency
15785 // from the instantiation arguments.
15786 //
15787 // FIXME: Creating the type of a lambda requires us to have a dependency
15788 // value, which happens before its substitution. We update its dependency
15789 // *after* the substitution in case we can't decide the dependency
15790 // so early, e.g. because we want to see if any of the *substituted*
15791 // parameters are dependent.
15792 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15793 Class->setLambdaDependencyKind(DependencyKind);
15794 // Clean up the type cache created previously. Then, we re-create a type for
15795 // such Decl with the new DependencyKind.
15796 Class->setTypeForDecl(nullptr);
15797 getSema().Context.getTypeDeclType(Class);
15798
15799 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15800 Body.get()->getEndLoc(), &LSICopy);
15801}
15802
15803template<typename Derived>
15804StmtResult
15805TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
15806 return TransformStmt(S);
15807}
15808
15809template<typename Derived>
15810StmtResult
15811TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
15812 // Transform captures.
15813 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15814 CEnd = E->capture_end();
15815 C != CEnd; ++C) {
15816 // When we hit the first implicit capture, tell Sema that we've finished
15817 // the list of explicit captures.
15818 if (!C->isImplicit())
15819 continue;
15820
15821 // Capturing 'this' is trivial.
15822 if (C->capturesThis()) {
15823 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15824 /*BuildAndDiagnose*/ true, nullptr,
15825 C->getCaptureKind() == LCK_StarThis);
15826 continue;
15827 }
15828 // Captured expression will be recaptured during captured variables
15829 // rebuilding.
15830 if (C->capturesVLAType())
15831 continue;
15832
15833 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15834 assert(!E->isInitCapture(C) && "implicit init-capture?");
15835
15836 // Transform the captured variable.
15837 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15838 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15839 if (!CapturedVar || CapturedVar->isInvalidDecl())
15840 return StmtError();
15841
15842 // Capture the transformed variable.
15843 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15844 }
15845
15846 return S;
15847}
15848
15849template<typename Derived>
15850ExprResult
15851TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
15852 CXXUnresolvedConstructExpr *E) {
15853 TypeSourceInfo *T =
15854 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15855 if (!T)
15856 return ExprError();
15857
15858 bool ArgumentChanged = false;
15859 SmallVector<Expr*, 8> Args;
15860 Args.reserve(N: E->getNumArgs());
15861 {
15862 EnterExpressionEvaluationContext Context(
15863 getSema(), EnterExpressionEvaluationContext::InitList,
15864 E->isListInitialization());
15865 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15866 &ArgumentChanged))
15867 return ExprError();
15868 }
15869
15870 if (!getDerived().AlwaysRebuild() &&
15871 T == E->getTypeSourceInfo() &&
15872 !ArgumentChanged)
15873 return E;
15874
15875 // FIXME: we're faking the locations of the commas
15876 return getDerived().RebuildCXXUnresolvedConstructExpr(
15877 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15878}
15879
15880template<typename Derived>
15881ExprResult
15882TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15883 CXXDependentScopeMemberExpr *E) {
15884 // Transform the base of the expression.
15885 ExprResult Base((Expr*) nullptr);
15886 Expr *OldBase;
15887 QualType BaseType;
15888 QualType ObjectType;
15889 if (!E->isImplicitAccess()) {
15890 OldBase = E->getBase();
15891 Base = getDerived().TransformExpr(OldBase);
15892 if (Base.isInvalid())
15893 return ExprError();
15894
15895 // Start the member reference and compute the object's type.
15896 ParsedType ObjectTy;
15897 bool MayBePseudoDestructor = false;
15898 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15899 OpLoc: E->getOperatorLoc(),
15900 OpKind: E->isArrow()? tok::arrow : tok::period,
15901 ObjectType&: ObjectTy,
15902 MayBePseudoDestructor);
15903 if (Base.isInvalid())
15904 return ExprError();
15905
15906 ObjectType = ObjectTy.get();
15907 BaseType = ((Expr*) Base.get())->getType();
15908 } else {
15909 OldBase = nullptr;
15910 BaseType = getDerived().TransformType(E->getBaseType());
15911 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15912 }
15913
15914 // Transform the first part of the nested-name-specifier that qualifies
15915 // the member name.
15916 NamedDecl *FirstQualifierInScope
15917 = getDerived().TransformFirstQualifierInScope(
15918 E->getFirstQualifierFoundInScope(),
15919 E->getQualifierLoc().getBeginLoc());
15920
15921 NestedNameSpecifierLoc QualifierLoc;
15922 if (E->getQualifier()) {
15923 QualifierLoc
15924 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15925 ObjectType,
15926 FirstQualifierInScope);
15927 if (!QualifierLoc)
15928 return ExprError();
15929 }
15930
15931 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15932
15933 // TODO: If this is a conversion-function-id, verify that the
15934 // destination type name (if present) resolves the same way after
15935 // instantiation as it did in the local scope.
15936
15937 DeclarationNameInfo NameInfo
15938 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15939 if (!NameInfo.getName())
15940 return ExprError();
15941
15942 if (!E->hasExplicitTemplateArgs()) {
15943 // This is a reference to a member without an explicitly-specified
15944 // template argument list. Optimize for this common case.
15945 if (!getDerived().AlwaysRebuild() &&
15946 Base.get() == OldBase &&
15947 BaseType == E->getBaseType() &&
15948 QualifierLoc == E->getQualifierLoc() &&
15949 NameInfo.getName() == E->getMember() &&
15950 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15951 return E;
15952
15953 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15954 BaseType,
15955 E->isArrow(),
15956 E->getOperatorLoc(),
15957 QualifierLoc,
15958 TemplateKWLoc,
15959 FirstQualifierInScope,
15960 NameInfo,
15961 /*TemplateArgs*/nullptr);
15962 }
15963
15964 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15965 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15966 E->getNumTemplateArgs(),
15967 TransArgs))
15968 return ExprError();
15969
15970 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15971 BaseType,
15972 E->isArrow(),
15973 E->getOperatorLoc(),
15974 QualifierLoc,
15975 TemplateKWLoc,
15976 FirstQualifierInScope,
15977 NameInfo,
15978 &TransArgs);
15979}
15980
15981template <typename Derived>
15982ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15983 UnresolvedMemberExpr *Old) {
15984 // Transform the base of the expression.
15985 ExprResult Base((Expr *)nullptr);
15986 QualType BaseType;
15987 if (!Old->isImplicitAccess()) {
15988 Base = getDerived().TransformExpr(Old->getBase());
15989 if (Base.isInvalid())
15990 return ExprError();
15991 Base =
15992 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
15993 if (Base.isInvalid())
15994 return ExprError();
15995 BaseType = Base.get()->getType();
15996 } else {
15997 BaseType = getDerived().TransformType(Old->getBaseType());
15998 }
15999
16000 NestedNameSpecifierLoc QualifierLoc;
16001 if (Old->getQualifierLoc()) {
16002 QualifierLoc =
16003 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16004 if (!QualifierLoc)
16005 return ExprError();
16006 }
16007
16008 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16009
16010 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16011
16012 // Transform the declaration set.
16013 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16014 return ExprError();
16015
16016 // Determine the naming class.
16017 if (Old->getNamingClass()) {
16018 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16019 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16020 if (!NamingClass)
16021 return ExprError();
16022
16023 R.setNamingClass(NamingClass);
16024 }
16025
16026 TemplateArgumentListInfo TransArgs;
16027 if (Old->hasExplicitTemplateArgs()) {
16028 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16029 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16030 if (getDerived().TransformTemplateArguments(
16031 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16032 return ExprError();
16033 }
16034
16035 // FIXME: to do this check properly, we will need to preserve the
16036 // first-qualifier-in-scope here, just in case we had a dependent
16037 // base (and therefore couldn't do the check) and a
16038 // nested-name-qualifier (and therefore could do the lookup).
16039 NamedDecl *FirstQualifierInScope = nullptr;
16040
16041 return getDerived().RebuildUnresolvedMemberExpr(
16042 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16043 TemplateKWLoc, FirstQualifierInScope, R,
16044 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16045}
16046
16047template<typename Derived>
16048ExprResult
16049TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16050 EnterExpressionEvaluationContext Unevaluated(
16051 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16052 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16053 if (SubExpr.isInvalid())
16054 return ExprError();
16055
16056 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16057 return E;
16058
16059 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16060}
16061
16062template<typename Derived>
16063ExprResult
16064TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16065 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16066 if (Pattern.isInvalid())
16067 return ExprError();
16068
16069 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16070 return E;
16071
16072 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16073 E->getNumExpansions());
16074}
16075
16076template <typename Derived>
16077UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16078 ArrayRef<TemplateArgument> PackArgs) {
16079 UnsignedOrNone Result = 0u;
16080 for (const TemplateArgument &Arg : PackArgs) {
16081 if (!Arg.isPackExpansion()) {
16082 Result = *Result + 1;
16083 continue;
16084 }
16085
16086 TemplateArgumentLoc ArgLoc;
16087 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16088
16089 // Find the pattern of the pack expansion.
16090 SourceLocation Ellipsis;
16091 UnsignedOrNone OrigNumExpansions = std::nullopt;
16092 TemplateArgumentLoc Pattern =
16093 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16094 OrigNumExpansions);
16095
16096 // Substitute under the pack expansion. Do not expand the pack (yet).
16097 TemplateArgumentLoc OutPattern;
16098 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16099 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16100 /*Uneval*/ true))
16101 return 1u;
16102
16103 // See if we can determine the number of arguments from the result.
16104 UnsignedOrNone NumExpansions =
16105 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16106 if (!NumExpansions) {
16107 // No: we must be in an alias template expansion, and we're going to
16108 // need to actually expand the packs.
16109 Result = std::nullopt;
16110 break;
16111 }
16112
16113 Result = *Result + *NumExpansions;
16114 }
16115 return Result;
16116}
16117
16118template<typename Derived>
16119ExprResult
16120TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16121 // If E is not value-dependent, then nothing will change when we transform it.
16122 // Note: This is an instantiation-centric view.
16123 if (!E->isValueDependent())
16124 return E;
16125
16126 EnterExpressionEvaluationContext Unevaluated(
16127 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16128
16129 ArrayRef<TemplateArgument> PackArgs;
16130 TemplateArgument ArgStorage;
16131
16132 // Find the argument list to transform.
16133 if (E->isPartiallySubstituted()) {
16134 PackArgs = E->getPartialArguments();
16135 } else if (E->isValueDependent()) {
16136 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16137 bool ShouldExpand = false;
16138 bool RetainExpansion = false;
16139 UnsignedOrNone NumExpansions = std::nullopt;
16140 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
16141 Unexpanded,
16142 ShouldExpand, RetainExpansion,
16143 NumExpansions))
16144 return ExprError();
16145
16146 // If we need to expand the pack, build a template argument from it and
16147 // expand that.
16148 if (ShouldExpand) {
16149 auto *Pack = E->getPack();
16150 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16151 ArgStorage = getSema().Context.getPackExpansionType(
16152 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16153 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16154 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16155 } else {
16156 auto *VD = cast<ValueDecl>(Val: Pack);
16157 ExprResult DRE = getSema().BuildDeclRefExpr(
16158 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16159 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16160 E->getPackLoc());
16161 if (DRE.isInvalid())
16162 return ExprError();
16163 ArgStorage = TemplateArgument(
16164 new (getSema().Context)
16165 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16166 /*IsCanonical=*/false);
16167 }
16168 PackArgs = ArgStorage;
16169 }
16170 }
16171
16172 // If we're not expanding the pack, just transform the decl.
16173 if (!PackArgs.size()) {
16174 auto *Pack = cast_or_null<NamedDecl>(
16175 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16176 if (!Pack)
16177 return ExprError();
16178 return getDerived().RebuildSizeOfPackExpr(
16179 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16180 std::nullopt, {});
16181 }
16182
16183 // Try to compute the result without performing a partial substitution.
16184 UnsignedOrNone Result =
16185 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16186
16187 // Common case: we could determine the number of expansions without
16188 // substituting.
16189 if (Result)
16190 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16191 E->getPackLoc(),
16192 E->getRParenLoc(), *Result, {});
16193
16194 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16195 E->getPackLoc());
16196 {
16197 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16198 typedef TemplateArgumentLocInventIterator<
16199 Derived, const TemplateArgument*> PackLocIterator;
16200 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16201 PackLocIterator(*this, PackArgs.end()),
16202 TransformedPackArgs, /*Uneval*/true))
16203 return ExprError();
16204 }
16205
16206 // Check whether we managed to fully-expand the pack.
16207 // FIXME: Is it possible for us to do so and not hit the early exit path?
16208 SmallVector<TemplateArgument, 8> Args;
16209 bool PartialSubstitution = false;
16210 for (auto &Loc : TransformedPackArgs.arguments()) {
16211 Args.push_back(Elt: Loc.getArgument());
16212 if (Loc.getArgument().isPackExpansion())
16213 PartialSubstitution = true;
16214 }
16215
16216 if (PartialSubstitution)
16217 return getDerived().RebuildSizeOfPackExpr(
16218 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16219 std::nullopt, Args);
16220
16221 return getDerived().RebuildSizeOfPackExpr(
16222 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16223 /*Length=*/static_cast<unsigned>(Args.size()),
16224 /*PartialArgs=*/{});
16225}
16226
16227template <typename Derived>
16228ExprResult
16229TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16230 if (!E->isValueDependent())
16231 return E;
16232
16233 // Transform the index
16234 ExprResult IndexExpr;
16235 {
16236 EnterExpressionEvaluationContext ConstantContext(
16237 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16238 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16239 if (IndexExpr.isInvalid())
16240 return ExprError();
16241 }
16242
16243 SmallVector<Expr *, 5> ExpandedExprs;
16244 bool FullySubstituted = true;
16245 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16246 Expr *Pattern = E->getPackIdExpression();
16247 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16248 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16249 Unexpanded);
16250 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16251
16252 // Determine whether the set of unexpanded parameter packs can and should
16253 // be expanded.
16254 bool ShouldExpand = true;
16255 bool RetainExpansion = false;
16256 UnsignedOrNone OrigNumExpansions = std::nullopt,
16257 NumExpansions = std::nullopt;
16258 if (getDerived().TryExpandParameterPacks(
16259 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16260 ShouldExpand, RetainExpansion, NumExpansions))
16261 return true;
16262 if (!ShouldExpand) {
16263 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16264 ExprResult Pack = getDerived().TransformExpr(Pattern);
16265 if (Pack.isInvalid())
16266 return ExprError();
16267 return getDerived().RebuildPackIndexingExpr(
16268 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16269 {}, /*FullySubstituted=*/false);
16270 }
16271 for (unsigned I = 0; I != *NumExpansions; ++I) {
16272 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16273 ExprResult Out = getDerived().TransformExpr(Pattern);
16274 if (Out.isInvalid())
16275 return true;
16276 if (Out.get()->containsUnexpandedParameterPack()) {
16277 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16278 OrigNumExpansions);
16279 if (Out.isInvalid())
16280 return true;
16281 FullySubstituted = false;
16282 }
16283 ExpandedExprs.push_back(Elt: Out.get());
16284 }
16285 // If we're supposed to retain a pack expansion, do so by temporarily
16286 // forgetting the partially-substituted parameter pack.
16287 if (RetainExpansion) {
16288 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16289
16290 ExprResult Out = getDerived().TransformExpr(Pattern);
16291 if (Out.isInvalid())
16292 return true;
16293
16294 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16295 OrigNumExpansions);
16296 if (Out.isInvalid())
16297 return true;
16298 FullySubstituted = false;
16299 ExpandedExprs.push_back(Elt: Out.get());
16300 }
16301 } else if (!E->expandsToEmptyPack()) {
16302 if (getDerived().TransformExprs(E->getExpressions().data(),
16303 E->getExpressions().size(), false,
16304 ExpandedExprs))
16305 return ExprError();
16306 }
16307
16308 return getDerived().RebuildPackIndexingExpr(
16309 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16310 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16311}
16312
16313template<typename Derived>
16314ExprResult
16315TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16316 SubstNonTypeTemplateParmPackExpr *E) {
16317 // Default behavior is to do nothing with this transformation.
16318 return E;
16319}
16320
16321template<typename Derived>
16322ExprResult
16323TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16324 SubstNonTypeTemplateParmExpr *E) {
16325 // Default behavior is to do nothing with this transformation.
16326 return E;
16327}
16328
16329template<typename Derived>
16330ExprResult
16331TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16332 // Default behavior is to do nothing with this transformation.
16333 return E;
16334}
16335
16336template<typename Derived>
16337ExprResult
16338TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16339 MaterializeTemporaryExpr *E) {
16340 return getDerived().TransformExpr(E->getSubExpr());
16341}
16342
16343template<typename Derived>
16344ExprResult
16345TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16346 UnresolvedLookupExpr *Callee = nullptr;
16347 if (Expr *OldCallee = E->getCallee()) {
16348 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16349 if (CalleeResult.isInvalid())
16350 return ExprError();
16351 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16352 }
16353
16354 Expr *Pattern = E->getPattern();
16355
16356 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16357 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16358 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16359
16360 // Determine whether the set of unexpanded parameter packs can and should
16361 // be expanded.
16362 bool Expand = true;
16363 bool RetainExpansion = false;
16364 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16365 NumExpansions = OrigNumExpansions;
16366 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
16367 Pattern->getSourceRange(),
16368 Unexpanded,
16369 Expand, RetainExpansion,
16370 NumExpansions))
16371 return true;
16372
16373 if (!Expand) {
16374 // Do not expand any packs here, just transform and rebuild a fold
16375 // expression.
16376 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16377
16378 ExprResult LHS =
16379 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16380 if (LHS.isInvalid())
16381 return true;
16382
16383 ExprResult RHS =
16384 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16385 if (RHS.isInvalid())
16386 return true;
16387
16388 if (!getDerived().AlwaysRebuild() &&
16389 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16390 return E;
16391
16392 return getDerived().RebuildCXXFoldExpr(
16393 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16394 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16395 }
16396
16397 // Formally a fold expression expands to nested parenthesized expressions.
16398 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16399 // them.
16400 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16401 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16402 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16403 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16404 << E->getSourceRange();
16405 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16406 return ExprError();
16407 }
16408
16409 // The transform has determined that we should perform an elementwise
16410 // expansion of the pattern. Do so.
16411 ExprResult Result = getDerived().TransformExpr(E->getInit());
16412 if (Result.isInvalid())
16413 return true;
16414 bool LeftFold = E->isLeftFold();
16415
16416 // If we're retaining an expansion for a right fold, it is the innermost
16417 // component and takes the init (if any).
16418 if (!LeftFold && RetainExpansion) {
16419 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16420
16421 ExprResult Out = getDerived().TransformExpr(Pattern);
16422 if (Out.isInvalid())
16423 return true;
16424
16425 Result = getDerived().RebuildCXXFoldExpr(
16426 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16427 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16428 if (Result.isInvalid())
16429 return true;
16430 }
16431
16432 bool WarnedOnComparison = false;
16433 for (unsigned I = 0; I != *NumExpansions; ++I) {
16434 Sema::ArgPackSubstIndexRAII SubstIndex(
16435 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16436 ExprResult Out = getDerived().TransformExpr(Pattern);
16437 if (Out.isInvalid())
16438 return true;
16439
16440 if (Out.get()->containsUnexpandedParameterPack()) {
16441 // We still have a pack; retain a pack expansion for this slice.
16442 Result = getDerived().RebuildCXXFoldExpr(
16443 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16444 E->getOperator(), E->getEllipsisLoc(),
16445 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16446 OrigNumExpansions);
16447 } else if (Result.isUsable()) {
16448 // We've got down to a single element; build a binary operator.
16449 Expr *LHS = LeftFold ? Result.get() : Out.get();
16450 Expr *RHS = LeftFold ? Out.get() : Result.get();
16451 if (Callee) {
16452 UnresolvedSet<16> Functions;
16453 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16454 Result = getDerived().RebuildCXXOperatorCallExpr(
16455 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16456 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16457 Functions, LHS, RHS);
16458 } else {
16459 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16460 E->getOperator(), LHS, RHS,
16461 /*ForFoldExpresion=*/true);
16462 if (!WarnedOnComparison && Result.isUsable()) {
16463 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16464 BO && BO->isComparisonOp()) {
16465 WarnedOnComparison = true;
16466 SemaRef.Diag(Loc: BO->getBeginLoc(),
16467 DiagID: diag::warn_comparison_in_fold_expression)
16468 << BO->getOpcodeStr();
16469 }
16470 }
16471 }
16472 } else
16473 Result = Out;
16474
16475 if (Result.isInvalid())
16476 return true;
16477 }
16478
16479 // If we're retaining an expansion for a left fold, it is the outermost
16480 // component and takes the complete expansion so far as its init (if any).
16481 if (LeftFold && RetainExpansion) {
16482 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16483
16484 ExprResult Out = getDerived().TransformExpr(Pattern);
16485 if (Out.isInvalid())
16486 return true;
16487
16488 Result = getDerived().RebuildCXXFoldExpr(
16489 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16490 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16491 if (Result.isInvalid())
16492 return true;
16493 }
16494
16495 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16496 PE->setIsProducedByFoldExpansion();
16497
16498 // If we had no init and an empty pack, and we're not retaining an expansion,
16499 // then produce a fallback value or error.
16500 if (Result.isUnset())
16501 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16502 E->getOperator());
16503 return Result;
16504}
16505
16506template <typename Derived>
16507ExprResult
16508TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16509 SmallVector<Expr *, 4> TransformedInits;
16510 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16511
16512 QualType T = getDerived().TransformType(E->getType());
16513
16514 bool ArgChanged = false;
16515
16516 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16517 TransformedInits, &ArgChanged))
16518 return ExprError();
16519
16520 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16521 return E;
16522
16523 return getDerived().RebuildCXXParenListInitExpr(
16524 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16525 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16526}
16527
16528template<typename Derived>
16529ExprResult
16530TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16531 CXXStdInitializerListExpr *E) {
16532 return getDerived().TransformExpr(E->getSubExpr());
16533}
16534
16535template<typename Derived>
16536ExprResult
16537TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16538 return SemaRef.MaybeBindToTemporary(E);
16539}
16540
16541template<typename Derived>
16542ExprResult
16543TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16544 return E;
16545}
16546
16547template<typename Derived>
16548ExprResult
16549TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16550 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16551 if (SubExpr.isInvalid())
16552 return ExprError();
16553
16554 if (!getDerived().AlwaysRebuild() &&
16555 SubExpr.get() == E->getSubExpr())
16556 return E;
16557
16558 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16559}
16560
16561template<typename Derived>
16562ExprResult
16563TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16564 // Transform each of the elements.
16565 SmallVector<Expr *, 8> Elements;
16566 bool ArgChanged = false;
16567 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16568 /*IsCall=*/false, Elements, &ArgChanged))
16569 return ExprError();
16570
16571 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16572 return SemaRef.MaybeBindToTemporary(E);
16573
16574 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16575 Elements.data(),
16576 Elements.size());
16577}
16578
16579template<typename Derived>
16580ExprResult
16581TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16582 ObjCDictionaryLiteral *E) {
16583 // Transform each of the elements.
16584 SmallVector<ObjCDictionaryElement, 8> Elements;
16585 bool ArgChanged = false;
16586 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16587 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
16588
16589 if (OrigElement.isPackExpansion()) {
16590 // This key/value element is a pack expansion.
16591 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16592 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16593 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16594 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16595
16596 // Determine whether the set of unexpanded parameter packs can
16597 // and should be expanded.
16598 bool Expand = true;
16599 bool RetainExpansion = false;
16600 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16601 UnsignedOrNone NumExpansions = OrigNumExpansions;
16602 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16603 OrigElement.Value->getEndLoc());
16604 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
16605 PatternRange, Unexpanded, Expand,
16606 RetainExpansion, NumExpansions))
16607 return ExprError();
16608
16609 if (!Expand) {
16610 // The transform has determined that we should perform a simple
16611 // transformation on the pack expansion, producing another pack
16612 // expansion.
16613 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16614 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16615 if (Key.isInvalid())
16616 return ExprError();
16617
16618 if (Key.get() != OrigElement.Key)
16619 ArgChanged = true;
16620
16621 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16622 if (Value.isInvalid())
16623 return ExprError();
16624
16625 if (Value.get() != OrigElement.Value)
16626 ArgChanged = true;
16627
16628 ObjCDictionaryElement Expansion = {
16629 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
16630 };
16631 Elements.push_back(Elt: Expansion);
16632 continue;
16633 }
16634
16635 // Record right away that the argument was changed. This needs
16636 // to happen even if the array expands to nothing.
16637 ArgChanged = true;
16638
16639 // The transform has determined that we should perform an elementwise
16640 // expansion of the pattern. Do so.
16641 for (unsigned I = 0; I != *NumExpansions; ++I) {
16642 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16643 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16644 if (Key.isInvalid())
16645 return ExprError();
16646
16647 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16648 if (Value.isInvalid())
16649 return ExprError();
16650
16651 ObjCDictionaryElement Element = {
16652 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
16653 };
16654
16655 // If any unexpanded parameter packs remain, we still have a
16656 // pack expansion.
16657 // FIXME: Can this really happen?
16658 if (Key.get()->containsUnexpandedParameterPack() ||
16659 Value.get()->containsUnexpandedParameterPack())
16660 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16661
16662 Elements.push_back(Elt: Element);
16663 }
16664
16665 // FIXME: Retain a pack expansion if RetainExpansion is true.
16666
16667 // We've finished with this pack expansion.
16668 continue;
16669 }
16670
16671 // Transform and check key.
16672 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16673 if (Key.isInvalid())
16674 return ExprError();
16675
16676 if (Key.get() != OrigElement.Key)
16677 ArgChanged = true;
16678
16679 // Transform and check value.
16680 ExprResult Value
16681 = getDerived().TransformExpr(OrigElement.Value);
16682 if (Value.isInvalid())
16683 return ExprError();
16684
16685 if (Value.get() != OrigElement.Value)
16686 ArgChanged = true;
16687
16688 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
16689 .NumExpansions: std::nullopt};
16690 Elements.push_back(Elt: Element);
16691 }
16692
16693 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16694 return SemaRef.MaybeBindToTemporary(E);
16695
16696 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16697 Elements);
16698}
16699
16700template<typename Derived>
16701ExprResult
16702TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16703 TypeSourceInfo *EncodedTypeInfo
16704 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16705 if (!EncodedTypeInfo)
16706 return ExprError();
16707
16708 if (!getDerived().AlwaysRebuild() &&
16709 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16710 return E;
16711
16712 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16713 EncodedTypeInfo,
16714 E->getRParenLoc());
16715}
16716
16717template<typename Derived>
16718ExprResult TreeTransform<Derived>::
16719TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16720 // This is a kind of implicit conversion, and it needs to get dropped
16721 // and recomputed for the same general reasons that ImplicitCastExprs
16722 // do, as well a more specific one: this expression is only valid when
16723 // it appears *immediately* as an argument expression.
16724 return getDerived().TransformExpr(E->getSubExpr());
16725}
16726
16727template<typename Derived>
16728ExprResult TreeTransform<Derived>::
16729TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16730 TypeSourceInfo *TSInfo
16731 = getDerived().TransformType(E->getTypeInfoAsWritten());
16732 if (!TSInfo)
16733 return ExprError();
16734
16735 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16736 if (Result.isInvalid())
16737 return ExprError();
16738
16739 if (!getDerived().AlwaysRebuild() &&
16740 TSInfo == E->getTypeInfoAsWritten() &&
16741 Result.get() == E->getSubExpr())
16742 return E;
16743
16744 return SemaRef.ObjC().BuildObjCBridgedCast(
16745 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
16746 SubExpr: Result.get());
16747}
16748
16749template <typename Derived>
16750ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16751 ObjCAvailabilityCheckExpr *E) {
16752 return E;
16753}
16754
16755template<typename Derived>
16756ExprResult
16757TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16758 // Transform arguments.
16759 bool ArgChanged = false;
16760 SmallVector<Expr*, 8> Args;
16761 Args.reserve(N: E->getNumArgs());
16762 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16763 &ArgChanged))
16764 return ExprError();
16765
16766 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16767 // Class message: transform the receiver type.
16768 TypeSourceInfo *ReceiverTypeInfo
16769 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16770 if (!ReceiverTypeInfo)
16771 return ExprError();
16772
16773 // If nothing changed, just retain the existing message send.
16774 if (!getDerived().AlwaysRebuild() &&
16775 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16776 return SemaRef.MaybeBindToTemporary(E);
16777
16778 // Build a new class message send.
16779 SmallVector<SourceLocation, 16> SelLocs;
16780 E->getSelectorLocs(SelLocs);
16781 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16782 E->getSelector(),
16783 SelLocs,
16784 E->getMethodDecl(),
16785 E->getLeftLoc(),
16786 Args,
16787 E->getRightLoc());
16788 }
16789 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16790 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16791 if (!E->getMethodDecl())
16792 return ExprError();
16793
16794 // Build a new class message send to 'super'.
16795 SmallVector<SourceLocation, 16> SelLocs;
16796 E->getSelectorLocs(SelLocs);
16797 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16798 E->getSelector(),
16799 SelLocs,
16800 E->getReceiverType(),
16801 E->getMethodDecl(),
16802 E->getLeftLoc(),
16803 Args,
16804 E->getRightLoc());
16805 }
16806
16807 // Instance message: transform the receiver
16808 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16809 "Only class and instance messages may be instantiated");
16810 ExprResult Receiver
16811 = getDerived().TransformExpr(E->getInstanceReceiver());
16812 if (Receiver.isInvalid())
16813 return ExprError();
16814
16815 // If nothing changed, just retain the existing message send.
16816 if (!getDerived().AlwaysRebuild() &&
16817 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16818 return SemaRef.MaybeBindToTemporary(E);
16819
16820 // Build a new instance message send.
16821 SmallVector<SourceLocation, 16> SelLocs;
16822 E->getSelectorLocs(SelLocs);
16823 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16824 E->getSelector(),
16825 SelLocs,
16826 E->getMethodDecl(),
16827 E->getLeftLoc(),
16828 Args,
16829 E->getRightLoc());
16830}
16831
16832template<typename Derived>
16833ExprResult
16834TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16835 return E;
16836}
16837
16838template<typename Derived>
16839ExprResult
16840TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16841 return E;
16842}
16843
16844template<typename Derived>
16845ExprResult
16846TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16847 // Transform the base expression.
16848 ExprResult Base = getDerived().TransformExpr(E->getBase());
16849 if (Base.isInvalid())
16850 return ExprError();
16851
16852 // We don't need to transform the ivar; it will never change.
16853
16854 // If nothing changed, just retain the existing expression.
16855 if (!getDerived().AlwaysRebuild() &&
16856 Base.get() == E->getBase())
16857 return E;
16858
16859 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16860 E->getLocation(),
16861 E->isArrow(), E->isFreeIvar());
16862}
16863
16864template<typename Derived>
16865ExprResult
16866TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16867 // 'super' and types never change. Property never changes. Just
16868 // retain the existing expression.
16869 if (!E->isObjectReceiver())
16870 return E;
16871
16872 // Transform the base expression.
16873 ExprResult Base = getDerived().TransformExpr(E->getBase());
16874 if (Base.isInvalid())
16875 return ExprError();
16876
16877 // We don't need to transform the property; it will never change.
16878
16879 // If nothing changed, just retain the existing expression.
16880 if (!getDerived().AlwaysRebuild() &&
16881 Base.get() == E->getBase())
16882 return E;
16883
16884 if (E->isExplicitProperty())
16885 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16886 E->getExplicitProperty(),
16887 E->getLocation());
16888
16889 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16890 SemaRef.Context.PseudoObjectTy,
16891 E->getImplicitPropertyGetter(),
16892 E->getImplicitPropertySetter(),
16893 E->getLocation());
16894}
16895
16896template<typename Derived>
16897ExprResult
16898TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16899 // Transform the base expression.
16900 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16901 if (Base.isInvalid())
16902 return ExprError();
16903
16904 // Transform the key expression.
16905 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16906 if (Key.isInvalid())
16907 return ExprError();
16908
16909 // If nothing changed, just retain the existing expression.
16910 if (!getDerived().AlwaysRebuild() &&
16911 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16912 return E;
16913
16914 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16915 Base.get(), Key.get(),
16916 E->getAtIndexMethodDecl(),
16917 E->setAtIndexMethodDecl());
16918}
16919
16920template<typename Derived>
16921ExprResult
16922TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16923 // Transform the base expression.
16924 ExprResult Base = getDerived().TransformExpr(E->getBase());
16925 if (Base.isInvalid())
16926 return ExprError();
16927
16928 // If nothing changed, just retain the existing expression.
16929 if (!getDerived().AlwaysRebuild() &&
16930 Base.get() == E->getBase())
16931 return E;
16932
16933 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16934 E->getOpLoc(),
16935 E->isArrow());
16936}
16937
16938template<typename Derived>
16939ExprResult
16940TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16941 bool ArgumentChanged = false;
16942 SmallVector<Expr*, 8> SubExprs;
16943 SubExprs.reserve(N: E->getNumSubExprs());
16944 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16945 SubExprs, &ArgumentChanged))
16946 return ExprError();
16947
16948 if (!getDerived().AlwaysRebuild() &&
16949 !ArgumentChanged)
16950 return E;
16951
16952 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16953 SubExprs,
16954 E->getRParenLoc());
16955}
16956
16957template<typename Derived>
16958ExprResult
16959TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16960 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16961 if (SrcExpr.isInvalid())
16962 return ExprError();
16963
16964 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16965 if (!Type)
16966 return ExprError();
16967
16968 if (!getDerived().AlwaysRebuild() &&
16969 Type == E->getTypeSourceInfo() &&
16970 SrcExpr.get() == E->getSrcExpr())
16971 return E;
16972
16973 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16974 SrcExpr.get(), Type,
16975 E->getRParenLoc());
16976}
16977
16978template<typename Derived>
16979ExprResult
16980TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16981 BlockDecl *oldBlock = E->getBlockDecl();
16982
16983 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
16984 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16985
16986 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16987 blockScope->TheDecl->setBlockMissingReturnType(
16988 oldBlock->blockMissingReturnType());
16989
16990 SmallVector<ParmVarDecl*, 4> params;
16991 SmallVector<QualType, 4> paramTypes;
16992
16993 const FunctionProtoType *exprFunctionType = E->getFunctionType();
16994
16995 // Parameter substitution.
16996 Sema::ExtParameterInfoBuilder extParamInfos;
16997 if (getDerived().TransformFunctionTypeParams(
16998 E->getCaretLocation(), oldBlock->parameters(), nullptr,
16999 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17000 extParamInfos)) {
17001 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17002 return ExprError();
17003 }
17004
17005 QualType exprResultType =
17006 getDerived().TransformType(exprFunctionType->getReturnType());
17007
17008 auto epi = exprFunctionType->getExtProtoInfo();
17009 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17010
17011 QualType functionType =
17012 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17013 blockScope->FunctionType = functionType;
17014
17015 // Set the parameters on the block decl.
17016 if (!params.empty())
17017 blockScope->TheDecl->setParams(params);
17018
17019 if (!oldBlock->blockMissingReturnType()) {
17020 blockScope->HasImplicitReturnType = false;
17021 blockScope->ReturnType = exprResultType;
17022 }
17023
17024 // Transform the body
17025 StmtResult body = getDerived().TransformStmt(E->getBody());
17026 if (body.isInvalid()) {
17027 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17028 return ExprError();
17029 }
17030
17031#ifndef NDEBUG
17032 // In builds with assertions, make sure that we captured everything we
17033 // captured before.
17034 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17035 for (const auto &I : oldBlock->captures()) {
17036 VarDecl *oldCapture = I.getVariable();
17037
17038 // Ignore parameter packs.
17039 if (oldCapture->isParameterPack())
17040 continue;
17041
17042 VarDecl *newCapture =
17043 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17044 oldCapture));
17045 assert(blockScope->CaptureMap.count(newCapture));
17046 }
17047
17048 // The this pointer may not be captured by the instantiated block, even when
17049 // it's captured by the original block, if the expression causing the
17050 // capture is in the discarded branch of a constexpr if statement.
17051 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17052 "this pointer isn't captured in the old block");
17053 }
17054#endif
17055
17056 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17057 /*Scope=*/CurScope: nullptr);
17058}
17059
17060template<typename Derived>
17061ExprResult
17062TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17063 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17064 if (SrcExpr.isInvalid())
17065 return ExprError();
17066
17067 QualType Type = getDerived().TransformType(E->getType());
17068
17069 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17070 RParenLoc: E->getRParenLoc());
17071}
17072
17073template<typename Derived>
17074ExprResult
17075TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17076 bool ArgumentChanged = false;
17077 SmallVector<Expr*, 8> SubExprs;
17078 SubExprs.reserve(N: E->getNumSubExprs());
17079 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17080 SubExprs, &ArgumentChanged))
17081 return ExprError();
17082
17083 if (!getDerived().AlwaysRebuild() &&
17084 !ArgumentChanged)
17085 return E;
17086
17087 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17088 E->getOp(), E->getRParenLoc());
17089}
17090
17091//===----------------------------------------------------------------------===//
17092// Type reconstruction
17093//===----------------------------------------------------------------------===//
17094
17095template<typename Derived>
17096QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17097 SourceLocation Star) {
17098 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17099 Entity: getDerived().getBaseEntity());
17100}
17101
17102template<typename Derived>
17103QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17104 SourceLocation Star) {
17105 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17106 Entity: getDerived().getBaseEntity());
17107}
17108
17109template<typename Derived>
17110QualType
17111TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17112 bool WrittenAsLValue,
17113 SourceLocation Sigil) {
17114 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17115 Loc: Sigil, Entity: getDerived().getBaseEntity());
17116}
17117
17118template <typename Derived>
17119QualType TreeTransform<Derived>::RebuildMemberPointerType(
17120 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17121 SourceLocation Sigil) {
17122 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17123 Entity: getDerived().getBaseEntity());
17124}
17125
17126template<typename Derived>
17127QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17128 const ObjCTypeParamDecl *Decl,
17129 SourceLocation ProtocolLAngleLoc,
17130 ArrayRef<ObjCProtocolDecl *> Protocols,
17131 ArrayRef<SourceLocation> ProtocolLocs,
17132 SourceLocation ProtocolRAngleLoc) {
17133 return SemaRef.ObjC().BuildObjCTypeParamType(
17134 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17135 /*FailOnError=*/FailOnError: true);
17136}
17137
17138template<typename Derived>
17139QualType TreeTransform<Derived>::RebuildObjCObjectType(
17140 QualType BaseType,
17141 SourceLocation Loc,
17142 SourceLocation TypeArgsLAngleLoc,
17143 ArrayRef<TypeSourceInfo *> TypeArgs,
17144 SourceLocation TypeArgsRAngleLoc,
17145 SourceLocation ProtocolLAngleLoc,
17146 ArrayRef<ObjCProtocolDecl *> Protocols,
17147 ArrayRef<SourceLocation> ProtocolLocs,
17148 SourceLocation ProtocolRAngleLoc) {
17149 return SemaRef.ObjC().BuildObjCObjectType(
17150 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17151 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17152 /*FailOnError=*/FailOnError: true,
17153 /*Rebuilding=*/Rebuilding: true);
17154}
17155
17156template<typename Derived>
17157QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17158 QualType PointeeType,
17159 SourceLocation Star) {
17160 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17161}
17162
17163template <typename Derived>
17164QualType TreeTransform<Derived>::RebuildArrayType(
17165 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17166 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17167 if (SizeExpr || !Size)
17168 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17169 Quals: IndexTypeQuals, Brackets: BracketsRange,
17170 Entity: getDerived().getBaseEntity());
17171
17172 QualType Types[] = {
17173 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17174 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17175 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17176 };
17177 QualType SizeType;
17178 for (const auto &T : Types)
17179 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17180 SizeType = T;
17181 break;
17182 }
17183
17184 // Note that we can return a VariableArrayType here in the case where
17185 // the element type was a dependent VariableArrayType.
17186 IntegerLiteral *ArraySize
17187 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17188 /*FIXME*/l: BracketsRange.getBegin());
17189 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17190 Quals: IndexTypeQuals, Brackets: BracketsRange,
17191 Entity: getDerived().getBaseEntity());
17192}
17193
17194template <typename Derived>
17195QualType TreeTransform<Derived>::RebuildConstantArrayType(
17196 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17197 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17198 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17199 IndexTypeQuals, BracketsRange);
17200}
17201
17202template <typename Derived>
17203QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17204 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17205 SourceRange BracketsRange) {
17206 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17207 IndexTypeQuals, BracketsRange);
17208}
17209
17210template <typename Derived>
17211QualType TreeTransform<Derived>::RebuildVariableArrayType(
17212 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17213 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17214 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17215 SizeExpr,
17216 IndexTypeQuals, BracketsRange);
17217}
17218
17219template <typename Derived>
17220QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17221 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17222 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17223 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17224 SizeExpr,
17225 IndexTypeQuals, BracketsRange);
17226}
17227
17228template <typename Derived>
17229QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17230 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17231 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17232 AttrLoc: AttributeLoc);
17233}
17234
17235template <typename Derived>
17236QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17237 unsigned NumElements,
17238 VectorKind VecKind) {
17239 // FIXME: semantic checking!
17240 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17241}
17242
17243template <typename Derived>
17244QualType TreeTransform<Derived>::RebuildDependentVectorType(
17245 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17246 VectorKind VecKind) {
17247 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17248}
17249
17250template<typename Derived>
17251QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17252 unsigned NumElements,
17253 SourceLocation AttributeLoc) {
17254 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17255 NumElements, true);
17256 IntegerLiteral *VectorSize
17257 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17258 l: AttributeLoc);
17259 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17260}
17261
17262template<typename Derived>
17263QualType
17264TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17265 Expr *SizeExpr,
17266 SourceLocation AttributeLoc) {
17267 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17268}
17269
17270template <typename Derived>
17271QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17272 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17273 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17274 NumColumns);
17275}
17276
17277template <typename Derived>
17278QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17279 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17280 SourceLocation AttributeLoc) {
17281 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17282 AttrLoc: AttributeLoc);
17283}
17284
17285template <typename Derived>
17286QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17287 QualType T, MutableArrayRef<QualType> ParamTypes,
17288 const FunctionProtoType::ExtProtoInfo &EPI) {
17289 return SemaRef.BuildFunctionType(T, ParamTypes,
17290 Loc: getDerived().getBaseLocation(),
17291 Entity: getDerived().getBaseEntity(),
17292 EPI);
17293}
17294
17295template<typename Derived>
17296QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17297 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17298}
17299
17300template<typename Derived>
17301QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
17302 Decl *D) {
17303 assert(D && "no decl found");
17304 if (D->isInvalidDecl()) return QualType();
17305
17306 // FIXME: Doesn't account for ObjCInterfaceDecl!
17307 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17308 // A valid resolved using typename pack expansion decl can have multiple
17309 // UsingDecls, but they must each have exactly one type, and it must be
17310 // the same type in every case. But we must have at least one expansion!
17311 if (UPD->expansions().empty()) {
17312 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
17313 << UPD->isCXXClassMember() << UPD;
17314 return QualType();
17315 }
17316
17317 // We might still have some unresolved types. Try to pick a resolved type
17318 // if we can. The final instantiation will check that the remaining
17319 // unresolved types instantiate to the type we pick.
17320 QualType FallbackT;
17321 QualType T;
17322 for (auto *E : UPD->expansions()) {
17323 QualType ThisT = RebuildUnresolvedUsingType(Loc, D: E);
17324 if (ThisT.isNull())
17325 continue;
17326 else if (ThisT->getAs<UnresolvedUsingType>())
17327 FallbackT = ThisT;
17328 else if (T.isNull())
17329 T = ThisT;
17330 else
17331 assert(getSema().Context.hasSameType(ThisT, T) &&
17332 "mismatched resolved types in using pack expansion");
17333 }
17334 return T.isNull() ? FallbackT : T;
17335 } else if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17336 assert(Using->hasTypename() &&
17337 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17338
17339 // A valid resolved using typename decl points to exactly one type decl.
17340 assert(++Using->shadow_begin() == Using->shadow_end());
17341
17342 UsingShadowDecl *Shadow = *Using->shadow_begin();
17343 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: Loc))
17344 return QualType();
17345 return SemaRef.Context.getUsingType(
17346 Found: Shadow, Underlying: SemaRef.Context.getTypeDeclType(
17347 Decl: cast<TypeDecl>(Val: Shadow->getTargetDecl())));
17348 } else {
17349 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17350 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17351 return SemaRef.Context.getTypeDeclType(
17352 Decl: cast<UnresolvedUsingTypenameDecl>(Val: D));
17353 }
17354}
17355
17356template <typename Derived>
17357QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17358 TypeOfKind Kind) {
17359 return SemaRef.BuildTypeofExprType(E, Kind);
17360}
17361
17362template<typename Derived>
17363QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17364 TypeOfKind Kind) {
17365 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17366}
17367
17368template <typename Derived>
17369QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17370 return SemaRef.BuildDecltypeType(E);
17371}
17372
17373template <typename Derived>
17374QualType TreeTransform<Derived>::RebuildPackIndexingType(
17375 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17376 SourceLocation EllipsisLoc, bool FullySubstituted,
17377 ArrayRef<QualType> Expansions) {
17378 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17379 FullySubstituted, Expansions);
17380}
17381
17382template<typename Derived>
17383QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17384 UnaryTransformType::UTTKind UKind,
17385 SourceLocation Loc) {
17386 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17387}
17388
17389template<typename Derived>
17390QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17391 TemplateName Template,
17392 SourceLocation TemplateNameLoc,
17393 TemplateArgumentListInfo &TemplateArgs) {
17394 return SemaRef.CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs);
17395}
17396
17397template<typename Derived>
17398QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17399 SourceLocation KWLoc) {
17400 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17401}
17402
17403template<typename Derived>
17404QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17405 SourceLocation KWLoc,
17406 bool isReadPipe) {
17407 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17408 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17409}
17410
17411template <typename Derived>
17412QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17413 unsigned NumBits,
17414 SourceLocation Loc) {
17415 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17416 NumBits, true);
17417 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17418 type: SemaRef.Context.IntTy, l: Loc);
17419 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17420}
17421
17422template <typename Derived>
17423QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17424 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17425 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17426}
17427
17428template<typename Derived>
17429TemplateName
17430TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17431 bool TemplateKW,
17432 TemplateDecl *Template) {
17433 return SemaRef.Context.getQualifiedTemplateName(NNS: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17434 Template: TemplateName(Template));
17435}
17436
17437template<typename Derived>
17438TemplateName
17439TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17440 SourceLocation TemplateKWLoc,
17441 const IdentifierInfo &Name,
17442 SourceLocation NameLoc,
17443 QualType ObjectType,
17444 NamedDecl *FirstQualifierInScope,
17445 bool AllowInjectedClassName) {
17446 UnqualifiedId TemplateName;
17447 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17448 Sema::TemplateTy Template;
17449 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17450 TemplateName, ParsedType::make(P: ObjectType),
17451 /*EnteringContext=*/false, Template,
17452 AllowInjectedClassName);
17453 return Template.get();
17454}
17455
17456template<typename Derived>
17457TemplateName
17458TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17459 SourceLocation TemplateKWLoc,
17460 OverloadedOperatorKind Operator,
17461 SourceLocation NameLoc,
17462 QualType ObjectType,
17463 bool AllowInjectedClassName) {
17464 UnqualifiedId Name;
17465 // FIXME: Bogus location information.
17466 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17467 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17468 Sema::TemplateTy Template;
17469 getSema().ActOnTemplateName(
17470 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17471 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17472 return Template.get();
17473}
17474
17475template <typename Derived>
17476ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17477 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17478 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17479 Expr *Second) {
17480 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17481
17482 if (First->getObjectKind() == OK_ObjCProperty) {
17483 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17484 if (BinaryOperator::isAssignmentOp(Opc))
17485 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17486 Opcode: Opc, LHS: First, RHS: Second);
17487 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17488 if (Result.isInvalid())
17489 return ExprError();
17490 First = Result.get();
17491 }
17492
17493 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17494 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17495 if (Result.isInvalid())
17496 return ExprError();
17497 Second = Result.get();
17498 }
17499
17500 // Determine whether this should be a builtin operation.
17501 if (Op == OO_Subscript) {
17502 if (!First->getType()->isOverloadableType() &&
17503 !Second->getType()->isOverloadableType())
17504 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17505 OpLoc);
17506 } else if (Op == OO_Arrow) {
17507 // It is possible that the type refers to a RecoveryExpr created earlier
17508 // in the tree transformation.
17509 if (First->getType()->isDependentType())
17510 return ExprError();
17511 // -> is never a builtin operation.
17512 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17513 } else if (Second == nullptr || isPostIncDec) {
17514 if (!First->getType()->isOverloadableType() ||
17515 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17516 // The argument is not of overloadable type, or this is an expression
17517 // of the form &Class::member, so try to create a built-in unary
17518 // operation.
17519 UnaryOperatorKind Opc
17520 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17521
17522 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17523 }
17524 } else {
17525 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17526 !First->getType()->isOverloadableType() &&
17527 !Second->getType()->isOverloadableType()) {
17528 // Neither of the arguments is type-dependent or has an overloadable
17529 // type, so try to create a built-in binary operation.
17530 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17531 ExprResult Result
17532 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17533 if (Result.isInvalid())
17534 return ExprError();
17535
17536 return Result;
17537 }
17538 }
17539
17540 // Create the overloaded operator invocation for unary operators.
17541 if (!Second || isPostIncDec) {
17542 UnaryOperatorKind Opc
17543 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17544 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
17545 RequiresADL);
17546 }
17547
17548 // Create the overloaded operator invocation for binary operators.
17549 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17550 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
17551 LHS: First, RHS: Second, RequiresADL);
17552 if (Result.isInvalid())
17553 return ExprError();
17554
17555 return Result;
17556}
17557
17558template<typename Derived>
17559ExprResult
17560TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17561 SourceLocation OperatorLoc,
17562 bool isArrow,
17563 CXXScopeSpec &SS,
17564 TypeSourceInfo *ScopeType,
17565 SourceLocation CCLoc,
17566 SourceLocation TildeLoc,
17567 PseudoDestructorTypeStorage Destroyed) {
17568 QualType BaseType = Base->getType();
17569 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17570 (!isArrow && !BaseType->getAs<RecordType>()) ||
17571 (isArrow && BaseType->getAs<PointerType>() &&
17572 !BaseType->castAs<PointerType>()->getPointeeType()
17573 ->template getAs<RecordType>())){
17574 // This pseudo-destructor expression is still a pseudo-destructor.
17575 return SemaRef.BuildPseudoDestructorExpr(
17576 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
17577 CCLoc, TildeLoc, DestroyedType: Destroyed);
17578 }
17579
17580 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17581 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17582 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
17583 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17584 NameInfo.setNamedTypeInfo(DestroyedType);
17585
17586 // The scope type is now known to be a valid nested name specifier
17587 // component. Tack it on to the end of the nested name specifier.
17588 if (ScopeType) {
17589 if (!ScopeType->getType()->getAs<TagType>()) {
17590 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17591 diag::err_expected_class_or_namespace)
17592 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17593 return ExprError();
17594 }
17595 SS.Extend(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
17596 }
17597
17598 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17599 return getSema().BuildMemberReferenceExpr(Base, BaseType,
17600 OperatorLoc, isArrow,
17601 SS, TemplateKWLoc,
17602 /*FIXME: FirstQualifier*/ nullptr,
17603 NameInfo,
17604 /*TemplateArgs*/ nullptr,
17605 /*S*/nullptr);
17606}
17607
17608template<typename Derived>
17609StmtResult
17610TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17611 SourceLocation Loc = S->getBeginLoc();
17612 CapturedDecl *CD = S->getCapturedDecl();
17613 unsigned NumParams = CD->getNumParams();
17614 unsigned ContextParamPos = CD->getContextParamPosition();
17615 SmallVector<Sema::CapturedParamNameType, 4> Params;
17616 for (unsigned I = 0; I < NumParams; ++I) {
17617 if (I != ContextParamPos) {
17618 Params.push_back(
17619 Elt: std::make_pair(
17620 CD->getParam(i: I)->getName(),
17621 getDerived().TransformType(CD->getParam(i: I)->getType())));
17622 } else {
17623 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
17624 }
17625 }
17626 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17627 S->getCapturedRegionKind(), Params);
17628 StmtResult Body;
17629 {
17630 Sema::CompoundScopeRAII CompoundScope(getSema());
17631 Body = getDerived().TransformStmt(S->getCapturedStmt());
17632 }
17633
17634 if (Body.isInvalid()) {
17635 getSema().ActOnCapturedRegionError();
17636 return StmtError();
17637 }
17638
17639 return getSema().ActOnCapturedRegionEnd(Body.get());
17640}
17641
17642template <typename Derived>
17643StmtResult
17644TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17645 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17646 // function definition or instantiation of a function template specialization
17647 // and will therefore never appear in a dependent context.
17648 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17649 "context");
17650}
17651
17652template <typename Derived>
17653ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17654 // We can transform the base expression and allow argument resolution to fill
17655 // in the rest.
17656 return getDerived().TransformExpr(E->getArgLValue());
17657}
17658
17659} // end namespace clang
17660
17661#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
17662