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
4565 EnterExpressionEvaluationContext Eval(
4566 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated,
4567 /*LambdaContextDecl=*/nullptr,
4568 /*ExprContext=*/Sema::ExpressionEvaluationContextRecord::EK_Other,
4569 /*ShouldEnter=*/Kind == Sema::ConditionKind::ConstexprIf);
4570
4571 if (Var) {
4572 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4573 getDerived().TransformDefinition(Var->getLocation(), Var));
4574
4575 if (!ConditionVar)
4576 return Sema::ConditionError();
4577
4578 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4579 }
4580
4581 if (Expr) {
4582 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4583
4584 if (CondExpr.isInvalid())
4585 return Sema::ConditionError();
4586
4587 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4588 /*MissingOK=*/true);
4589 }
4590
4591 return Sema::ConditionResult();
4592}
4593
4594template <typename Derived>
4595NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4596 NestedNameSpecifierLoc NNS, QualType ObjectType,
4597 NamedDecl *FirstQualifierInScope) {
4598 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4599
4600 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4601 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4602 Qualifier = Qualifier.getPrefix())
4603 Qualifiers.push_back(Elt: Qualifier);
4604 };
4605 insertNNS(NNS);
4606
4607 CXXScopeSpec SS;
4608 while (!Qualifiers.empty()) {
4609 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4610 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4611
4612 switch (QNNS->getKind()) {
4613 case NestedNameSpecifier::Identifier: {
4614 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4615 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4616 ObjectType);
4617 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4618 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4619 return NestedNameSpecifierLoc();
4620 break;
4621 }
4622
4623 case NestedNameSpecifier::Namespace: {
4624 NamespaceDecl *NS =
4625 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4626 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4627 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4628 break;
4629 }
4630
4631 case NestedNameSpecifier::NamespaceAlias: {
4632 NamespaceAliasDecl *Alias =
4633 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4634 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4635 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4636 ColonColonLoc: Q.getLocalEndLoc());
4637 break;
4638 }
4639
4640 case NestedNameSpecifier::Global:
4641 // There is no meaningful transformation that one could perform on the
4642 // global scope.
4643 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4644 break;
4645
4646 case NestedNameSpecifier::Super: {
4647 CXXRecordDecl *RD =
4648 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4649 SourceLocation(), QNNS->getAsRecordDecl()));
4650 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4651 break;
4652 }
4653
4654 case NestedNameSpecifier::TypeSpec: {
4655 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4656 FirstQualifierInScope, SS);
4657
4658 if (!TL)
4659 return NestedNameSpecifierLoc();
4660
4661 QualType T = TL.getType();
4662 if (T->isDependentType() || T->isRecordType() ||
4663 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4664 if (T->isEnumeralType())
4665 SemaRef.Diag(Loc: TL.getBeginLoc(),
4666 DiagID: diag::warn_cxx98_compat_enum_nested_name_spec);
4667
4668 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4669 SS.Adopt(Other: ETL.getQualifierLoc());
4670 TL = ETL.getNamedTypeLoc();
4671 }
4672
4673 SS.Extend(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4674 break;
4675 }
4676 // If the nested-name-specifier is an invalid type def, don't emit an
4677 // error because a previous error should have already been emitted.
4678 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4679 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4680 SemaRef.Diag(Loc: TL.getBeginLoc(), DiagID: diag::err_nested_name_spec_non_tag)
4681 << T << SS.getRange();
4682 }
4683 return NestedNameSpecifierLoc();
4684 }
4685 }
4686
4687 // The qualifier-in-scope and object type only apply to the leftmost entity.
4688 FirstQualifierInScope = nullptr;
4689 ObjectType = QualType();
4690 }
4691
4692 // Don't rebuild the nested-name-specifier if we don't have to.
4693 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4694 !getDerived().AlwaysRebuild())
4695 return NNS;
4696
4697 // If we can re-use the source-location data from the original
4698 // nested-name-specifier, do so.
4699 if (SS.location_size() == NNS.getDataLength() &&
4700 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4701 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4702
4703 // Allocate new nested-name-specifier location information.
4704 return SS.getWithLocInContext(Context&: SemaRef.Context);
4705}
4706
4707template<typename Derived>
4708DeclarationNameInfo
4709TreeTransform<Derived>
4710::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4711 DeclarationName Name = NameInfo.getName();
4712 if (!Name)
4713 return DeclarationNameInfo();
4714
4715 switch (Name.getNameKind()) {
4716 case DeclarationName::Identifier:
4717 case DeclarationName::ObjCZeroArgSelector:
4718 case DeclarationName::ObjCOneArgSelector:
4719 case DeclarationName::ObjCMultiArgSelector:
4720 case DeclarationName::CXXOperatorName:
4721 case DeclarationName::CXXLiteralOperatorName:
4722 case DeclarationName::CXXUsingDirective:
4723 return NameInfo;
4724
4725 case DeclarationName::CXXDeductionGuideName: {
4726 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4727 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4728 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4729 if (!NewTemplate)
4730 return DeclarationNameInfo();
4731
4732 DeclarationNameInfo NewNameInfo(NameInfo);
4733 NewNameInfo.setName(
4734 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4735 return NewNameInfo;
4736 }
4737
4738 case DeclarationName::CXXConstructorName:
4739 case DeclarationName::CXXDestructorName:
4740 case DeclarationName::CXXConversionFunctionName: {
4741 TypeSourceInfo *NewTInfo;
4742 CanQualType NewCanTy;
4743 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4744 NewTInfo = getDerived().TransformType(OldTInfo);
4745 if (!NewTInfo)
4746 return DeclarationNameInfo();
4747 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4748 }
4749 else {
4750 NewTInfo = nullptr;
4751 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4752 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4753 if (NewT.isNull())
4754 return DeclarationNameInfo();
4755 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4756 }
4757
4758 DeclarationName NewName
4759 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4760 Ty: NewCanTy);
4761 DeclarationNameInfo NewNameInfo(NameInfo);
4762 NewNameInfo.setName(NewName);
4763 NewNameInfo.setNamedTypeInfo(NewTInfo);
4764 return NewNameInfo;
4765 }
4766 }
4767
4768 llvm_unreachable("Unknown name kind.");
4769}
4770
4771template <typename Derived>
4772TemplateName TreeTransform<Derived>::RebuildTemplateName(
4773 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4774 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4775 QualType ObjectType, NamedDecl *FirstQualifierInScope,
4776 bool AllowInjectedClassName) {
4777 if (const IdentifierInfo *II = IO.getIdentifier()) {
4778 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4779 ObjectType, FirstQualifierInScope,
4780 AllowInjectedClassName);
4781 }
4782 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4783 NameLoc, ObjectType,
4784 AllowInjectedClassName);
4785}
4786
4787template<typename Derived>
4788TemplateName
4789TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4790 TemplateName Name,
4791 SourceLocation NameLoc,
4792 QualType ObjectType,
4793 NamedDecl *FirstQualifierInScope,
4794 bool AllowInjectedClassName) {
4795 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4796 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4797 assert(Template && "qualified template name must refer to a template");
4798
4799 TemplateDecl *TransTemplate
4800 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4801 Template));
4802 if (!TransTemplate)
4803 return TemplateName();
4804
4805 if (!getDerived().AlwaysRebuild() &&
4806 SS.getScopeRep() == QTN->getQualifier() &&
4807 TransTemplate == Template)
4808 return Name;
4809
4810 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4811 TransTemplate);
4812 }
4813
4814 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4815 if (SS.getScopeRep()) {
4816 // These apply to the scope specifier, not the template.
4817 ObjectType = QualType();
4818 FirstQualifierInScope = nullptr;
4819 }
4820
4821 if (!getDerived().AlwaysRebuild() &&
4822 SS.getScopeRep() == DTN->getQualifier() &&
4823 ObjectType.isNull())
4824 return Name;
4825
4826 // FIXME: Preserve the location of the "template" keyword.
4827 SourceLocation TemplateKWLoc = NameLoc;
4828 return getDerived().RebuildTemplateName(
4829 SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType,
4830 FirstQualifierInScope, AllowInjectedClassName);
4831 }
4832
4833 // FIXME: Try to preserve more of the TemplateName.
4834 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4835 TemplateDecl *TransTemplate
4836 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4837 Template));
4838 if (!TransTemplate)
4839 return TemplateName();
4840
4841 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4842 TransTemplate);
4843 }
4844
4845 if (SubstTemplateTemplateParmPackStorage *SubstPack
4846 = Name.getAsSubstTemplateTemplateParmPack()) {
4847 return getDerived().RebuildTemplateName(
4848 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4849 SubstPack->getIndex(), SubstPack->getFinal());
4850 }
4851
4852 // These should be getting filtered out before they reach the AST.
4853 llvm_unreachable("overloaded function decl survived to here");
4854}
4855
4856template<typename Derived>
4857void TreeTransform<Derived>::InventTemplateArgumentLoc(
4858 const TemplateArgument &Arg,
4859 TemplateArgumentLoc &Output) {
4860 Output = getSema().getTrivialTemplateArgumentLoc(
4861 Arg, QualType(), getDerived().getBaseLocation());
4862}
4863
4864template <typename Derived>
4865bool TreeTransform<Derived>::TransformTemplateArgument(
4866 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4867 bool Uneval) {
4868 const TemplateArgument &Arg = Input.getArgument();
4869 switch (Arg.getKind()) {
4870 case TemplateArgument::Null:
4871 case TemplateArgument::Pack:
4872 llvm_unreachable("Unexpected TemplateArgument");
4873
4874 case TemplateArgument::Integral:
4875 case TemplateArgument::NullPtr:
4876 case TemplateArgument::Declaration:
4877 case TemplateArgument::StructuralValue: {
4878 // Transform a resolved template argument straight to a resolved template
4879 // argument. We get here when substituting into an already-substituted
4880 // template type argument during concept satisfaction checking.
4881 QualType T = Arg.getNonTypeTemplateArgumentType();
4882 QualType NewT = getDerived().TransformType(T);
4883 if (NewT.isNull())
4884 return true;
4885
4886 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4887 ? Arg.getAsDecl()
4888 : nullptr;
4889 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4890 getDerived().getBaseLocation(), D))
4891 : nullptr;
4892 if (D && !NewD)
4893 return true;
4894
4895 if (NewT == T && D == NewD)
4896 Output = Input;
4897 else if (Arg.getKind() == TemplateArgument::Integral)
4898 Output = TemplateArgumentLoc(
4899 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4900 TemplateArgumentLocInfo());
4901 else if (Arg.getKind() == TemplateArgument::NullPtr)
4902 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4903 TemplateArgumentLocInfo());
4904 else if (Arg.getKind() == TemplateArgument::Declaration)
4905 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4906 TemplateArgumentLocInfo());
4907 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4908 Output = TemplateArgumentLoc(
4909 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4910 TemplateArgumentLocInfo());
4911 else
4912 llvm_unreachable("unexpected template argument kind");
4913
4914 return false;
4915 }
4916
4917 case TemplateArgument::Type: {
4918 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4919 if (!DI)
4920 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4921
4922 DI = getDerived().TransformType(DI);
4923 if (!DI)
4924 return true;
4925
4926 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4927 return false;
4928 }
4929
4930 case TemplateArgument::Template: {
4931 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4932 if (QualifierLoc) {
4933 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4934 if (!QualifierLoc)
4935 return true;
4936 }
4937
4938 CXXScopeSpec SS;
4939 SS.Adopt(Other: QualifierLoc);
4940 TemplateName Template = getDerived().TransformTemplateName(
4941 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4942 if (Template.isNull())
4943 return true;
4944
4945 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4946 QualifierLoc, Input.getTemplateNameLoc());
4947 return false;
4948 }
4949
4950 case TemplateArgument::TemplateExpansion:
4951 llvm_unreachable("Caller should expand pack expansions");
4952
4953 case TemplateArgument::Expression: {
4954 // Template argument expressions are constant expressions.
4955 EnterExpressionEvaluationContext Unevaluated(
4956 getSema(),
4957 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4958 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4959 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4960 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4961
4962 Expr *InputExpr = Input.getSourceExpression();
4963 if (!InputExpr)
4964 InputExpr = Input.getArgument().getAsExpr();
4965
4966 ExprResult E = getDerived().TransformExpr(InputExpr);
4967 E = SemaRef.ActOnConstantExpression(Res: E);
4968 if (E.isInvalid())
4969 return true;
4970 Output = TemplateArgumentLoc(
4971 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
4972 return false;
4973 }
4974 }
4975
4976 // Work around bogus GCC warning
4977 return true;
4978}
4979
4980/// Iterator adaptor that invents template argument location information
4981/// for each of the template arguments in its underlying iterator.
4982template<typename Derived, typename InputIterator>
4983class TemplateArgumentLocInventIterator {
4984 TreeTransform<Derived> &Self;
4985 InputIterator Iter;
4986
4987public:
4988 typedef TemplateArgumentLoc value_type;
4989 typedef TemplateArgumentLoc reference;
4990 typedef typename std::iterator_traits<InputIterator>::difference_type
4991 difference_type;
4992 typedef std::input_iterator_tag iterator_category;
4993
4994 class pointer {
4995 TemplateArgumentLoc Arg;
4996
4997 public:
4998 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4999
5000 const TemplateArgumentLoc *operator->() const { return &Arg; }
5001 };
5002
5003 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
5004 InputIterator Iter)
5005 : Self(Self), Iter(Iter) { }
5006
5007 TemplateArgumentLocInventIterator &operator++() {
5008 ++Iter;
5009 return *this;
5010 }
5011
5012 TemplateArgumentLocInventIterator operator++(int) {
5013 TemplateArgumentLocInventIterator Old(*this);
5014 ++(*this);
5015 return Old;
5016 }
5017
5018 reference operator*() const {
5019 TemplateArgumentLoc Result;
5020 Self.InventTemplateArgumentLoc(*Iter, Result);
5021 return Result;
5022 }
5023
5024 pointer operator->() const { return pointer(**this); }
5025
5026 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5027 const TemplateArgumentLocInventIterator &Y) {
5028 return X.Iter == Y.Iter;
5029 }
5030
5031 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5032 const TemplateArgumentLocInventIterator &Y) {
5033 return X.Iter != Y.Iter;
5034 }
5035};
5036
5037template<typename Derived>
5038template<typename InputIterator>
5039bool TreeTransform<Derived>::TransformTemplateArguments(
5040 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5041 bool Uneval) {
5042 for (; First != Last; ++First) {
5043 TemplateArgumentLoc Out;
5044 TemplateArgumentLoc In = *First;
5045
5046 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5047 // Unpack argument packs, which we translate them into separate
5048 // arguments.
5049 // FIXME: We could do much better if we could guarantee that the
5050 // TemplateArgumentLocInfo for the pack expansion would be usable for
5051 // all of the template arguments in the argument pack.
5052 typedef TemplateArgumentLocInventIterator<Derived,
5053 TemplateArgument::pack_iterator>
5054 PackLocIterator;
5055 if (TransformTemplateArguments(PackLocIterator(*this,
5056 In.getArgument().pack_begin()),
5057 PackLocIterator(*this,
5058 In.getArgument().pack_end()),
5059 Outputs, Uneval))
5060 return true;
5061
5062 continue;
5063 }
5064
5065 if (In.getArgument().isPackExpansion()) {
5066 // We have a pack expansion, for which we will be substituting into
5067 // the pattern.
5068 SourceLocation Ellipsis;
5069 UnsignedOrNone OrigNumExpansions = std::nullopt;
5070 TemplateArgumentLoc Pattern
5071 = getSema().getTemplateArgumentPackExpansionPattern(
5072 In, Ellipsis, OrigNumExpansions);
5073
5074 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5075 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5076 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5077
5078 // Determine whether the set of unexpanded parameter packs can and should
5079 // be expanded.
5080 bool Expand = true;
5081 bool RetainExpansion = false;
5082 UnsignedOrNone NumExpansions = OrigNumExpansions;
5083 if (getDerived().TryExpandParameterPacks(Ellipsis,
5084 Pattern.getSourceRange(),
5085 Unexpanded,
5086 Expand,
5087 RetainExpansion,
5088 NumExpansions))
5089 return true;
5090
5091 if (!Expand) {
5092 // The transform has determined that we should perform a simple
5093 // transformation on the pack expansion, producing another pack
5094 // expansion.
5095 TemplateArgumentLoc OutPattern;
5096 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5097 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5098 return true;
5099
5100 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5101 NumExpansions);
5102 if (Out.getArgument().isNull())
5103 return true;
5104
5105 Outputs.addArgument(Loc: Out);
5106 continue;
5107 }
5108
5109 // The transform has determined that we should perform an elementwise
5110 // expansion of the pattern. Do so.
5111 for (unsigned I = 0; I != *NumExpansions; ++I) {
5112 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5113
5114 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5115 return true;
5116
5117 if (Out.getArgument().containsUnexpandedParameterPack()) {
5118 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5119 OrigNumExpansions);
5120 if (Out.getArgument().isNull())
5121 return true;
5122 }
5123
5124 Outputs.addArgument(Loc: Out);
5125 }
5126
5127 // If we're supposed to retain a pack expansion, do so by temporarily
5128 // forgetting the partially-substituted parameter pack.
5129 if (RetainExpansion) {
5130 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5131
5132 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5133 return true;
5134
5135 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5136 OrigNumExpansions);
5137 if (Out.getArgument().isNull())
5138 return true;
5139
5140 Outputs.addArgument(Loc: Out);
5141 }
5142
5143 continue;
5144 }
5145
5146 // The simple case:
5147 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5148 return true;
5149
5150 Outputs.addArgument(Loc: Out);
5151 }
5152
5153 return false;
5154
5155}
5156
5157//===----------------------------------------------------------------------===//
5158// Type transformation
5159//===----------------------------------------------------------------------===//
5160
5161template<typename Derived>
5162QualType TreeTransform<Derived>::TransformType(QualType T) {
5163 if (getDerived().AlreadyTransformed(T))
5164 return T;
5165
5166 // Temporary workaround. All of these transformations should
5167 // eventually turn into transformations on TypeLocs.
5168 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5169 getDerived().getBaseLocation());
5170
5171 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5172
5173 if (!NewDI)
5174 return QualType();
5175
5176 return NewDI->getType();
5177}
5178
5179template<typename Derived>
5180TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5181 // Refine the base location to the type's location.
5182 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5183 getDerived().getBaseEntity());
5184 if (getDerived().AlreadyTransformed(DI->getType()))
5185 return DI;
5186
5187 TypeLocBuilder TLB;
5188
5189 TypeLoc TL = DI->getTypeLoc();
5190 TLB.reserve(Requested: TL.getFullDataSize());
5191
5192 QualType Result = getDerived().TransformType(TLB, TL);
5193 if (Result.isNull())
5194 return nullptr;
5195
5196 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5197}
5198
5199template<typename Derived>
5200QualType
5201TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5202 switch (T.getTypeLocClass()) {
5203#define ABSTRACT_TYPELOC(CLASS, PARENT)
5204#define TYPELOC(CLASS, PARENT) \
5205 case TypeLoc::CLASS: \
5206 return getDerived().Transform##CLASS##Type(TLB, \
5207 T.castAs<CLASS##TypeLoc>());
5208#include "clang/AST/TypeLocNodes.def"
5209 }
5210
5211 llvm_unreachable("unhandled type loc!");
5212}
5213
5214template<typename Derived>
5215QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5216 if (!isa<DependentNameType>(Val: T))
5217 return TransformType(T);
5218
5219 if (getDerived().AlreadyTransformed(T))
5220 return T;
5221 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5222 getDerived().getBaseLocation());
5223 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5224 return NewDI ? NewDI->getType() : QualType();
5225}
5226
5227template<typename Derived>
5228TypeSourceInfo *
5229TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5230 if (!isa<DependentNameType>(Val: DI->getType()))
5231 return TransformType(DI);
5232
5233 // Refine the base location to the type's location.
5234 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5235 getDerived().getBaseEntity());
5236 if (getDerived().AlreadyTransformed(DI->getType()))
5237 return DI;
5238
5239 TypeLocBuilder TLB;
5240
5241 TypeLoc TL = DI->getTypeLoc();
5242 TLB.reserve(Requested: TL.getFullDataSize());
5243
5244 auto QTL = TL.getAs<QualifiedTypeLoc>();
5245 if (QTL)
5246 TL = QTL.getUnqualifiedLoc();
5247
5248 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5249
5250 QualType Result = getDerived().TransformDependentNameType(
5251 TLB, DNTL, /*DeducedTSTContext*/true);
5252 if (Result.isNull())
5253 return nullptr;
5254
5255 if (QTL) {
5256 Result = getDerived().RebuildQualifiedType(Result, QTL);
5257 if (Result.isNull())
5258 return nullptr;
5259 TLB.TypeWasModifiedSafely(T: Result);
5260 }
5261
5262 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5263}
5264
5265template<typename Derived>
5266QualType
5267TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5268 QualifiedTypeLoc T) {
5269 QualType Result;
5270 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5271 auto SuppressObjCLifetime =
5272 T.getType().getLocalQualifiers().hasObjCLifetime();
5273 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5274 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5275 SuppressObjCLifetime);
5276 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5277 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5278 TLB, STTP, SuppressObjCLifetime);
5279 } else {
5280 Result = getDerived().TransformType(TLB, UnqualTL);
5281 }
5282
5283 if (Result.isNull())
5284 return QualType();
5285
5286 Result = getDerived().RebuildQualifiedType(Result, T);
5287
5288 if (Result.isNull())
5289 return QualType();
5290
5291 // RebuildQualifiedType might have updated the type, but not in a way
5292 // that invalidates the TypeLoc. (There's no location information for
5293 // qualifiers.)
5294 TLB.TypeWasModifiedSafely(T: Result);
5295
5296 return Result;
5297}
5298
5299template <typename Derived>
5300QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5301 QualifiedTypeLoc TL) {
5302
5303 SourceLocation Loc = TL.getBeginLoc();
5304 Qualifiers Quals = TL.getType().getLocalQualifiers();
5305
5306 if ((T.getAddressSpace() != LangAS::Default &&
5307 Quals.getAddressSpace() != LangAS::Default) &&
5308 T.getAddressSpace() != Quals.getAddressSpace()) {
5309 SemaRef.Diag(Loc, DiagID: diag::err_address_space_mismatch_templ_inst)
5310 << TL.getType() << T;
5311 return QualType();
5312 }
5313
5314 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5315 if (LocalPointerAuth.isPresent()) {
5316 if (T.getPointerAuth().isPresent()) {
5317 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_redundant) << TL.getType();
5318 return QualType();
5319 }
5320 if (!T->isDependentType()) {
5321 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5322 SemaRef.Diag(Loc, DiagID: diag::err_ptrauth_qualifier_invalid_target) << T;
5323 return QualType();
5324 }
5325 }
5326 }
5327 // C++ [dcl.fct]p7:
5328 // [When] adding cv-qualifications on top of the function type [...] the
5329 // cv-qualifiers are ignored.
5330 if (T->isFunctionType()) {
5331 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5332 AddressSpace: Quals.getAddressSpace());
5333 return T;
5334 }
5335
5336 // C++ [dcl.ref]p1:
5337 // when the cv-qualifiers are introduced through the use of a typedef-name
5338 // or decltype-specifier [...] the cv-qualifiers are ignored.
5339 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5340 // applied to a reference type.
5341 if (T->isReferenceType()) {
5342 // The only qualifier that applies to a reference type is restrict.
5343 if (!Quals.hasRestrict())
5344 return T;
5345 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5346 }
5347
5348 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5349 // resulting type.
5350 if (Quals.hasObjCLifetime()) {
5351 if (!T->isObjCLifetimeType() && !T->isDependentType())
5352 Quals.removeObjCLifetime();
5353 else if (T.getObjCLifetime()) {
5354 // Objective-C ARC:
5355 // A lifetime qualifier applied to a substituted template parameter
5356 // overrides the lifetime qualifier from the template argument.
5357 const AutoType *AutoTy;
5358 if ((AutoTy = dyn_cast<AutoType>(Val&: T)) && AutoTy->isDeduced()) {
5359 // 'auto' types behave the same way as template parameters.
5360 QualType Deduced = AutoTy->getDeducedType();
5361 Qualifiers Qs = Deduced.getQualifiers();
5362 Qs.removeObjCLifetime();
5363 Deduced =
5364 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5365 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5366 IsDependent: AutoTy->isDependentType(),
5367 /*isPack=*/IsPack: false,
5368 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5369 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5370 } else {
5371 // Otherwise, complain about the addition of a qualifier to an
5372 // already-qualified type.
5373 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5374 SemaRef.Diag(Loc, DiagID: diag::err_attr_objc_ownership_redundant) << T;
5375 Quals.removeObjCLifetime();
5376 }
5377 }
5378 }
5379
5380 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5381}
5382
5383template<typename Derived>
5384TypeLoc
5385TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5386 QualType ObjectType,
5387 NamedDecl *UnqualLookup,
5388 CXXScopeSpec &SS) {
5389 if (getDerived().AlreadyTransformed(TL.getType()))
5390 return TL;
5391
5392 TypeSourceInfo *TSI =
5393 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5394 if (TSI)
5395 return TSI->getTypeLoc();
5396 return TypeLoc();
5397}
5398
5399template<typename Derived>
5400TypeSourceInfo *
5401TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5402 QualType ObjectType,
5403 NamedDecl *UnqualLookup,
5404 CXXScopeSpec &SS) {
5405 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5406 return TSInfo;
5407
5408 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5409 FirstQualifierInScope: UnqualLookup, SS);
5410}
5411
5412template <typename Derived>
5413TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5414 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5415 CXXScopeSpec &SS) {
5416 QualType T = TL.getType();
5417 assert(!getDerived().AlreadyTransformed(T));
5418
5419 TypeLocBuilder TLB;
5420 QualType Result;
5421
5422 if (isa<TemplateSpecializationType>(Val: T)) {
5423 TemplateSpecializationTypeLoc SpecTL =
5424 TL.castAs<TemplateSpecializationTypeLoc>();
5425
5426 TemplateName Template = getDerived().TransformTemplateName(
5427 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5428 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5429 if (Template.isNull())
5430 return nullptr;
5431
5432 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5433 Template);
5434 } else if (isa<DependentTemplateSpecializationType>(Val: T)) {
5435 DependentTemplateSpecializationTypeLoc SpecTL =
5436 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5437
5438 const IdentifierInfo *II = SpecTL.getTypePtr()
5439 ->getDependentTemplateName()
5440 .getName()
5441 .getIdentifier();
5442 TemplateName Template = getDerived().RebuildTemplateName(
5443 SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(),
5444 ObjectType, UnqualLookup,
5445 /*AllowInjectedClassName*/ true);
5446 if (Template.isNull())
5447 return nullptr;
5448
5449 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5450 SpecTL,
5451 Template,
5452 SS);
5453 } else {
5454 // Nothing special needs to be done for these.
5455 Result = getDerived().TransformType(TLB, TL);
5456 }
5457
5458 if (Result.isNull())
5459 return nullptr;
5460
5461 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5462}
5463
5464template <class TyLoc> static inline
5465QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5466 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5467 NewT.setNameLoc(T.getNameLoc());
5468 return T.getType();
5469}
5470
5471template<typename Derived>
5472QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5473 BuiltinTypeLoc T) {
5474 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T: T.getType());
5475 NewT.setBuiltinLoc(T.getBuiltinLoc());
5476 if (T.needsExtraLocalData())
5477 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5478 return T.getType();
5479}
5480
5481template<typename Derived>
5482QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5483 ComplexTypeLoc T) {
5484 // FIXME: recurse?
5485 return TransformTypeSpecType(TLB, T);
5486}
5487
5488template <typename Derived>
5489QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5490 AdjustedTypeLoc TL) {
5491 // Adjustments applied during transformation are handled elsewhere.
5492 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5493}
5494
5495template<typename Derived>
5496QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5497 DecayedTypeLoc TL) {
5498 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5499 if (OriginalType.isNull())
5500 return QualType();
5501
5502 QualType Result = TL.getType();
5503 if (getDerived().AlwaysRebuild() ||
5504 OriginalType != TL.getOriginalLoc().getType())
5505 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5506 TLB.push<DecayedTypeLoc>(T: Result);
5507 // Nothing to set for DecayedTypeLoc.
5508 return Result;
5509}
5510
5511template <typename Derived>
5512QualType
5513TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5514 ArrayParameterTypeLoc TL) {
5515 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5516 if (OriginalType.isNull())
5517 return QualType();
5518
5519 QualType Result = TL.getType();
5520 if (getDerived().AlwaysRebuild() ||
5521 OriginalType != TL.getElementLoc().getType())
5522 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5523 TLB.push<ArrayParameterTypeLoc>(T: Result);
5524 // Nothing to set for ArrayParameterTypeLoc.
5525 return Result;
5526}
5527
5528template<typename Derived>
5529QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5530 PointerTypeLoc TL) {
5531 QualType PointeeType
5532 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5533 if (PointeeType.isNull())
5534 return QualType();
5535
5536 QualType Result = TL.getType();
5537 if (PointeeType->getAs<ObjCObjectType>()) {
5538 // A dependent pointer type 'T *' has is being transformed such
5539 // that an Objective-C class type is being replaced for 'T'. The
5540 // resulting pointer type is an ObjCObjectPointerType, not a
5541 // PointerType.
5542 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5543
5544 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
5545 NewT.setStarLoc(TL.getStarLoc());
5546 return Result;
5547 }
5548
5549 if (getDerived().AlwaysRebuild() ||
5550 PointeeType != TL.getPointeeLoc().getType()) {
5551 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5552 if (Result.isNull())
5553 return QualType();
5554 }
5555
5556 // Objective-C ARC can add lifetime qualifiers to the type that we're
5557 // pointing to.
5558 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5559
5560 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(T: Result);
5561 NewT.setSigilLoc(TL.getSigilLoc());
5562 return Result;
5563}
5564
5565template<typename Derived>
5566QualType
5567TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5568 BlockPointerTypeLoc TL) {
5569 QualType PointeeType
5570 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5571 if (PointeeType.isNull())
5572 return QualType();
5573
5574 QualType Result = TL.getType();
5575 if (getDerived().AlwaysRebuild() ||
5576 PointeeType != TL.getPointeeLoc().getType()) {
5577 Result = getDerived().RebuildBlockPointerType(PointeeType,
5578 TL.getSigilLoc());
5579 if (Result.isNull())
5580 return QualType();
5581 }
5582
5583 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(T: Result);
5584 NewT.setSigilLoc(TL.getSigilLoc());
5585 return Result;
5586}
5587
5588/// Transforms a reference type. Note that somewhat paradoxically we
5589/// don't care whether the type itself is an l-value type or an r-value
5590/// type; we only care if the type was *written* as an l-value type
5591/// or an r-value type.
5592template<typename Derived>
5593QualType
5594TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5595 ReferenceTypeLoc TL) {
5596 const ReferenceType *T = TL.getTypePtr();
5597
5598 // Note that this works with the pointee-as-written.
5599 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5600 if (PointeeType.isNull())
5601 return QualType();
5602
5603 QualType Result = TL.getType();
5604 if (getDerived().AlwaysRebuild() ||
5605 PointeeType != T->getPointeeTypeAsWritten()) {
5606 Result = getDerived().RebuildReferenceType(PointeeType,
5607 T->isSpelledAsLValue(),
5608 TL.getSigilLoc());
5609 if (Result.isNull())
5610 return QualType();
5611 }
5612
5613 // Objective-C ARC can add lifetime qualifiers to the type that we're
5614 // referring to.
5615 TLB.TypeWasModifiedSafely(
5616 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5617
5618 // r-value references can be rebuilt as l-value references.
5619 ReferenceTypeLoc NewTL;
5620 if (isa<LValueReferenceType>(Val: Result))
5621 NewTL = TLB.push<LValueReferenceTypeLoc>(T: Result);
5622 else
5623 NewTL = TLB.push<RValueReferenceTypeLoc>(T: Result);
5624 NewTL.setSigilLoc(TL.getSigilLoc());
5625
5626 return Result;
5627}
5628
5629template<typename Derived>
5630QualType
5631TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5632 LValueReferenceTypeLoc TL) {
5633 return TransformReferenceType(TLB, TL);
5634}
5635
5636template<typename Derived>
5637QualType
5638TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5639 RValueReferenceTypeLoc TL) {
5640 return TransformReferenceType(TLB, TL);
5641}
5642
5643template<typename Derived>
5644QualType
5645TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5646 MemberPointerTypeLoc TL) {
5647 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5648 if (PointeeType.isNull())
5649 return QualType();
5650
5651 const MemberPointerType *T = TL.getTypePtr();
5652
5653 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5654 NestedNameSpecifierLoc NewQualifierLoc =
5655 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5656 if (!NewQualifierLoc)
5657 return QualType();
5658
5659 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5660 if (OldCls) {
5661 NewCls = cast_or_null<CXXRecordDecl>(
5662 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5663 if (!NewCls)
5664 return QualType();
5665 }
5666
5667 QualType Result = TL.getType();
5668 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5669 NewQualifierLoc.getNestedNameSpecifier() !=
5670 OldQualifierLoc.getNestedNameSpecifier() ||
5671 NewCls != OldCls) {
5672 CXXScopeSpec SS;
5673 SS.Adopt(Other: NewQualifierLoc);
5674 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5675 TL.getStarLoc());
5676 if (Result.isNull())
5677 return QualType();
5678 }
5679
5680 // If we had to adjust the pointee type when building a member pointer, make
5681 // sure to push TypeLoc info for it.
5682 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5683 if (MPT && PointeeType != MPT->getPointeeType()) {
5684 assert(isa<AdjustedType>(MPT->getPointeeType()));
5685 TLB.push<AdjustedTypeLoc>(T: MPT->getPointeeType());
5686 }
5687
5688 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(T: Result);
5689 NewTL.setSigilLoc(TL.getSigilLoc());
5690 NewTL.setQualifierLoc(NewQualifierLoc);
5691
5692 return Result;
5693}
5694
5695template<typename Derived>
5696QualType
5697TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5698 ConstantArrayTypeLoc TL) {
5699 const ConstantArrayType *T = TL.getTypePtr();
5700 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5701 if (ElementType.isNull())
5702 return QualType();
5703
5704 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5705 Expr *OldSize = TL.getSizeExpr();
5706 if (!OldSize)
5707 OldSize = const_cast<Expr*>(T->getSizeExpr());
5708 Expr *NewSize = nullptr;
5709 if (OldSize) {
5710 EnterExpressionEvaluationContext Unevaluated(
5711 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5712 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5713 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5714 }
5715
5716 QualType Result = TL.getType();
5717 if (getDerived().AlwaysRebuild() ||
5718 ElementType != T->getElementType() ||
5719 (T->getSizeExpr() && NewSize != OldSize)) {
5720 Result = getDerived().RebuildConstantArrayType(ElementType,
5721 T->getSizeModifier(),
5722 T->getSize(), NewSize,
5723 T->getIndexTypeCVRQualifiers(),
5724 TL.getBracketsRange());
5725 if (Result.isNull())
5726 return QualType();
5727 }
5728
5729 // We might have either a ConstantArrayType or a VariableArrayType now:
5730 // a ConstantArrayType is allowed to have an element type which is a
5731 // VariableArrayType if the type is dependent. Fortunately, all array
5732 // types have the same location layout.
5733 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5734 NewTL.setLBracketLoc(TL.getLBracketLoc());
5735 NewTL.setRBracketLoc(TL.getRBracketLoc());
5736 NewTL.setSizeExpr(NewSize);
5737
5738 return Result;
5739}
5740
5741template<typename Derived>
5742QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5743 TypeLocBuilder &TLB,
5744 IncompleteArrayTypeLoc TL) {
5745 const IncompleteArrayType *T = TL.getTypePtr();
5746 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5747 if (ElementType.isNull())
5748 return QualType();
5749
5750 QualType Result = TL.getType();
5751 if (getDerived().AlwaysRebuild() ||
5752 ElementType != T->getElementType()) {
5753 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5754 T->getSizeModifier(),
5755 T->getIndexTypeCVRQualifiers(),
5756 TL.getBracketsRange());
5757 if (Result.isNull())
5758 return QualType();
5759 }
5760
5761 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(T: Result);
5762 NewTL.setLBracketLoc(TL.getLBracketLoc());
5763 NewTL.setRBracketLoc(TL.getRBracketLoc());
5764 NewTL.setSizeExpr(nullptr);
5765
5766 return Result;
5767}
5768
5769template<typename Derived>
5770QualType
5771TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5772 VariableArrayTypeLoc TL) {
5773 const VariableArrayType *T = TL.getTypePtr();
5774 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5775 if (ElementType.isNull())
5776 return QualType();
5777
5778 ExprResult SizeResult;
5779 {
5780 EnterExpressionEvaluationContext Context(
5781 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5782 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5783 }
5784 if (SizeResult.isInvalid())
5785 return QualType();
5786 SizeResult =
5787 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5788 if (SizeResult.isInvalid())
5789 return QualType();
5790
5791 Expr *Size = SizeResult.get();
5792
5793 QualType Result = TL.getType();
5794 if (getDerived().AlwaysRebuild() ||
5795 ElementType != T->getElementType() ||
5796 Size != T->getSizeExpr()) {
5797 Result = getDerived().RebuildVariableArrayType(ElementType,
5798 T->getSizeModifier(),
5799 Size,
5800 T->getIndexTypeCVRQualifiers(),
5801 TL.getBracketsRange());
5802 if (Result.isNull())
5803 return QualType();
5804 }
5805
5806 // We might have constant size array now, but fortunately it has the same
5807 // location layout.
5808 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5809 NewTL.setLBracketLoc(TL.getLBracketLoc());
5810 NewTL.setRBracketLoc(TL.getRBracketLoc());
5811 NewTL.setSizeExpr(Size);
5812
5813 return Result;
5814}
5815
5816template<typename Derived>
5817QualType
5818TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5819 DependentSizedArrayTypeLoc TL) {
5820 const DependentSizedArrayType *T = TL.getTypePtr();
5821 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5822 if (ElementType.isNull())
5823 return QualType();
5824
5825 // Array bounds are constant expressions.
5826 EnterExpressionEvaluationContext Unevaluated(
5827 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5828
5829 // If we have a VLA then it won't be a constant.
5830 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5831
5832 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5833 Expr *origSize = TL.getSizeExpr();
5834 if (!origSize) origSize = T->getSizeExpr();
5835
5836 ExprResult sizeResult
5837 = getDerived().TransformExpr(origSize);
5838 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5839 if (sizeResult.isInvalid())
5840 return QualType();
5841
5842 Expr *size = sizeResult.get();
5843
5844 QualType Result = TL.getType();
5845 if (getDerived().AlwaysRebuild() ||
5846 ElementType != T->getElementType() ||
5847 size != origSize) {
5848 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5849 T->getSizeModifier(),
5850 size,
5851 T->getIndexTypeCVRQualifiers(),
5852 TL.getBracketsRange());
5853 if (Result.isNull())
5854 return QualType();
5855 }
5856
5857 // We might have any sort of array type now, but fortunately they
5858 // all have the same location layout.
5859 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(T: Result);
5860 NewTL.setLBracketLoc(TL.getLBracketLoc());
5861 NewTL.setRBracketLoc(TL.getRBracketLoc());
5862 NewTL.setSizeExpr(size);
5863
5864 return Result;
5865}
5866
5867template <typename Derived>
5868QualType TreeTransform<Derived>::TransformDependentVectorType(
5869 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5870 const DependentVectorType *T = TL.getTypePtr();
5871 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5872 if (ElementType.isNull())
5873 return QualType();
5874
5875 EnterExpressionEvaluationContext Unevaluated(
5876 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5877
5878 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5879 Size = SemaRef.ActOnConstantExpression(Res: Size);
5880 if (Size.isInvalid())
5881 return QualType();
5882
5883 QualType Result = TL.getType();
5884 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5885 Size.get() != T->getSizeExpr()) {
5886 Result = getDerived().RebuildDependentVectorType(
5887 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5888 if (Result.isNull())
5889 return QualType();
5890 }
5891
5892 // Result might be dependent or not.
5893 if (isa<DependentVectorType>(Val: Result)) {
5894 DependentVectorTypeLoc NewTL =
5895 TLB.push<DependentVectorTypeLoc>(T: Result);
5896 NewTL.setNameLoc(TL.getNameLoc());
5897 } else {
5898 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
5899 NewTL.setNameLoc(TL.getNameLoc());
5900 }
5901
5902 return Result;
5903}
5904
5905template<typename Derived>
5906QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5907 TypeLocBuilder &TLB,
5908 DependentSizedExtVectorTypeLoc TL) {
5909 const DependentSizedExtVectorType *T = TL.getTypePtr();
5910
5911 // FIXME: ext vector locs should be nested
5912 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5913 if (ElementType.isNull())
5914 return QualType();
5915
5916 // Vector sizes are constant expressions.
5917 EnterExpressionEvaluationContext Unevaluated(
5918 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5919
5920 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5921 Size = SemaRef.ActOnConstantExpression(Res: Size);
5922 if (Size.isInvalid())
5923 return QualType();
5924
5925 QualType Result = TL.getType();
5926 if (getDerived().AlwaysRebuild() ||
5927 ElementType != T->getElementType() ||
5928 Size.get() != T->getSizeExpr()) {
5929 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5930 Size.get(),
5931 T->getAttributeLoc());
5932 if (Result.isNull())
5933 return QualType();
5934 }
5935
5936 // Result might be dependent or not.
5937 if (isa<DependentSizedExtVectorType>(Val: Result)) {
5938 DependentSizedExtVectorTypeLoc NewTL
5939 = TLB.push<DependentSizedExtVectorTypeLoc>(T: Result);
5940 NewTL.setNameLoc(TL.getNameLoc());
5941 } else {
5942 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
5943 NewTL.setNameLoc(TL.getNameLoc());
5944 }
5945
5946 return Result;
5947}
5948
5949template <typename Derived>
5950QualType
5951TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5952 ConstantMatrixTypeLoc TL) {
5953 const ConstantMatrixType *T = TL.getTypePtr();
5954 QualType ElementType = getDerived().TransformType(T->getElementType());
5955 if (ElementType.isNull())
5956 return QualType();
5957
5958 QualType Result = TL.getType();
5959 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5960 Result = getDerived().RebuildConstantMatrixType(
5961 ElementType, T->getNumRows(), T->getNumColumns());
5962 if (Result.isNull())
5963 return QualType();
5964 }
5965
5966 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(T: Result);
5967 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5968 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5969 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5970 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5971
5972 return Result;
5973}
5974
5975template <typename Derived>
5976QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5977 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5978 const DependentSizedMatrixType *T = TL.getTypePtr();
5979
5980 QualType ElementType = getDerived().TransformType(T->getElementType());
5981 if (ElementType.isNull()) {
5982 return QualType();
5983 }
5984
5985 // Matrix dimensions are constant expressions.
5986 EnterExpressionEvaluationContext Unevaluated(
5987 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5988
5989 Expr *origRows = TL.getAttrRowOperand();
5990 if (!origRows)
5991 origRows = T->getRowExpr();
5992 Expr *origColumns = TL.getAttrColumnOperand();
5993 if (!origColumns)
5994 origColumns = T->getColumnExpr();
5995
5996 ExprResult rowResult = getDerived().TransformExpr(origRows);
5997 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5998 if (rowResult.isInvalid())
5999 return QualType();
6000
6001 ExprResult columnResult = getDerived().TransformExpr(origColumns);
6002 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
6003 if (columnResult.isInvalid())
6004 return QualType();
6005
6006 Expr *rows = rowResult.get();
6007 Expr *columns = columnResult.get();
6008
6009 QualType Result = TL.getType();
6010 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6011 rows != origRows || columns != origColumns) {
6012 Result = getDerived().RebuildDependentSizedMatrixType(
6013 ElementType, rows, columns, T->getAttributeLoc());
6014
6015 if (Result.isNull())
6016 return QualType();
6017 }
6018
6019 // We might have any sort of matrix type now, but fortunately they
6020 // all have the same location layout.
6021 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(T: Result);
6022 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6023 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6024 NewTL.setAttrRowOperand(rows);
6025 NewTL.setAttrColumnOperand(columns);
6026 return Result;
6027}
6028
6029template <typename Derived>
6030QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6031 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6032 const DependentAddressSpaceType *T = TL.getTypePtr();
6033
6034 QualType pointeeType =
6035 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6036
6037 if (pointeeType.isNull())
6038 return QualType();
6039
6040 // Address spaces are constant expressions.
6041 EnterExpressionEvaluationContext Unevaluated(
6042 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6043
6044 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6045 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6046 if (AddrSpace.isInvalid())
6047 return QualType();
6048
6049 QualType Result = TL.getType();
6050 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6051 AddrSpace.get() != T->getAddrSpaceExpr()) {
6052 Result = getDerived().RebuildDependentAddressSpaceType(
6053 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6054 if (Result.isNull())
6055 return QualType();
6056 }
6057
6058 // Result might be dependent or not.
6059 if (isa<DependentAddressSpaceType>(Val: Result)) {
6060 DependentAddressSpaceTypeLoc NewTL =
6061 TLB.push<DependentAddressSpaceTypeLoc>(T: Result);
6062
6063 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6064 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6065 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6066
6067 } else {
6068 TLB.TypeWasModifiedSafely(T: Result);
6069 }
6070
6071 return Result;
6072}
6073
6074template <typename Derived>
6075QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6076 VectorTypeLoc TL) {
6077 const VectorType *T = TL.getTypePtr();
6078 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6079 if (ElementType.isNull())
6080 return QualType();
6081
6082 QualType Result = TL.getType();
6083 if (getDerived().AlwaysRebuild() ||
6084 ElementType != T->getElementType()) {
6085 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6086 T->getVectorKind());
6087 if (Result.isNull())
6088 return QualType();
6089 }
6090
6091 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(T: Result);
6092 NewTL.setNameLoc(TL.getNameLoc());
6093
6094 return Result;
6095}
6096
6097template<typename Derived>
6098QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6099 ExtVectorTypeLoc TL) {
6100 const VectorType *T = TL.getTypePtr();
6101 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6102 if (ElementType.isNull())
6103 return QualType();
6104
6105 QualType Result = TL.getType();
6106 if (getDerived().AlwaysRebuild() ||
6107 ElementType != T->getElementType()) {
6108 Result = getDerived().RebuildExtVectorType(ElementType,
6109 T->getNumElements(),
6110 /*FIXME*/ SourceLocation());
6111 if (Result.isNull())
6112 return QualType();
6113 }
6114
6115 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(T: Result);
6116 NewTL.setNameLoc(TL.getNameLoc());
6117
6118 return Result;
6119}
6120
6121template <typename Derived>
6122ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6123 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6124 bool ExpectParameterPack) {
6125 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6126 TypeSourceInfo *NewDI = nullptr;
6127
6128 if (NumExpansions && isa<PackExpansionType>(Val: OldDI->getType())) {
6129 // If we're substituting into a pack expansion type and we know the
6130 // length we want to expand to, just substitute for the pattern.
6131 TypeLoc OldTL = OldDI->getTypeLoc();
6132 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6133
6134 TypeLocBuilder TLB;
6135 TypeLoc NewTL = OldDI->getTypeLoc();
6136 TLB.reserve(Requested: NewTL.getFullDataSize());
6137
6138 QualType Result = getDerived().TransformType(TLB,
6139 OldExpansionTL.getPatternLoc());
6140 if (Result.isNull())
6141 return nullptr;
6142
6143 Result = RebuildPackExpansionType(Pattern: Result,
6144 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6145 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6146 NumExpansions);
6147 if (Result.isNull())
6148 return nullptr;
6149
6150 PackExpansionTypeLoc NewExpansionTL
6151 = TLB.push<PackExpansionTypeLoc>(T: Result);
6152 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6153 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6154 } else
6155 NewDI = getDerived().TransformType(OldDI);
6156 if (!NewDI)
6157 return nullptr;
6158
6159 if (NewDI == OldDI && indexAdjustment == 0)
6160 return OldParm;
6161
6162 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
6163 DC: OldParm->getDeclContext(),
6164 StartLoc: OldParm->getInnerLocStart(),
6165 IdLoc: OldParm->getLocation(),
6166 Id: OldParm->getIdentifier(),
6167 T: NewDI->getType(),
6168 TInfo: NewDI,
6169 S: OldParm->getStorageClass(),
6170 /* DefArg */ DefArg: nullptr);
6171 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6172 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6173 transformedLocalDecl(Old: OldParm, New: {newParm});
6174 return newParm;
6175}
6176
6177template <typename Derived>
6178bool TreeTransform<Derived>::TransformFunctionTypeParams(
6179 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6180 const QualType *ParamTypes,
6181 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6182 SmallVectorImpl<QualType> &OutParamTypes,
6183 SmallVectorImpl<ParmVarDecl *> *PVars,
6184 Sema::ExtParameterInfoBuilder &PInfos,
6185 unsigned *LastParamTransformed) {
6186 int indexAdjustment = 0;
6187
6188 unsigned NumParams = Params.size();
6189 for (unsigned i = 0; i != NumParams; ++i) {
6190 if (LastParamTransformed)
6191 *LastParamTransformed = i;
6192 if (ParmVarDecl *OldParm = Params[i]) {
6193 assert(OldParm->getFunctionScopeIndex() == i);
6194
6195 UnsignedOrNone NumExpansions = std::nullopt;
6196 ParmVarDecl *NewParm = nullptr;
6197 if (OldParm->isParameterPack()) {
6198 // We have a function parameter pack that may need to be expanded.
6199 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6200
6201 // Find the parameter packs that could be expanded.
6202 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6203 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6204 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6205 SemaRef.collectUnexpandedParameterPacks(TL: Pattern, Unexpanded);
6206
6207 // Determine whether we should expand the parameter packs.
6208 bool ShouldExpand = false;
6209 bool RetainExpansion = false;
6210 UnsignedOrNone OrigNumExpansions = std::nullopt;
6211 if (Unexpanded.size() > 0) {
6212 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6213 NumExpansions = OrigNumExpansions;
6214 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6215 Pattern.getSourceRange(),
6216 Unexpanded,
6217 ShouldExpand,
6218 RetainExpansion,
6219 NumExpansions)) {
6220 return true;
6221 }
6222 } else {
6223#ifndef NDEBUG
6224 const AutoType *AT =
6225 Pattern.getType().getTypePtr()->getContainedAutoType();
6226 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6227 "Could not find parameter packs or undeduced auto type!");
6228#endif
6229 }
6230
6231 if (ShouldExpand) {
6232 // Expand the function parameter pack into multiple, separate
6233 // parameters.
6234 getDerived().ExpandingFunctionParameterPack(OldParm);
6235 for (unsigned I = 0; I != *NumExpansions; ++I) {
6236 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6237 ParmVarDecl *NewParm
6238 = getDerived().TransformFunctionTypeParam(OldParm,
6239 indexAdjustment++,
6240 OrigNumExpansions,
6241 /*ExpectParameterPack=*/false);
6242 if (!NewParm)
6243 return true;
6244
6245 if (ParamInfos)
6246 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6247 OutParamTypes.push_back(Elt: NewParm->getType());
6248 if (PVars)
6249 PVars->push_back(Elt: NewParm);
6250 }
6251
6252 // If we're supposed to retain a pack expansion, do so by temporarily
6253 // forgetting the partially-substituted parameter pack.
6254 if (RetainExpansion) {
6255 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6256 ParmVarDecl *NewParm
6257 = getDerived().TransformFunctionTypeParam(OldParm,
6258 indexAdjustment++,
6259 OrigNumExpansions,
6260 /*ExpectParameterPack=*/false);
6261 if (!NewParm)
6262 return true;
6263
6264 if (ParamInfos)
6265 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6266 OutParamTypes.push_back(Elt: NewParm->getType());
6267 if (PVars)
6268 PVars->push_back(Elt: NewParm);
6269 }
6270
6271 // The next parameter should have the same adjustment as the
6272 // last thing we pushed, but we post-incremented indexAdjustment
6273 // on every push. Also, if we push nothing, the adjustment should
6274 // go down by one.
6275 indexAdjustment--;
6276
6277 // We're done with the pack expansion.
6278 continue;
6279 }
6280
6281 // We'll substitute the parameter now without expanding the pack
6282 // expansion.
6283 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6284 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6285 indexAdjustment,
6286 NumExpansions,
6287 /*ExpectParameterPack=*/true);
6288 assert(NewParm->isParameterPack() &&
6289 "Parameter pack no longer a parameter pack after "
6290 "transformation.");
6291 } else {
6292 NewParm = getDerived().TransformFunctionTypeParam(
6293 OldParm, indexAdjustment, std::nullopt,
6294 /*ExpectParameterPack=*/false);
6295 }
6296
6297 if (!NewParm)
6298 return true;
6299
6300 if (ParamInfos)
6301 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6302 OutParamTypes.push_back(Elt: NewParm->getType());
6303 if (PVars)
6304 PVars->push_back(Elt: NewParm);
6305 continue;
6306 }
6307
6308 // Deal with the possibility that we don't have a parameter
6309 // declaration for this parameter.
6310 assert(ParamTypes);
6311 QualType OldType = ParamTypes[i];
6312 bool IsPackExpansion = false;
6313 UnsignedOrNone NumExpansions = std::nullopt;
6314 QualType NewType;
6315 if (const PackExpansionType *Expansion
6316 = dyn_cast<PackExpansionType>(Val&: OldType)) {
6317 // We have a function parameter pack that may need to be expanded.
6318 QualType Pattern = Expansion->getPattern();
6319 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6320 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6321
6322 // Determine whether we should expand the parameter packs.
6323 bool ShouldExpand = false;
6324 bool RetainExpansion = false;
6325 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6326 Unexpanded,
6327 ShouldExpand,
6328 RetainExpansion,
6329 NumExpansions)) {
6330 return true;
6331 }
6332
6333 if (ShouldExpand) {
6334 // Expand the function parameter pack into multiple, separate
6335 // parameters.
6336 for (unsigned I = 0; I != *NumExpansions; ++I) {
6337 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6338 QualType NewType = getDerived().TransformType(Pattern);
6339 if (NewType.isNull())
6340 return true;
6341
6342 if (NewType->containsUnexpandedParameterPack()) {
6343 NewType = getSema().getASTContext().getPackExpansionType(
6344 NewType, std::nullopt);
6345
6346 if (NewType.isNull())
6347 return true;
6348 }
6349
6350 if (ParamInfos)
6351 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6352 OutParamTypes.push_back(Elt: NewType);
6353 if (PVars)
6354 PVars->push_back(Elt: nullptr);
6355 }
6356
6357 // We're done with the pack expansion.
6358 continue;
6359 }
6360
6361 // If we're supposed to retain a pack expansion, do so by temporarily
6362 // forgetting the partially-substituted parameter pack.
6363 if (RetainExpansion) {
6364 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6365 QualType NewType = getDerived().TransformType(Pattern);
6366 if (NewType.isNull())
6367 return true;
6368
6369 if (ParamInfos)
6370 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6371 OutParamTypes.push_back(Elt: NewType);
6372 if (PVars)
6373 PVars->push_back(Elt: nullptr);
6374 }
6375
6376 // We'll substitute the parameter now without expanding the pack
6377 // expansion.
6378 OldType = Expansion->getPattern();
6379 IsPackExpansion = true;
6380 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6381 NewType = getDerived().TransformType(OldType);
6382 } else {
6383 NewType = getDerived().TransformType(OldType);
6384 }
6385
6386 if (NewType.isNull())
6387 return true;
6388
6389 if (IsPackExpansion)
6390 NewType = getSema().Context.getPackExpansionType(NewType,
6391 NumExpansions);
6392
6393 if (ParamInfos)
6394 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6395 OutParamTypes.push_back(Elt: NewType);
6396 if (PVars)
6397 PVars->push_back(Elt: nullptr);
6398 }
6399
6400#ifndef NDEBUG
6401 if (PVars) {
6402 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6403 if (ParmVarDecl *parm = (*PVars)[i])
6404 assert(parm->getFunctionScopeIndex() == i);
6405 }
6406#endif
6407
6408 return false;
6409}
6410
6411template<typename Derived>
6412QualType
6413TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6414 FunctionProtoTypeLoc TL) {
6415 SmallVector<QualType, 4> ExceptionStorage;
6416 return getDerived().TransformFunctionProtoType(
6417 TLB, TL, nullptr, Qualifiers(),
6418 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6419 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6420 ExceptionStorage, Changed);
6421 });
6422}
6423
6424template<typename Derived> template<typename Fn>
6425QualType TreeTransform<Derived>::TransformFunctionProtoType(
6426 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6427 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6428
6429 // Transform the parameters and return type.
6430 //
6431 // We are required to instantiate the params and return type in source order.
6432 // When the function has a trailing return type, we instantiate the
6433 // parameters before the return type, since the return type can then refer
6434 // to the parameters themselves (via decltype, sizeof, etc.).
6435 //
6436 SmallVector<QualType, 4> ParamTypes;
6437 SmallVector<ParmVarDecl*, 4> ParamDecls;
6438 Sema::ExtParameterInfoBuilder ExtParamInfos;
6439 const FunctionProtoType *T = TL.getTypePtr();
6440
6441 QualType ResultType;
6442
6443 if (T->hasTrailingReturn()) {
6444 if (getDerived().TransformFunctionTypeParams(
6445 TL.getBeginLoc(), TL.getParams(),
6446 TL.getTypePtr()->param_type_begin(),
6447 T->getExtParameterInfosOrNull(),
6448 ParamTypes, &ParamDecls, ExtParamInfos))
6449 return QualType();
6450
6451 {
6452 // C++11 [expr.prim.general]p3:
6453 // If a declaration declares a member function or member function
6454 // template of a class X, the expression this is a prvalue of type
6455 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6456 // and the end of the function-definition, member-declarator, or
6457 // declarator.
6458 auto *RD = dyn_cast<CXXRecordDecl>(Val: SemaRef.getCurLexicalContext());
6459 Sema::CXXThisScopeRAII ThisScope(
6460 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6461
6462 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6463 if (ResultType.isNull())
6464 return QualType();
6465 }
6466 }
6467 else {
6468 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6469 if (ResultType.isNull())
6470 return QualType();
6471
6472 if (getDerived().TransformFunctionTypeParams(
6473 TL.getBeginLoc(), TL.getParams(),
6474 TL.getTypePtr()->param_type_begin(),
6475 T->getExtParameterInfosOrNull(),
6476 ParamTypes, &ParamDecls, ExtParamInfos))
6477 return QualType();
6478 }
6479
6480 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6481
6482 bool EPIChanged = false;
6483 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6484 return QualType();
6485
6486 // Handle extended parameter information.
6487 if (auto NewExtParamInfos =
6488 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6489 if (!EPI.ExtParameterInfos ||
6490 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6491 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6492 EPIChanged = true;
6493 }
6494 EPI.ExtParameterInfos = NewExtParamInfos;
6495 } else if (EPI.ExtParameterInfos) {
6496 EPIChanged = true;
6497 EPI.ExtParameterInfos = nullptr;
6498 }
6499
6500 // Transform any function effects with unevaluated conditions.
6501 // Hold this set in a local for the rest of this function, since EPI
6502 // may need to hold a FunctionEffectsRef pointing into it.
6503 std::optional<FunctionEffectSet> NewFX;
6504 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6505 NewFX.emplace();
6506 EnterExpressionEvaluationContext Unevaluated(
6507 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6508
6509 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6510 FunctionEffectWithCondition NewEC = PrevEC;
6511 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6512 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6513 if (NewExpr.isInvalid())
6514 return QualType();
6515 std::optional<FunctionEffectMode> Mode =
6516 SemaRef.ActOnEffectExpression(CondExpr: NewExpr.get(), AttributeName: PrevEC.Effect.name());
6517 if (!Mode)
6518 return QualType();
6519
6520 // The condition expression has been transformed, and re-evaluated.
6521 // It may or may not have become constant.
6522 switch (*Mode) {
6523 case FunctionEffectMode::True:
6524 NewEC.Cond = {};
6525 break;
6526 case FunctionEffectMode::False:
6527 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6528 NewEC.Cond = {};
6529 break;
6530 case FunctionEffectMode::Dependent:
6531 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6532 break;
6533 case FunctionEffectMode::None:
6534 llvm_unreachable(
6535 "FunctionEffectMode::None shouldn't be possible here");
6536 }
6537 }
6538 if (!SemaRef.diagnoseConflictingFunctionEffect(FX: *NewFX, EC: NewEC,
6539 NewAttrLoc: TL.getBeginLoc())) {
6540 FunctionEffectSet::Conflicts Errs;
6541 NewFX->insert(NewEC, Errs);
6542 assert(Errs.empty());
6543 }
6544 }
6545 EPI.FunctionEffects = *NewFX;
6546 EPIChanged = true;
6547 }
6548
6549 QualType Result = TL.getType();
6550 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6551 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6552 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6553 if (Result.isNull())
6554 return QualType();
6555 }
6556
6557 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(T: Result);
6558 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6559 NewTL.setLParenLoc(TL.getLParenLoc());
6560 NewTL.setRParenLoc(TL.getRParenLoc());
6561 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6562 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6563 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6564 NewTL.setParam(i, VD: ParamDecls[i]);
6565
6566 return Result;
6567}
6568
6569template<typename Derived>
6570bool TreeTransform<Derived>::TransformExceptionSpec(
6571 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6572 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6573 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6574
6575 // Instantiate a dynamic noexcept expression, if any.
6576 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6577 // Update this scrope because ContextDecl in Sema will be used in
6578 // TransformExpr.
6579 auto *Method = dyn_cast_if_present<CXXMethodDecl>(Val: ESI.SourceTemplate);
6580 Sema::CXXThisScopeRAII ThisScope(
6581 SemaRef, Method ? Method->getParent() : nullptr,
6582 Method ? Method->getMethodQualifiers() : Qualifiers{},
6583 Method != nullptr);
6584 EnterExpressionEvaluationContext Unevaluated(
6585 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6586 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6587 if (NoexceptExpr.isInvalid())
6588 return true;
6589
6590 ExceptionSpecificationType EST = ESI.Type;
6591 NoexceptExpr =
6592 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6593 if (NoexceptExpr.isInvalid())
6594 return true;
6595
6596 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6597 Changed = true;
6598 ESI.NoexceptExpr = NoexceptExpr.get();
6599 ESI.Type = EST;
6600 }
6601
6602 if (ESI.Type != EST_Dynamic)
6603 return false;
6604
6605 // Instantiate a dynamic exception specification's type.
6606 for (QualType T : ESI.Exceptions) {
6607 if (const PackExpansionType *PackExpansion =
6608 T->getAs<PackExpansionType>()) {
6609 Changed = true;
6610
6611 // We have a pack expansion. Instantiate it.
6612 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6613 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
6614 Unexpanded);
6615 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6616
6617 // Determine whether the set of unexpanded parameter packs can and
6618 // should
6619 // be expanded.
6620 bool Expand = false;
6621 bool RetainExpansion = false;
6622 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6623 // FIXME: Track the location of the ellipsis (and track source location
6624 // information for the types in the exception specification in general).
6625 if (getDerived().TryExpandParameterPacks(
6626 Loc, SourceRange(), Unexpanded, Expand,
6627 RetainExpansion, NumExpansions))
6628 return true;
6629
6630 if (!Expand) {
6631 // We can't expand this pack expansion into separate arguments yet;
6632 // just substitute into the pattern and create a new pack expansion
6633 // type.
6634 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6635 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6636 if (U.isNull())
6637 return true;
6638
6639 U = SemaRef.Context.getPackExpansionType(Pattern: U, NumExpansions);
6640 Exceptions.push_back(Elt: U);
6641 continue;
6642 }
6643
6644 // Substitute into the pack expansion pattern for each slice of the
6645 // pack.
6646 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6647 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6648
6649 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6650 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6651 return true;
6652
6653 Exceptions.push_back(Elt: U);
6654 }
6655 } else {
6656 QualType U = getDerived().TransformType(T);
6657 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(T&: U, Range: Loc))
6658 return true;
6659 if (T != U)
6660 Changed = true;
6661
6662 Exceptions.push_back(Elt: U);
6663 }
6664 }
6665
6666 ESI.Exceptions = Exceptions;
6667 if (ESI.Exceptions.empty())
6668 ESI.Type = EST_DynamicNone;
6669 return false;
6670}
6671
6672template<typename Derived>
6673QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6674 TypeLocBuilder &TLB,
6675 FunctionNoProtoTypeLoc TL) {
6676 const FunctionNoProtoType *T = TL.getTypePtr();
6677 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6678 if (ResultType.isNull())
6679 return QualType();
6680
6681 QualType Result = TL.getType();
6682 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6683 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6684
6685 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(T: Result);
6686 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6687 NewTL.setLParenLoc(TL.getLParenLoc());
6688 NewTL.setRParenLoc(TL.getRParenLoc());
6689 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6690
6691 return Result;
6692}
6693
6694template <typename Derived>
6695QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6696 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6697 const UnresolvedUsingType *T = TL.getTypePtr();
6698 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6699 if (!D)
6700 return QualType();
6701
6702 QualType Result = TL.getType();
6703 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6704 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6705 if (Result.isNull())
6706 return QualType();
6707 }
6708
6709 // We might get an arbitrary type spec type back. We should at
6710 // least always get a type spec type, though.
6711 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6712 NewTL.setNameLoc(TL.getNameLoc());
6713
6714 return Result;
6715}
6716
6717template <typename Derived>
6718QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6719 UsingTypeLoc TL) {
6720 const UsingType *T = TL.getTypePtr();
6721
6722 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6723 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6724 if (!Found)
6725 return QualType();
6726
6727 QualType Underlying = getDerived().TransformType(T->desugar());
6728 if (Underlying.isNull())
6729 return QualType();
6730
6731 QualType Result = TL.getType();
6732 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6733 Underlying != T->getUnderlyingType()) {
6734 Result = getDerived().RebuildUsingType(Found, Underlying);
6735 if (Result.isNull())
6736 return QualType();
6737 }
6738
6739 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6740 return Result;
6741}
6742
6743template<typename Derived>
6744QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6745 TypedefTypeLoc TL) {
6746 const TypedefType *T = TL.getTypePtr();
6747 TypedefNameDecl *Typedef
6748 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6749 T->getDecl()));
6750 if (!Typedef)
6751 return QualType();
6752
6753 QualType Result = TL.getType();
6754 if (getDerived().AlwaysRebuild() ||
6755 Typedef != T->getDecl()) {
6756 Result = getDerived().RebuildTypedefType(Typedef);
6757 if (Result.isNull())
6758 return QualType();
6759 }
6760
6761 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(T: Result);
6762 NewTL.setNameLoc(TL.getNameLoc());
6763
6764 return Result;
6765}
6766
6767template<typename Derived>
6768QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6769 TypeOfExprTypeLoc TL) {
6770 // typeof expressions are not potentially evaluated contexts
6771 EnterExpressionEvaluationContext Unevaluated(
6772 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6773 Sema::ReuseLambdaContextDecl);
6774
6775 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6776 if (E.isInvalid())
6777 return QualType();
6778
6779 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6780 if (E.isInvalid())
6781 return QualType();
6782
6783 QualType Result = TL.getType();
6784 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6785 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6786 Result =
6787 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6788 if (Result.isNull())
6789 return QualType();
6790 }
6791
6792 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(T: Result);
6793 NewTL.setTypeofLoc(TL.getTypeofLoc());
6794 NewTL.setLParenLoc(TL.getLParenLoc());
6795 NewTL.setRParenLoc(TL.getRParenLoc());
6796
6797 return Result;
6798}
6799
6800template<typename Derived>
6801QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6802 TypeOfTypeLoc TL) {
6803 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6804 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6805 if (!New_Under_TI)
6806 return QualType();
6807
6808 QualType Result = TL.getType();
6809 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6810 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6811 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6812 if (Result.isNull())
6813 return QualType();
6814 }
6815
6816 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(T: Result);
6817 NewTL.setTypeofLoc(TL.getTypeofLoc());
6818 NewTL.setLParenLoc(TL.getLParenLoc());
6819 NewTL.setRParenLoc(TL.getRParenLoc());
6820 NewTL.setUnmodifiedTInfo(New_Under_TI);
6821
6822 return Result;
6823}
6824
6825template<typename Derived>
6826QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6827 DecltypeTypeLoc TL) {
6828 const DecltypeType *T = TL.getTypePtr();
6829
6830 // decltype expressions are not potentially evaluated contexts
6831 EnterExpressionEvaluationContext Unevaluated(
6832 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6833 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6834
6835 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6836 if (E.isInvalid())
6837 return QualType();
6838
6839 E = getSema().ActOnDecltypeExpression(E.get());
6840 if (E.isInvalid())
6841 return QualType();
6842
6843 QualType Result = TL.getType();
6844 if (getDerived().AlwaysRebuild() ||
6845 E.get() != T->getUnderlyingExpr()) {
6846 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6847 if (Result.isNull())
6848 return QualType();
6849 }
6850 else E.get();
6851
6852 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(T: Result);
6853 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6854 NewTL.setRParenLoc(TL.getRParenLoc());
6855 return Result;
6856}
6857
6858template <typename Derived>
6859QualType
6860TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6861 PackIndexingTypeLoc TL) {
6862 // Transform the index
6863 ExprResult IndexExpr;
6864 {
6865 EnterExpressionEvaluationContext ConstantContext(
6866 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6867
6868 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6869 if (IndexExpr.isInvalid())
6870 return QualType();
6871 }
6872 QualType Pattern = TL.getPattern();
6873
6874 const PackIndexingType *PIT = TL.getTypePtr();
6875 SmallVector<QualType, 5> SubtitutedTypes;
6876 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6877
6878 bool NotYetExpanded = Types.empty();
6879 bool FullySubstituted = true;
6880
6881 if (Types.empty() && !PIT->expandsToEmptyPack())
6882 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6883
6884 for (QualType T : Types) {
6885 if (!T->containsUnexpandedParameterPack()) {
6886 QualType Transformed = getDerived().TransformType(T);
6887 if (Transformed.isNull())
6888 return QualType();
6889 SubtitutedTypes.push_back(Elt: Transformed);
6890 continue;
6891 }
6892
6893 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6894 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6895 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6896 // Determine whether the set of unexpanded parameter packs can and should
6897 // be expanded.
6898 bool ShouldExpand = true;
6899 bool RetainExpansion = false;
6900 UnsignedOrNone NumExpansions = std::nullopt;
6901 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6902 Unexpanded, ShouldExpand,
6903 RetainExpansion, NumExpansions))
6904 return QualType();
6905 if (!ShouldExpand) {
6906 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6907 // FIXME: should we keep TypeLoc for individual expansions in
6908 // PackIndexingTypeLoc?
6909 TypeSourceInfo *TI =
6910 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, Loc: TL.getBeginLoc());
6911 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6912 if (Pack.isNull())
6913 return QualType();
6914 if (NotYetExpanded) {
6915 FullySubstituted = false;
6916 QualType Out = getDerived().RebuildPackIndexingType(
6917 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6918 FullySubstituted);
6919 if (Out.isNull())
6920 return QualType();
6921
6922 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6923 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6924 return Out;
6925 }
6926 SubtitutedTypes.push_back(Elt: Pack);
6927 continue;
6928 }
6929 for (unsigned I = 0; I != *NumExpansions; ++I) {
6930 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6931 QualType Out = getDerived().TransformType(T);
6932 if (Out.isNull())
6933 return QualType();
6934 SubtitutedTypes.push_back(Elt: Out);
6935 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6936 }
6937 // If we're supposed to retain a pack expansion, do so by temporarily
6938 // forgetting the partially-substituted parameter pack.
6939 if (RetainExpansion) {
6940 FullySubstituted = false;
6941 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6942 QualType Out = getDerived().TransformType(T);
6943 if (Out.isNull())
6944 return QualType();
6945 SubtitutedTypes.push_back(Elt: Out);
6946 }
6947 }
6948
6949 // A pack indexing type can appear in a larger pack expansion,
6950 // e.g. `Pack...[pack_of_indexes]...`
6951 // so we need to temporarily disable substitution of pack elements
6952 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6953 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6954
6955 QualType Out = getDerived().RebuildPackIndexingType(
6956 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6957 FullySubstituted, SubtitutedTypes);
6958 if (Out.isNull())
6959 return Out;
6960
6961 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(T: Out);
6962 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6963 return Out;
6964}
6965
6966template<typename Derived>
6967QualType TreeTransform<Derived>::TransformUnaryTransformType(
6968 TypeLocBuilder &TLB,
6969 UnaryTransformTypeLoc TL) {
6970 QualType Result = TL.getType();
6971 if (Result->isDependentType()) {
6972 const UnaryTransformType *T = TL.getTypePtr();
6973
6974 TypeSourceInfo *NewBaseTSI =
6975 getDerived().TransformType(TL.getUnderlyingTInfo());
6976 if (!NewBaseTSI)
6977 return QualType();
6978 QualType NewBase = NewBaseTSI->getType();
6979
6980 Result = getDerived().RebuildUnaryTransformType(NewBase,
6981 T->getUTTKind(),
6982 TL.getKWLoc());
6983 if (Result.isNull())
6984 return QualType();
6985 }
6986
6987 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(T: Result);
6988 NewTL.setKWLoc(TL.getKWLoc());
6989 NewTL.setParensRange(TL.getParensRange());
6990 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6991 return Result;
6992}
6993
6994template<typename Derived>
6995QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6996 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6997 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6998
6999 CXXScopeSpec SS;
7000 TemplateName TemplateName = getDerived().TransformTemplateName(
7001 SS, T->getTemplateName(), TL.getTemplateNameLoc());
7002 if (TemplateName.isNull())
7003 return QualType();
7004
7005 QualType OldDeduced = T->getDeducedType();
7006 QualType NewDeduced;
7007 if (!OldDeduced.isNull()) {
7008 NewDeduced = getDerived().TransformType(OldDeduced);
7009 if (NewDeduced.isNull())
7010 return QualType();
7011 }
7012
7013 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7014 TemplateName, NewDeduced);
7015 if (Result.isNull())
7016 return QualType();
7017
7018 DeducedTemplateSpecializationTypeLoc NewTL =
7019 TLB.push<DeducedTemplateSpecializationTypeLoc>(T: Result);
7020 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7021
7022 return Result;
7023}
7024
7025template<typename Derived>
7026QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7027 RecordTypeLoc TL) {
7028 const RecordType *T = TL.getTypePtr();
7029 RecordDecl *Record
7030 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7031 T->getDecl()));
7032 if (!Record)
7033 return QualType();
7034
7035 QualType Result = TL.getType();
7036 if (getDerived().AlwaysRebuild() ||
7037 Record != T->getDecl()) {
7038 Result = getDerived().RebuildRecordType(Record);
7039 if (Result.isNull())
7040 return QualType();
7041 }
7042
7043 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(T: Result);
7044 NewTL.setNameLoc(TL.getNameLoc());
7045
7046 return Result;
7047}
7048
7049template<typename Derived>
7050QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7051 EnumTypeLoc TL) {
7052 const EnumType *T = TL.getTypePtr();
7053 EnumDecl *Enum
7054 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7055 T->getDecl()));
7056 if (!Enum)
7057 return QualType();
7058
7059 QualType Result = TL.getType();
7060 if (getDerived().AlwaysRebuild() ||
7061 Enum != T->getDecl()) {
7062 Result = getDerived().RebuildEnumType(Enum);
7063 if (Result.isNull())
7064 return QualType();
7065 }
7066
7067 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(T: Result);
7068 NewTL.setNameLoc(TL.getNameLoc());
7069
7070 return Result;
7071}
7072
7073template<typename Derived>
7074QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7075 TypeLocBuilder &TLB,
7076 InjectedClassNameTypeLoc TL) {
7077 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7078 TL.getTypePtr()->getDecl());
7079 if (!D) return QualType();
7080
7081 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(Val: D));
7082 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7083 return T;
7084}
7085
7086template<typename Derived>
7087QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7088 TypeLocBuilder &TLB,
7089 TemplateTypeParmTypeLoc TL) {
7090 return getDerived().TransformTemplateTypeParmType(
7091 TLB, TL,
7092 /*SuppressObjCLifetime=*/false);
7093}
7094
7095template <typename Derived>
7096QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7097 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7098 return TransformTypeSpecType(TLB, T: TL);
7099}
7100
7101template<typename Derived>
7102QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7103 TypeLocBuilder &TLB,
7104 SubstTemplateTypeParmTypeLoc TL) {
7105 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7106
7107 Decl *NewReplaced =
7108 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7109
7110 // Substitute into the replacement type, which itself might involve something
7111 // that needs to be transformed. This only tends to occur with default
7112 // template arguments of template template parameters.
7113 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7114 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7115 if (Replacement.isNull())
7116 return QualType();
7117
7118 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7119 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7120 Final: T->getFinal());
7121
7122 // Propagate type-source information.
7123 SubstTemplateTypeParmTypeLoc NewTL
7124 = TLB.push<SubstTemplateTypeParmTypeLoc>(T: Result);
7125 NewTL.setNameLoc(TL.getNameLoc());
7126 return Result;
7127
7128}
7129
7130template<typename Derived>
7131QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7132 TypeLocBuilder &TLB,
7133 SubstTemplateTypeParmPackTypeLoc TL) {
7134 return getDerived().TransformSubstTemplateTypeParmPackType(
7135 TLB, TL, /*SuppressObjCLifetime=*/false);
7136}
7137
7138template <typename Derived>
7139QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7140 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7141 return TransformTypeSpecType(TLB, T: TL);
7142}
7143
7144template<typename Derived>
7145QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7146 TypeLocBuilder &TLB,
7147 TemplateSpecializationTypeLoc TL) {
7148 const TemplateSpecializationType *T = TL.getTypePtr();
7149
7150 // The nested-name-specifier never matters in a TemplateSpecializationType,
7151 // because we can't have a dependent nested-name-specifier anyway.
7152 CXXScopeSpec SS;
7153 TemplateName Template
7154 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7155 TL.getTemplateNameLoc());
7156 if (Template.isNull())
7157 return QualType();
7158
7159 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7160}
7161
7162template<typename Derived>
7163QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7164 AtomicTypeLoc TL) {
7165 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7166 if (ValueType.isNull())
7167 return QualType();
7168
7169 QualType Result = TL.getType();
7170 if (getDerived().AlwaysRebuild() ||
7171 ValueType != TL.getValueLoc().getType()) {
7172 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7173 if (Result.isNull())
7174 return QualType();
7175 }
7176
7177 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(T: Result);
7178 NewTL.setKWLoc(TL.getKWLoc());
7179 NewTL.setLParenLoc(TL.getLParenLoc());
7180 NewTL.setRParenLoc(TL.getRParenLoc());
7181
7182 return Result;
7183}
7184
7185template <typename Derived>
7186QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7187 PipeTypeLoc TL) {
7188 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7189 if (ValueType.isNull())
7190 return QualType();
7191
7192 QualType Result = TL.getType();
7193 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7194 const PipeType *PT = Result->castAs<PipeType>();
7195 bool isReadPipe = PT->isReadOnly();
7196 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7197 if (Result.isNull())
7198 return QualType();
7199 }
7200
7201 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(T: Result);
7202 NewTL.setKWLoc(TL.getKWLoc());
7203
7204 return Result;
7205}
7206
7207template <typename Derived>
7208QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7209 BitIntTypeLoc TL) {
7210 const BitIntType *EIT = TL.getTypePtr();
7211 QualType Result = TL.getType();
7212
7213 if (getDerived().AlwaysRebuild()) {
7214 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7215 EIT->getNumBits(), TL.getNameLoc());
7216 if (Result.isNull())
7217 return QualType();
7218 }
7219
7220 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7221 NewTL.setNameLoc(TL.getNameLoc());
7222 return Result;
7223}
7224
7225template <typename Derived>
7226QualType TreeTransform<Derived>::TransformDependentBitIntType(
7227 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7228 const DependentBitIntType *EIT = TL.getTypePtr();
7229
7230 EnterExpressionEvaluationContext Unevaluated(
7231 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7232 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7233 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7234
7235 if (BitsExpr.isInvalid())
7236 return QualType();
7237
7238 QualType Result = TL.getType();
7239
7240 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7241 Result = getDerived().RebuildDependentBitIntType(
7242 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7243
7244 if (Result.isNull())
7245 return QualType();
7246 }
7247
7248 if (isa<DependentBitIntType>(Val: Result)) {
7249 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(T: Result);
7250 NewTL.setNameLoc(TL.getNameLoc());
7251 } else {
7252 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(T: Result);
7253 NewTL.setNameLoc(TL.getNameLoc());
7254 }
7255 return Result;
7256}
7257
7258 /// Simple iterator that traverses the template arguments in a
7259 /// container that provides a \c getArgLoc() member function.
7260 ///
7261 /// This iterator is intended to be used with the iterator form of
7262 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7263 template<typename ArgLocContainer>
7264 class TemplateArgumentLocContainerIterator {
7265 ArgLocContainer *Container;
7266 unsigned Index;
7267
7268 public:
7269 typedef TemplateArgumentLoc value_type;
7270 typedef TemplateArgumentLoc reference;
7271 typedef int difference_type;
7272 typedef std::input_iterator_tag iterator_category;
7273
7274 class pointer {
7275 TemplateArgumentLoc Arg;
7276
7277 public:
7278 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7279
7280 const TemplateArgumentLoc *operator->() const {
7281 return &Arg;
7282 }
7283 };
7284
7285
7286 TemplateArgumentLocContainerIterator() {}
7287
7288 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7289 unsigned Index)
7290 : Container(&Container), Index(Index) { }
7291
7292 TemplateArgumentLocContainerIterator &operator++() {
7293 ++Index;
7294 return *this;
7295 }
7296
7297 TemplateArgumentLocContainerIterator operator++(int) {
7298 TemplateArgumentLocContainerIterator Old(*this);
7299 ++(*this);
7300 return Old;
7301 }
7302
7303 TemplateArgumentLoc operator*() const {
7304 return Container->getArgLoc(Index);
7305 }
7306
7307 pointer operator->() const {
7308 return pointer(Container->getArgLoc(Index));
7309 }
7310
7311 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7312 const TemplateArgumentLocContainerIterator &Y) {
7313 return X.Container == Y.Container && X.Index == Y.Index;
7314 }
7315
7316 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7317 const TemplateArgumentLocContainerIterator &Y) {
7318 return !(X == Y);
7319 }
7320 };
7321
7322template<typename Derived>
7323QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7324 AutoTypeLoc TL) {
7325 const AutoType *T = TL.getTypePtr();
7326 QualType OldDeduced = T->getDeducedType();
7327 QualType NewDeduced;
7328 if (!OldDeduced.isNull()) {
7329 NewDeduced = getDerived().TransformType(OldDeduced);
7330 if (NewDeduced.isNull())
7331 return QualType();
7332 }
7333
7334 ConceptDecl *NewCD = nullptr;
7335 TemplateArgumentListInfo NewTemplateArgs;
7336 NestedNameSpecifierLoc NewNestedNameSpec;
7337 if (T->isConstrained()) {
7338 assert(TL.getConceptReference());
7339 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7340 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7341
7342 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7343 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7344 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7345 if (getDerived().TransformTemplateArguments(
7346 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7347 NewTemplateArgs))
7348 return QualType();
7349
7350 if (TL.getNestedNameSpecifierLoc()) {
7351 NewNestedNameSpec
7352 = getDerived().TransformNestedNameSpecifierLoc(
7353 TL.getNestedNameSpecifierLoc());
7354 if (!NewNestedNameSpec)
7355 return QualType();
7356 }
7357 }
7358
7359 QualType Result = TL.getType();
7360 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7361 T->isDependentType() || T->isConstrained()) {
7362 // FIXME: Maybe don't rebuild if all template arguments are the same.
7363 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7364 NewArgList.reserve(N: NewTemplateArgs.size());
7365 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7366 NewArgList.push_back(Elt: ArgLoc.getArgument());
7367 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7368 NewArgList);
7369 if (Result.isNull())
7370 return QualType();
7371 }
7372
7373 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(T: Result);
7374 NewTL.setNameLoc(TL.getNameLoc());
7375 NewTL.setRParenLoc(TL.getRParenLoc());
7376 NewTL.setConceptReference(nullptr);
7377
7378 if (T->isConstrained()) {
7379 DeclarationNameInfo DNI = DeclarationNameInfo(
7380 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7381 TL.getConceptNameLoc(),
7382 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7383 auto *CR = ConceptReference::Create(
7384 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7385 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7386 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7387 NewTL.setConceptReference(CR);
7388 }
7389
7390 return Result;
7391}
7392
7393template <typename Derived>
7394QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7395 TypeLocBuilder &TLB,
7396 TemplateSpecializationTypeLoc TL,
7397 TemplateName Template) {
7398 TemplateArgumentListInfo NewTemplateArgs;
7399 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7400 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7401 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7402 ArgIterator;
7403 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7404 ArgIterator(TL, TL.getNumArgs()),
7405 NewTemplateArgs))
7406 return QualType();
7407
7408 // This needs to be rebuilt if either the arguments changed, or if the
7409 // original template changed. If the template changed, and even if the
7410 // arguments didn't change, these arguments might not correspond to their
7411 // respective parameters, therefore needing conversions.
7412 QualType Result =
7413 getDerived().RebuildTemplateSpecializationType(Template,
7414 TL.getTemplateNameLoc(),
7415 NewTemplateArgs);
7416
7417 if (!Result.isNull()) {
7418 // Specializations of template template parameters are represented as
7419 // TemplateSpecializationTypes, and substitution of type alias templates
7420 // within a dependent context can transform them into
7421 // DependentTemplateSpecializationTypes.
7422 if (isa<DependentTemplateSpecializationType>(Val: Result)) {
7423 DependentTemplateSpecializationTypeLoc NewTL
7424 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7425 NewTL.setElaboratedKeywordLoc(SourceLocation());
7426 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7427 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7428 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7429 NewTL.setLAngleLoc(TL.getLAngleLoc());
7430 NewTL.setRAngleLoc(TL.getRAngleLoc());
7431 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7432 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7433 return Result;
7434 }
7435
7436 TemplateSpecializationTypeLoc NewTL
7437 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7438 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7439 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7440 NewTL.setLAngleLoc(TL.getLAngleLoc());
7441 NewTL.setRAngleLoc(TL.getRAngleLoc());
7442 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7443 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7444 }
7445
7446 return Result;
7447}
7448
7449template <typename Derived>
7450QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7451 TypeLocBuilder &TLB,
7452 DependentTemplateSpecializationTypeLoc TL,
7453 TemplateName Template,
7454 CXXScopeSpec &SS) {
7455 TemplateArgumentListInfo NewTemplateArgs;
7456 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7457 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7458 typedef TemplateArgumentLocContainerIterator<
7459 DependentTemplateSpecializationTypeLoc> ArgIterator;
7460 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7461 ArgIterator(TL, TL.getNumArgs()),
7462 NewTemplateArgs))
7463 return QualType();
7464
7465 // FIXME: maybe don't rebuild if all the template arguments are the same.
7466
7467 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7468 assert(DTN->getQualifier() == SS.getScopeRep());
7469 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7470 TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments());
7471
7472 DependentTemplateSpecializationTypeLoc NewTL
7473 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7474 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7475 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7476 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7477 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7478 NewTL.setLAngleLoc(TL.getLAngleLoc());
7479 NewTL.setRAngleLoc(TL.getRAngleLoc());
7480 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7481 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7482 return Result;
7483 }
7484
7485 QualType Result
7486 = getDerived().RebuildTemplateSpecializationType(Template,
7487 TL.getTemplateNameLoc(),
7488 NewTemplateArgs);
7489
7490 if (!Result.isNull()) {
7491 /// FIXME: Wrap this in an elaborated-type-specifier?
7492 TemplateSpecializationTypeLoc NewTL
7493 = TLB.push<TemplateSpecializationTypeLoc>(T: Result);
7494 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7495 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7496 NewTL.setLAngleLoc(TL.getLAngleLoc());
7497 NewTL.setRAngleLoc(TL.getRAngleLoc());
7498 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7499 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7500 }
7501
7502 return Result;
7503}
7504
7505template<typename Derived>
7506QualType
7507TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7508 ElaboratedTypeLoc TL) {
7509 const ElaboratedType *T = TL.getTypePtr();
7510
7511 NestedNameSpecifierLoc QualifierLoc;
7512 // NOTE: the qualifier in an ElaboratedType is optional.
7513 if (TL.getQualifierLoc()) {
7514 QualifierLoc
7515 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7516 if (!QualifierLoc)
7517 return QualType();
7518 }
7519
7520 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7521 if (NamedT.isNull())
7522 return QualType();
7523
7524 // C++0x [dcl.type.elab]p2:
7525 // If the identifier resolves to a typedef-name or the simple-template-id
7526 // resolves to an alias template specialization, the
7527 // elaborated-type-specifier is ill-formed.
7528 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7529 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7530 if (const TemplateSpecializationType *TST =
7531 NamedT->getAs<TemplateSpecializationType>()) {
7532 TemplateName Template = TST->getTemplateName();
7533 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7534 Val: Template.getAsTemplateDecl())) {
7535 SemaRef.Diag(Loc: TL.getNamedTypeLoc().getBeginLoc(),
7536 DiagID: diag::err_tag_reference_non_tag)
7537 << TAT << NonTagKind::TypeAliasTemplate
7538 << ElaboratedType::getTagTypeKindForKeyword(Keyword: T->getKeyword());
7539 SemaRef.Diag(Loc: TAT->getLocation(), DiagID: diag::note_declared_at);
7540 }
7541 }
7542 }
7543
7544 QualType Result = TL.getType();
7545 if (getDerived().AlwaysRebuild() ||
7546 QualifierLoc != TL.getQualifierLoc() ||
7547 NamedT != T->getNamedType()) {
7548 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7549 T->getKeyword(),
7550 QualifierLoc, NamedT);
7551 if (Result.isNull())
7552 return QualType();
7553 }
7554
7555 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7556 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7557 NewTL.setQualifierLoc(QualifierLoc);
7558 return Result;
7559}
7560
7561template <typename Derived>
7562QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7563 AttributedTypeLoc TL) {
7564 const AttributedType *oldType = TL.getTypePtr();
7565 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7566 if (modifiedType.isNull())
7567 return QualType();
7568
7569 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7570 const Attr *oldAttr = TL.getAttr();
7571 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7572 if (oldAttr && !newAttr)
7573 return QualType();
7574
7575 QualType result = TL.getType();
7576
7577 // FIXME: dependent operand expressions?
7578 if (getDerived().AlwaysRebuild() ||
7579 modifiedType != oldType->getModifiedType()) {
7580 // If the equivalent type is equal to the modified type, we don't want to
7581 // transform it as well because:
7582 //
7583 // 1. The transformation would yield the same result and is therefore
7584 // superfluous, and
7585 //
7586 // 2. Transforming the same type twice can cause problems, e.g. if it
7587 // is a FunctionProtoType, we may end up instantiating the function
7588 // parameters twice, which causes an assertion since the parameters
7589 // are already bound to their counterparts in the template for this
7590 // instantiation.
7591 //
7592 QualType equivalentType = modifiedType;
7593 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7594 TypeLocBuilder AuxiliaryTLB;
7595 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7596 equivalentType =
7597 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7598 if (equivalentType.isNull())
7599 return QualType();
7600 }
7601
7602 // Check whether we can add nullability; it is only represented as
7603 // type sugar, and therefore cannot be diagnosed in any other way.
7604 if (auto nullability = oldType->getImmediateNullability()) {
7605 if (!modifiedType->canHaveNullability()) {
7606 SemaRef.Diag(Loc: (TL.getAttr() ? TL.getAttr()->getLocation()
7607 : TL.getModifiedLoc().getBeginLoc()),
7608 DiagID: diag::err_nullability_nonpointer)
7609 << DiagNullabilityKind(*nullability, false) << modifiedType;
7610 return QualType();
7611 }
7612 }
7613
7614 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7615 modifiedType,
7616 equivalentType,
7617 attr: TL.getAttr());
7618 }
7619
7620 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(T: result);
7621 newTL.setAttr(newAttr);
7622 return result;
7623}
7624
7625template <typename Derived>
7626QualType TreeTransform<Derived>::TransformCountAttributedType(
7627 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7628 const CountAttributedType *OldTy = TL.getTypePtr();
7629 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7630 if (InnerTy.isNull())
7631 return QualType();
7632
7633 Expr *OldCount = TL.getCountExpr();
7634 Expr *NewCount = nullptr;
7635 if (OldCount) {
7636 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7637 if (CountResult.isInvalid())
7638 return QualType();
7639 NewCount = CountResult.get();
7640 }
7641
7642 QualType Result = TL.getType();
7643 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7644 OldCount != NewCount) {
7645 // Currently, CountAttributedType can only wrap incomplete array types.
7646 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7647 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7648 }
7649
7650 TLB.push<CountAttributedTypeLoc>(T: Result);
7651 return Result;
7652}
7653
7654template <typename Derived>
7655QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7656 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7657 // The BTFTagAttributedType is available for C only.
7658 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7659}
7660
7661template <typename Derived>
7662QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7663 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7664
7665 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7666
7667 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7668 if (WrappedTy.isNull())
7669 return QualType();
7670
7671 QualType ContainedTy = QualType();
7672 QualType OldContainedTy = oldType->getContainedType();
7673 if (!OldContainedTy.isNull()) {
7674 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7675 if (!oldContainedTSI)
7676 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7677 OldContainedTy, SourceLocation());
7678 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7679 if (!ContainedTSI)
7680 return QualType();
7681 ContainedTy = ContainedTSI->getType();
7682 }
7683
7684 QualType Result = TL.getType();
7685 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7686 ContainedTy != oldType->getContainedType()) {
7687 Result = SemaRef.Context.getHLSLAttributedResourceType(
7688 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7689 }
7690
7691 TLB.push<HLSLAttributedResourceTypeLoc>(T: Result);
7692 return Result;
7693}
7694
7695template <typename Derived>
7696QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7697 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7698 // No transformations needed.
7699 return TL.getType();
7700}
7701
7702template<typename Derived>
7703QualType
7704TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7705 ParenTypeLoc TL) {
7706 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7707 if (Inner.isNull())
7708 return QualType();
7709
7710 QualType Result = TL.getType();
7711 if (getDerived().AlwaysRebuild() ||
7712 Inner != TL.getInnerLoc().getType()) {
7713 Result = getDerived().RebuildParenType(Inner);
7714 if (Result.isNull())
7715 return QualType();
7716 }
7717
7718 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(T: Result);
7719 NewTL.setLParenLoc(TL.getLParenLoc());
7720 NewTL.setRParenLoc(TL.getRParenLoc());
7721 return Result;
7722}
7723
7724template <typename Derived>
7725QualType
7726TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7727 MacroQualifiedTypeLoc TL) {
7728 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7729 if (Inner.isNull())
7730 return QualType();
7731
7732 QualType Result = TL.getType();
7733 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7734 Result =
7735 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7736 if (Result.isNull())
7737 return QualType();
7738 }
7739
7740 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(T: Result);
7741 NewTL.setExpansionLoc(TL.getExpansionLoc());
7742 return Result;
7743}
7744
7745template<typename Derived>
7746QualType TreeTransform<Derived>::TransformDependentNameType(
7747 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7748 return TransformDependentNameType(TLB, TL, false);
7749}
7750
7751template<typename Derived>
7752QualType TreeTransform<Derived>::TransformDependentNameType(
7753 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7754 const DependentNameType *T = TL.getTypePtr();
7755
7756 NestedNameSpecifierLoc QualifierLoc
7757 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7758 if (!QualifierLoc)
7759 return QualType();
7760
7761 QualType Result
7762 = getDerived().RebuildDependentNameType(T->getKeyword(),
7763 TL.getElaboratedKeywordLoc(),
7764 QualifierLoc,
7765 T->getIdentifier(),
7766 TL.getNameLoc(),
7767 DeducedTSTContext);
7768 if (Result.isNull())
7769 return QualType();
7770
7771 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7772 QualType NamedT = ElabT->getNamedType();
7773 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7774
7775 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7776 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7777 NewTL.setQualifierLoc(QualifierLoc);
7778 } else {
7779 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(T: Result);
7780 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7781 NewTL.setQualifierLoc(QualifierLoc);
7782 NewTL.setNameLoc(TL.getNameLoc());
7783 }
7784 return Result;
7785}
7786
7787template<typename Derived>
7788QualType TreeTransform<Derived>::
7789 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7790 DependentTemplateSpecializationTypeLoc TL) {
7791 NestedNameSpecifierLoc QualifierLoc;
7792 if (TL.getQualifierLoc()) {
7793 QualifierLoc
7794 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7795 if (!QualifierLoc)
7796 return QualType();
7797 }
7798
7799 CXXScopeSpec SS;
7800 SS.Adopt(Other: QualifierLoc);
7801 return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS);
7802}
7803
7804template <typename Derived>
7805QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7806 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
7807 CXXScopeSpec &SS) {
7808 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7809
7810 TemplateArgumentListInfo NewTemplateArgs;
7811 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7812 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7813
7814 auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator<
7815 DependentTemplateSpecializationTypeLoc>>(x: {TL, 0}, y: {TL, TL.getNumArgs()});
7816
7817 if (getDerived().TransformTemplateArguments(ArgsRange.begin(),
7818 ArgsRange.end(), NewTemplateArgs))
7819 return QualType();
7820 bool TemplateArgumentsChanged = !llvm::equal(
7821 ArgsRange, NewTemplateArgs.arguments(),
7822 [](const TemplateArgumentLoc &A, const TemplateArgumentLoc &B) {
7823 return A.getArgument().structurallyEquals(Other: B.getArgument());
7824 });
7825
7826 const DependentTemplateStorage &DTN = T->getDependentTemplateName();
7827
7828 QualType Result = TL.getType();
7829 if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() ||
7830 TemplateArgumentsChanged) {
7831 TemplateName Name = getDerived().RebuildTemplateName(
7832 SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(),
7833 /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7834 /*AllowInjectedClassName=*/false);
7835 if (Name.isNull())
7836 return QualType();
7837 Result = getDerived().RebuildDependentTemplateSpecializationType(
7838 T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name,
7839 TL.getTemplateNameLoc(), NewTemplateArgs,
7840 /*AllowInjectedClassName=*/false);
7841 if (Result.isNull())
7842 return QualType();
7843 }
7844
7845 NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context&: SemaRef.Context);
7846 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Val&: Result)) {
7847 QualType NamedT = ElabT->getNamedType();
7848
7849 // Copy information relevant to the template specialization.
7850 TemplateSpecializationTypeLoc NamedTL
7851 = TLB.push<TemplateSpecializationTypeLoc>(T: NamedT);
7852 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7853 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7854 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7855 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7856 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7857 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7858
7859 // Copy information relevant to the elaborated type.
7860 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(T: Result);
7861 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7862 NewTL.setQualifierLoc(QualifierLoc);
7863 } else {
7864 assert(isa<DependentTemplateSpecializationType>(Result));
7865 DependentTemplateSpecializationTypeLoc SpecTL
7866 = TLB.push<DependentTemplateSpecializationTypeLoc>(T: Result);
7867 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7868 SpecTL.setQualifierLoc(QualifierLoc);
7869 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7870 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7871 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7872 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7873 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7874 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7875 }
7876 return Result;
7877}
7878
7879template<typename Derived>
7880QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7881 PackExpansionTypeLoc TL) {
7882 QualType Pattern
7883 = getDerived().TransformType(TLB, TL.getPatternLoc());
7884 if (Pattern.isNull())
7885 return QualType();
7886
7887 QualType Result = TL.getType();
7888 if (getDerived().AlwaysRebuild() ||
7889 Pattern != TL.getPatternLoc().getType()) {
7890 Result = getDerived().RebuildPackExpansionType(Pattern,
7891 TL.getPatternLoc().getSourceRange(),
7892 TL.getEllipsisLoc(),
7893 TL.getTypePtr()->getNumExpansions());
7894 if (Result.isNull())
7895 return QualType();
7896 }
7897
7898 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(T: Result);
7899 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7900 return Result;
7901}
7902
7903template<typename Derived>
7904QualType
7905TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7906 ObjCInterfaceTypeLoc TL) {
7907 // ObjCInterfaceType is never dependent.
7908 TLB.pushFullCopy(L: TL);
7909 return TL.getType();
7910}
7911
7912template<typename Derived>
7913QualType
7914TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7915 ObjCTypeParamTypeLoc TL) {
7916 const ObjCTypeParamType *T = TL.getTypePtr();
7917 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7918 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7919 if (!OTP)
7920 return QualType();
7921
7922 QualType Result = TL.getType();
7923 if (getDerived().AlwaysRebuild() ||
7924 OTP != T->getDecl()) {
7925 Result = getDerived().RebuildObjCTypeParamType(
7926 OTP, TL.getProtocolLAngleLoc(),
7927 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7928 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7929 if (Result.isNull())
7930 return QualType();
7931 }
7932
7933 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(T: Result);
7934 if (TL.getNumProtocols()) {
7935 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7936 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7937 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7938 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7939 }
7940 return Result;
7941}
7942
7943template<typename Derived>
7944QualType
7945TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7946 ObjCObjectTypeLoc TL) {
7947 // Transform base type.
7948 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7949 if (BaseType.isNull())
7950 return QualType();
7951
7952 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7953
7954 // Transform type arguments.
7955 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7956 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7957 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7958 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7959 QualType TypeArg = TypeArgInfo->getType();
7960 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7961 AnyChanged = true;
7962
7963 // We have a pack expansion. Instantiate it.
7964 const auto *PackExpansion = PackExpansionLoc.getType()
7965 ->castAs<PackExpansionType>();
7966 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7967 SemaRef.collectUnexpandedParameterPacks(T: PackExpansion->getPattern(),
7968 Unexpanded);
7969 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7970
7971 // Determine whether the set of unexpanded parameter packs can
7972 // and should be expanded.
7973 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7974 bool Expand = false;
7975 bool RetainExpansion = false;
7976 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
7977 if (getDerived().TryExpandParameterPacks(
7978 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7979 Unexpanded, Expand, RetainExpansion, NumExpansions))
7980 return QualType();
7981
7982 if (!Expand) {
7983 // We can't expand this pack expansion into separate arguments yet;
7984 // just substitute into the pattern and create a new pack expansion
7985 // type.
7986 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7987
7988 TypeLocBuilder TypeArgBuilder;
7989 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7990 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7991 PatternLoc);
7992 if (NewPatternType.isNull())
7993 return QualType();
7994
7995 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7996 Pattern: NewPatternType, NumExpansions);
7997 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(T: NewExpansionType);
7998 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7999 NewTypeArgInfos.push_back(
8000 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
8001 continue;
8002 }
8003
8004 // Substitute into the pack expansion pattern for each slice of the
8005 // pack.
8006 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
8007 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
8008
8009 TypeLocBuilder TypeArgBuilder;
8010 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8011
8012 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8013 PatternLoc);
8014 if (NewTypeArg.isNull())
8015 return QualType();
8016
8017 NewTypeArgInfos.push_back(
8018 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8019 }
8020
8021 continue;
8022 }
8023
8024 TypeLocBuilder TypeArgBuilder;
8025 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8026 QualType NewTypeArg =
8027 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8028 if (NewTypeArg.isNull())
8029 return QualType();
8030
8031 // If nothing changed, just keep the old TypeSourceInfo.
8032 if (NewTypeArg == TypeArg) {
8033 NewTypeArgInfos.push_back(Elt: TypeArgInfo);
8034 continue;
8035 }
8036
8037 NewTypeArgInfos.push_back(
8038 Elt: TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8039 AnyChanged = true;
8040 }
8041
8042 QualType Result = TL.getType();
8043 if (getDerived().AlwaysRebuild() || AnyChanged) {
8044 // Rebuild the type.
8045 Result = getDerived().RebuildObjCObjectType(
8046 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8047 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8048 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8049 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8050
8051 if (Result.isNull())
8052 return QualType();
8053 }
8054
8055 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(T: Result);
8056 NewT.setHasBaseTypeAsWritten(true);
8057 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8058 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8059 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8060 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8061 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8062 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8063 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8064 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8065 return Result;
8066}
8067
8068template<typename Derived>
8069QualType
8070TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8071 ObjCObjectPointerTypeLoc TL) {
8072 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8073 if (PointeeType.isNull())
8074 return QualType();
8075
8076 QualType Result = TL.getType();
8077 if (getDerived().AlwaysRebuild() ||
8078 PointeeType != TL.getPointeeLoc().getType()) {
8079 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8080 TL.getStarLoc());
8081 if (Result.isNull())
8082 return QualType();
8083 }
8084
8085 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(T: Result);
8086 NewT.setStarLoc(TL.getStarLoc());
8087 return Result;
8088}
8089
8090//===----------------------------------------------------------------------===//
8091// Statement transformation
8092//===----------------------------------------------------------------------===//
8093template<typename Derived>
8094StmtResult
8095TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8096 return S;
8097}
8098
8099template<typename Derived>
8100StmtResult
8101TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8102 return getDerived().TransformCompoundStmt(S, false);
8103}
8104
8105template<typename Derived>
8106StmtResult
8107TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8108 bool IsStmtExpr) {
8109 Sema::CompoundScopeRAII CompoundScope(getSema());
8110 Sema::FPFeaturesStateRAII FPSave(getSema());
8111 if (S->hasStoredFPFeatures())
8112 getSema().resetFPOptions(
8113 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8114
8115 const Stmt *ExprResult = S->getStmtExprResult();
8116 bool SubStmtInvalid = false;
8117 bool SubStmtChanged = false;
8118 SmallVector<Stmt*, 8> Statements;
8119 for (auto *B : S->body()) {
8120 StmtResult Result = getDerived().TransformStmt(
8121 B, IsStmtExpr && B == ExprResult ? StmtDiscardKind::StmtExprResult
8122 : StmtDiscardKind::Discarded);
8123
8124 if (Result.isInvalid()) {
8125 // Immediately fail if this was a DeclStmt, since it's very
8126 // likely that this will cause problems for future statements.
8127 if (isa<DeclStmt>(Val: B))
8128 return StmtError();
8129
8130 // Otherwise, just keep processing substatements and fail later.
8131 SubStmtInvalid = true;
8132 continue;
8133 }
8134
8135 SubStmtChanged = SubStmtChanged || Result.get() != B;
8136 Statements.push_back(Elt: Result.getAs<Stmt>());
8137 }
8138
8139 if (SubStmtInvalid)
8140 return StmtError();
8141
8142 if (!getDerived().AlwaysRebuild() &&
8143 !SubStmtChanged)
8144 return S;
8145
8146 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8147 Statements,
8148 S->getRBracLoc(),
8149 IsStmtExpr);
8150}
8151
8152template<typename Derived>
8153StmtResult
8154TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8155 ExprResult LHS, RHS;
8156 {
8157 EnterExpressionEvaluationContext Unevaluated(
8158 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8159
8160 // Transform the left-hand case value.
8161 LHS = getDerived().TransformExpr(S->getLHS());
8162 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8163 if (LHS.isInvalid())
8164 return StmtError();
8165
8166 // Transform the right-hand case value (for the GNU case-range extension).
8167 RHS = getDerived().TransformExpr(S->getRHS());
8168 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8169 if (RHS.isInvalid())
8170 return StmtError();
8171 }
8172
8173 // Build the case statement.
8174 // Case statements are always rebuilt so that they will attached to their
8175 // transformed switch statement.
8176 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8177 LHS.get(),
8178 S->getEllipsisLoc(),
8179 RHS.get(),
8180 S->getColonLoc());
8181 if (Case.isInvalid())
8182 return StmtError();
8183
8184 // Transform the statement following the case
8185 StmtResult SubStmt =
8186 getDerived().TransformStmt(S->getSubStmt());
8187 if (SubStmt.isInvalid())
8188 return StmtError();
8189
8190 // Attach the body to the case statement
8191 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8192}
8193
8194template <typename Derived>
8195StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8196 // Transform the statement following the default case
8197 StmtResult SubStmt =
8198 getDerived().TransformStmt(S->getSubStmt());
8199 if (SubStmt.isInvalid())
8200 return StmtError();
8201
8202 // Default statements are always rebuilt
8203 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8204 SubStmt.get());
8205}
8206
8207template<typename Derived>
8208StmtResult
8209TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8210 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8211 if (SubStmt.isInvalid())
8212 return StmtError();
8213
8214 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8215 S->getDecl());
8216 if (!LD)
8217 return StmtError();
8218
8219 // If we're transforming "in-place" (we're not creating new local
8220 // declarations), assume we're replacing the old label statement
8221 // and clear out the reference to it.
8222 if (LD == S->getDecl())
8223 S->getDecl()->setStmt(nullptr);
8224
8225 // FIXME: Pass the real colon location in.
8226 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8227 cast<LabelDecl>(Val: LD), SourceLocation(),
8228 SubStmt.get());
8229}
8230
8231template <typename Derived>
8232const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8233 if (!R)
8234 return R;
8235
8236 switch (R->getKind()) {
8237// Transform attributes by calling TransformXXXAttr.
8238#define ATTR(X) \
8239 case attr::X: \
8240 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8241#include "clang/Basic/AttrList.inc"
8242 }
8243 return R;
8244}
8245
8246template <typename Derived>
8247const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8248 const Stmt *InstS,
8249 const Attr *R) {
8250 if (!R)
8251 return R;
8252
8253 switch (R->getKind()) {
8254// Transform attributes by calling TransformStmtXXXAttr.
8255#define ATTR(X) \
8256 case attr::X: \
8257 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8258#include "clang/Basic/AttrList.inc"
8259 }
8260 return TransformAttr(R);
8261}
8262
8263template <typename Derived>
8264StmtResult
8265TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8266 StmtDiscardKind SDK) {
8267 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8268 if (SubStmt.isInvalid())
8269 return StmtError();
8270
8271 bool AttrsChanged = false;
8272 SmallVector<const Attr *, 1> Attrs;
8273
8274 // Visit attributes and keep track if any are transformed.
8275 for (const auto *I : S->getAttrs()) {
8276 const Attr *R =
8277 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8278 AttrsChanged |= (I != R);
8279 if (R)
8280 Attrs.push_back(Elt: R);
8281 }
8282
8283 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8284 return S;
8285
8286 // If transforming the attributes failed for all of the attributes in the
8287 // statement, don't make an AttributedStmt without attributes.
8288 if (Attrs.empty())
8289 return SubStmt;
8290
8291 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8292 SubStmt.get());
8293}
8294
8295template<typename Derived>
8296StmtResult
8297TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8298 // Transform the initialization statement
8299 StmtResult Init = getDerived().TransformStmt(S->getInit());
8300 if (Init.isInvalid())
8301 return StmtError();
8302
8303 Sema::ConditionResult Cond;
8304 if (!S->isConsteval()) {
8305 // Transform the condition
8306 Cond = getDerived().TransformCondition(
8307 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8308 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8309 : Sema::ConditionKind::Boolean);
8310 if (Cond.isInvalid())
8311 return StmtError();
8312 }
8313
8314 // If this is a constexpr if, determine which arm we should instantiate.
8315 std::optional<bool> ConstexprConditionValue;
8316 if (S->isConstexpr())
8317 ConstexprConditionValue = Cond.getKnownValue();
8318
8319 // Transform the "then" branch.
8320 StmtResult Then;
8321 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8322 EnterExpressionEvaluationContext Ctx(
8323 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8324 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8325 S->isNonNegatedConsteval());
8326
8327 Then = getDerived().TransformStmt(S->getThen());
8328 if (Then.isInvalid())
8329 return StmtError();
8330 } else {
8331 // Discarded branch is replaced with empty CompoundStmt so we can keep
8332 // proper source location for start and end of original branch, so
8333 // subsequent transformations like CoverageMapping work properly
8334 Then = new (getSema().Context)
8335 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8336 }
8337
8338 // Transform the "else" branch.
8339 StmtResult Else;
8340 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8341 EnterExpressionEvaluationContext Ctx(
8342 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8343 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8344 S->isNegatedConsteval());
8345
8346 Else = getDerived().TransformStmt(S->getElse());
8347 if (Else.isInvalid())
8348 return StmtError();
8349 } else if (S->getElse() && ConstexprConditionValue &&
8350 *ConstexprConditionValue) {
8351 // Same thing here as with <then> branch, we are discarding it, we can't
8352 // replace it with NULL nor NullStmt as we need to keep for source location
8353 // range, for CoverageMapping
8354 Else = new (getSema().Context)
8355 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8356 }
8357
8358 if (!getDerived().AlwaysRebuild() &&
8359 Init.get() == S->getInit() &&
8360 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8361 Then.get() == S->getThen() &&
8362 Else.get() == S->getElse())
8363 return S;
8364
8365 return getDerived().RebuildIfStmt(
8366 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8367 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8368}
8369
8370template<typename Derived>
8371StmtResult
8372TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8373 // Transform the initialization statement
8374 StmtResult Init = getDerived().TransformStmt(S->getInit());
8375 if (Init.isInvalid())
8376 return StmtError();
8377
8378 // Transform the condition.
8379 Sema::ConditionResult Cond = getDerived().TransformCondition(
8380 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8381 Sema::ConditionKind::Switch);
8382 if (Cond.isInvalid())
8383 return StmtError();
8384
8385 // Rebuild the switch statement.
8386 StmtResult Switch =
8387 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8388 Init.get(), Cond, S->getRParenLoc());
8389 if (Switch.isInvalid())
8390 return StmtError();
8391
8392 // Transform the body of the switch statement.
8393 StmtResult Body = getDerived().TransformStmt(S->getBody());
8394 if (Body.isInvalid())
8395 return StmtError();
8396
8397 // Complete the switch statement.
8398 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8399 Body.get());
8400}
8401
8402template<typename Derived>
8403StmtResult
8404TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8405 // Transform the condition
8406 Sema::ConditionResult Cond = getDerived().TransformCondition(
8407 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8408 Sema::ConditionKind::Boolean);
8409 if (Cond.isInvalid())
8410 return StmtError();
8411
8412 // OpenACC Restricts a while-loop inside of certain construct/clause
8413 // combinations, so diagnose that here in OpenACC mode.
8414 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8415 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8416
8417 // Transform the body
8418 StmtResult Body = getDerived().TransformStmt(S->getBody());
8419 if (Body.isInvalid())
8420 return StmtError();
8421
8422 if (!getDerived().AlwaysRebuild() &&
8423 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8424 Body.get() == S->getBody())
8425 return Owned(S);
8426
8427 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8428 Cond, S->getRParenLoc(), Body.get());
8429}
8430
8431template<typename Derived>
8432StmtResult
8433TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8434 // OpenACC Restricts a do-loop inside of certain construct/clause
8435 // combinations, so diagnose that here in OpenACC mode.
8436 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8437 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8438
8439 // Transform the body
8440 StmtResult Body = getDerived().TransformStmt(S->getBody());
8441 if (Body.isInvalid())
8442 return StmtError();
8443
8444 // Transform the condition
8445 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8446 if (Cond.isInvalid())
8447 return StmtError();
8448
8449 if (!getDerived().AlwaysRebuild() &&
8450 Cond.get() == S->getCond() &&
8451 Body.get() == S->getBody())
8452 return S;
8453
8454 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8455 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8456 S->getRParenLoc());
8457}
8458
8459template<typename Derived>
8460StmtResult
8461TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8462 if (getSema().getLangOpts().OpenMP)
8463 getSema().OpenMP().startOpenMPLoop();
8464
8465 // Transform the initialization statement
8466 StmtResult Init = getDerived().TransformStmt(S->getInit());
8467 if (Init.isInvalid())
8468 return StmtError();
8469
8470 // In OpenMP loop region loop control variable must be captured and be
8471 // private. Perform analysis of first part (if any).
8472 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8473 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8474 Init.get());
8475
8476 // Transform the condition
8477 Sema::ConditionResult Cond = getDerived().TransformCondition(
8478 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8479 Sema::ConditionKind::Boolean);
8480 if (Cond.isInvalid())
8481 return StmtError();
8482
8483 // Transform the increment
8484 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8485 if (Inc.isInvalid())
8486 return StmtError();
8487
8488 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8489 if (S->getInc() && !FullInc.get())
8490 return StmtError();
8491
8492 // OpenACC Restricts a for-loop inside of certain construct/clause
8493 // combinations, so diagnose that here in OpenACC mode.
8494 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8495 SemaRef.OpenACC().ActOnForStmtBegin(
8496 ForLoc: S->getBeginLoc(), OldFirst: S->getInit(), First: Init.get(), OldSecond: S->getCond(),
8497 Second: Cond.get().second, OldThird: S->getInc(), Third: Inc.get());
8498
8499 // Transform the body
8500 StmtResult Body = getDerived().TransformStmt(S->getBody());
8501 if (Body.isInvalid())
8502 return StmtError();
8503
8504 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8505
8506 if (!getDerived().AlwaysRebuild() &&
8507 Init.get() == S->getInit() &&
8508 Cond.get() == std::make_pair(x: S->getConditionVariable(), y: S->getCond()) &&
8509 Inc.get() == S->getInc() &&
8510 Body.get() == S->getBody())
8511 return S;
8512
8513 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8514 Init.get(), Cond, FullInc,
8515 S->getRParenLoc(), Body.get());
8516}
8517
8518template<typename Derived>
8519StmtResult
8520TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8521 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8522 S->getLabel());
8523 if (!LD)
8524 return StmtError();
8525
8526 // Goto statements must always be rebuilt, to resolve the label.
8527 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8528 cast<LabelDecl>(Val: LD));
8529}
8530
8531template<typename Derived>
8532StmtResult
8533TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8534 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8535 if (Target.isInvalid())
8536 return StmtError();
8537 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8538
8539 if (!getDerived().AlwaysRebuild() &&
8540 Target.get() == S->getTarget())
8541 return S;
8542
8543 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8544 Target.get());
8545}
8546
8547template<typename Derived>
8548StmtResult
8549TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8550 return S;
8551}
8552
8553template<typename Derived>
8554StmtResult
8555TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8556 return S;
8557}
8558
8559template<typename Derived>
8560StmtResult
8561TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8562 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8563 /*NotCopyInit*/false);
8564 if (Result.isInvalid())
8565 return StmtError();
8566
8567 // FIXME: We always rebuild the return statement because there is no way
8568 // to tell whether the return type of the function has changed.
8569 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8570}
8571
8572template<typename Derived>
8573StmtResult
8574TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8575 bool DeclChanged = false;
8576 SmallVector<Decl *, 4> Decls;
8577 LambdaScopeInfo *LSI = getSema().getCurLambda();
8578 for (auto *D : S->decls()) {
8579 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8580 if (!Transformed)
8581 return StmtError();
8582
8583 if (Transformed != D)
8584 DeclChanged = true;
8585
8586 if (LSI) {
8587 if (auto *TD = dyn_cast<TypeDecl>(Val: Transformed))
8588 LSI->ContainsUnexpandedParameterPack |=
8589 getSema()
8590 .getASTContext()
8591 .getTypeDeclType(TD)
8592 .getSingleStepDesugaredType(getSema().getASTContext())
8593 ->containsUnexpandedParameterPack();
8594
8595 if (auto *VD = dyn_cast<VarDecl>(Val: Transformed))
8596 LSI->ContainsUnexpandedParameterPack |=
8597 VD->getType()->containsUnexpandedParameterPack();
8598 }
8599
8600 Decls.push_back(Elt: Transformed);
8601 }
8602
8603 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8604 return S;
8605
8606 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8607}
8608
8609template<typename Derived>
8610StmtResult
8611TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8612
8613 SmallVector<Expr*, 8> Constraints;
8614 SmallVector<Expr*, 8> Exprs;
8615 SmallVector<IdentifierInfo *, 4> Names;
8616
8617 SmallVector<Expr*, 8> Clobbers;
8618
8619 bool ExprsChanged = false;
8620
8621 auto RebuildString = [&](Expr *E) {
8622 ExprResult Result = getDerived().TransformExpr(E);
8623 if (!Result.isUsable())
8624 return Result;
8625 if (Result.get() != E) {
8626 ExprsChanged = true;
8627 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8628 }
8629 return Result;
8630 };
8631
8632 // Go through the outputs.
8633 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8634 Names.push_back(Elt: S->getOutputIdentifier(i: I));
8635
8636 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8637 if (Result.isInvalid())
8638 return StmtError();
8639
8640 Constraints.push_back(Elt: Result.get());
8641
8642 // Transform the output expr.
8643 Expr *OutputExpr = S->getOutputExpr(i: I);
8644 Result = getDerived().TransformExpr(OutputExpr);
8645 if (Result.isInvalid())
8646 return StmtError();
8647
8648 ExprsChanged |= Result.get() != OutputExpr;
8649
8650 Exprs.push_back(Elt: Result.get());
8651 }
8652
8653 // Go through the inputs.
8654 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8655 Names.push_back(Elt: S->getInputIdentifier(i: I));
8656
8657 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8658 if (Result.isInvalid())
8659 return StmtError();
8660
8661 Constraints.push_back(Elt: Result.get());
8662
8663 // Transform the input expr.
8664 Expr *InputExpr = S->getInputExpr(i: I);
8665 Result = getDerived().TransformExpr(InputExpr);
8666 if (Result.isInvalid())
8667 return StmtError();
8668
8669 ExprsChanged |= Result.get() != InputExpr;
8670
8671 Exprs.push_back(Elt: Result.get());
8672 }
8673
8674 // Go through the Labels.
8675 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8676 Names.push_back(Elt: S->getLabelIdentifier(i: I));
8677
8678 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8679 if (Result.isInvalid())
8680 return StmtError();
8681 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8682 Exprs.push_back(Elt: Result.get());
8683 }
8684
8685 // Go through the clobbers.
8686 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8687 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8688 if (Result.isInvalid())
8689 return StmtError();
8690 Clobbers.push_back(Elt: Result.get());
8691 }
8692
8693 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8694 if (AsmString.isInvalid())
8695 return StmtError();
8696
8697 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8698 return S;
8699
8700 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8701 S->isVolatile(), S->getNumOutputs(),
8702 S->getNumInputs(), Names.data(),
8703 Constraints, Exprs, AsmString.get(),
8704 Clobbers, S->getNumLabels(),
8705 S->getRParenLoc());
8706}
8707
8708template<typename Derived>
8709StmtResult
8710TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8711 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8712
8713 bool HadError = false, HadChange = false;
8714
8715 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8716 SmallVector<Expr*, 8> TransformedExprs;
8717 TransformedExprs.reserve(N: SrcExprs.size());
8718 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8719 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8720 if (!Result.isUsable()) {
8721 HadError = true;
8722 } else {
8723 HadChange |= (Result.get() != SrcExprs[i]);
8724 TransformedExprs.push_back(Elt: Result.get());
8725 }
8726 }
8727
8728 if (HadError) return StmtError();
8729 if (!HadChange && !getDerived().AlwaysRebuild())
8730 return Owned(S);
8731
8732 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8733 AsmToks, S->getAsmString(),
8734 S->getNumOutputs(), S->getNumInputs(),
8735 S->getAllConstraints(), S->getClobbers(),
8736 TransformedExprs, S->getEndLoc());
8737}
8738
8739// C++ Coroutines
8740template<typename Derived>
8741StmtResult
8742TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8743 auto *ScopeInfo = SemaRef.getCurFunction();
8744 auto *FD = cast<FunctionDecl>(Val: SemaRef.CurContext);
8745 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8746 ScopeInfo->NeedsCoroutineSuspends &&
8747 ScopeInfo->CoroutineSuspends.first == nullptr &&
8748 ScopeInfo->CoroutineSuspends.second == nullptr &&
8749 "expected clean scope info");
8750
8751 // Set that we have (possibly-invalid) suspend points before we do anything
8752 // that may fail.
8753 ScopeInfo->setNeedsCoroutineSuspends(false);
8754
8755 // We re-build the coroutine promise object (and the coroutine parameters its
8756 // type and constructor depend on) based on the types used in our current
8757 // function. We must do so, and set it on the current FunctionScopeInfo,
8758 // before attempting to transform the other parts of the coroutine body
8759 // statement, such as the implicit suspend statements (because those
8760 // statements reference the FunctionScopeInfo::CoroutinePromise).
8761 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8762 return StmtError();
8763 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8764 if (!Promise)
8765 return StmtError();
8766 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8767 ScopeInfo->CoroutinePromise = Promise;
8768
8769 // Transform the implicit coroutine statements constructed using dependent
8770 // types during the previous parse: initial and final suspensions, the return
8771 // object, and others. We also transform the coroutine function's body.
8772 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8773 if (InitSuspend.isInvalid())
8774 return StmtError();
8775 StmtResult FinalSuspend =
8776 getDerived().TransformStmt(S->getFinalSuspendStmt());
8777 if (FinalSuspend.isInvalid() ||
8778 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8779 return StmtError();
8780 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8781 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8782
8783 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8784 if (BodyRes.isInvalid())
8785 return StmtError();
8786
8787 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8788 if (Builder.isInvalid())
8789 return StmtError();
8790
8791 Expr *ReturnObject = S->getReturnValueInit();
8792 assert(ReturnObject && "the return object is expected to be valid");
8793 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8794 /*NoCopyInit*/ false);
8795 if (Res.isInvalid())
8796 return StmtError();
8797 Builder.ReturnValue = Res.get();
8798
8799 // If during the previous parse the coroutine still had a dependent promise
8800 // statement, we may need to build some implicit coroutine statements
8801 // (such as exception and fallthrough handlers) for the first time.
8802 if (S->hasDependentPromiseType()) {
8803 // We can only build these statements, however, if the current promise type
8804 // is not dependent.
8805 if (!Promise->getType()->isDependentType()) {
8806 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8807 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8808 "these nodes should not have been built yet");
8809 if (!Builder.buildDependentStatements())
8810 return StmtError();
8811 }
8812 } else {
8813 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8814 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8815 if (Res.isInvalid())
8816 return StmtError();
8817 Builder.OnFallthrough = Res.get();
8818 }
8819
8820 if (auto *OnException = S->getExceptionHandler()) {
8821 StmtResult Res = getDerived().TransformStmt(OnException);
8822 if (Res.isInvalid())
8823 return StmtError();
8824 Builder.OnException = Res.get();
8825 }
8826
8827 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8828 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8829 if (Res.isInvalid())
8830 return StmtError();
8831 Builder.ReturnStmtOnAllocFailure = Res.get();
8832 }
8833
8834 // Transform any additional statements we may have already built
8835 assert(S->getAllocate() && S->getDeallocate() &&
8836 "allocation and deallocation calls must already be built");
8837 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8838 if (AllocRes.isInvalid())
8839 return StmtError();
8840 Builder.Allocate = AllocRes.get();
8841
8842 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8843 if (DeallocRes.isInvalid())
8844 return StmtError();
8845 Builder.Deallocate = DeallocRes.get();
8846
8847 if (auto *ResultDecl = S->getResultDecl()) {
8848 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8849 if (Res.isInvalid())
8850 return StmtError();
8851 Builder.ResultDecl = Res.get();
8852 }
8853
8854 if (auto *ReturnStmt = S->getReturnStmt()) {
8855 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8856 if (Res.isInvalid())
8857 return StmtError();
8858 Builder.ReturnStmt = Res.get();
8859 }
8860 }
8861
8862 return getDerived().RebuildCoroutineBodyStmt(Builder);
8863}
8864
8865template<typename Derived>
8866StmtResult
8867TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8868 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8869 /*NotCopyInit*/false);
8870 if (Result.isInvalid())
8871 return StmtError();
8872
8873 // Always rebuild; we don't know if this needs to be injected into a new
8874 // context or if the promise type has changed.
8875 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8876 S->isImplicit());
8877}
8878
8879template <typename Derived>
8880ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8881 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8882 /*NotCopyInit*/ false);
8883 if (Operand.isInvalid())
8884 return ExprError();
8885
8886 // Rebuild the common-expr from the operand rather than transforming it
8887 // separately.
8888
8889 // FIXME: getCurScope() should not be used during template instantiation.
8890 // We should pick up the set of unqualified lookup results for operator
8891 // co_await during the initial parse.
8892 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8893 getSema().getCurScope(), E->getKeywordLoc());
8894
8895 // Always rebuild; we don't know if this needs to be injected into a new
8896 // context or if the promise type has changed.
8897 return getDerived().RebuildCoawaitExpr(
8898 E->getKeywordLoc(), Operand.get(),
8899 cast<UnresolvedLookupExpr>(Val: Lookup.get()), E->isImplicit());
8900}
8901
8902template <typename Derived>
8903ExprResult
8904TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8905 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8906 /*NotCopyInit*/ false);
8907 if (OperandResult.isInvalid())
8908 return ExprError();
8909
8910 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8911 E->getOperatorCoawaitLookup());
8912
8913 if (LookupResult.isInvalid())
8914 return ExprError();
8915
8916 // Always rebuild; we don't know if this needs to be injected into a new
8917 // context or if the promise type has changed.
8918 return getDerived().RebuildDependentCoawaitExpr(
8919 E->getKeywordLoc(), OperandResult.get(),
8920 cast<UnresolvedLookupExpr>(Val: LookupResult.get()));
8921}
8922
8923template<typename Derived>
8924ExprResult
8925TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8926 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8927 /*NotCopyInit*/false);
8928 if (Result.isInvalid())
8929 return ExprError();
8930
8931 // Always rebuild; we don't know if this needs to be injected into a new
8932 // context or if the promise type has changed.
8933 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8934}
8935
8936// Objective-C Statements.
8937
8938template<typename Derived>
8939StmtResult
8940TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8941 // Transform the body of the @try.
8942 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8943 if (TryBody.isInvalid())
8944 return StmtError();
8945
8946 // Transform the @catch statements (if present).
8947 bool AnyCatchChanged = false;
8948 SmallVector<Stmt*, 8> CatchStmts;
8949 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8950 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8951 if (Catch.isInvalid())
8952 return StmtError();
8953 if (Catch.get() != S->getCatchStmt(I))
8954 AnyCatchChanged = true;
8955 CatchStmts.push_back(Elt: Catch.get());
8956 }
8957
8958 // Transform the @finally statement (if present).
8959 StmtResult Finally;
8960 if (S->getFinallyStmt()) {
8961 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8962 if (Finally.isInvalid())
8963 return StmtError();
8964 }
8965
8966 // If nothing changed, just retain this statement.
8967 if (!getDerived().AlwaysRebuild() &&
8968 TryBody.get() == S->getTryBody() &&
8969 !AnyCatchChanged &&
8970 Finally.get() == S->getFinallyStmt())
8971 return S;
8972
8973 // Build a new statement.
8974 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8975 CatchStmts, Finally.get());
8976}
8977
8978template<typename Derived>
8979StmtResult
8980TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8981 // Transform the @catch parameter, if there is one.
8982 VarDecl *Var = nullptr;
8983 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8984 TypeSourceInfo *TSInfo = nullptr;
8985 if (FromVar->getTypeSourceInfo()) {
8986 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8987 if (!TSInfo)
8988 return StmtError();
8989 }
8990
8991 QualType T;
8992 if (TSInfo)
8993 T = TSInfo->getType();
8994 else {
8995 T = getDerived().TransformType(FromVar->getType());
8996 if (T.isNull())
8997 return StmtError();
8998 }
8999
9000 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
9001 if (!Var)
9002 return StmtError();
9003 }
9004
9005 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
9006 if (Body.isInvalid())
9007 return StmtError();
9008
9009 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9010 S->getRParenLoc(),
9011 Var, Body.get());
9012}
9013
9014template<typename Derived>
9015StmtResult
9016TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9017 // Transform the body.
9018 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9019 if (Body.isInvalid())
9020 return StmtError();
9021
9022 // If nothing changed, just retain this statement.
9023 if (!getDerived().AlwaysRebuild() &&
9024 Body.get() == S->getFinallyBody())
9025 return S;
9026
9027 // Build a new statement.
9028 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9029 Body.get());
9030}
9031
9032template<typename Derived>
9033StmtResult
9034TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9035 ExprResult Operand;
9036 if (S->getThrowExpr()) {
9037 Operand = getDerived().TransformExpr(S->getThrowExpr());
9038 if (Operand.isInvalid())
9039 return StmtError();
9040 }
9041
9042 if (!getDerived().AlwaysRebuild() &&
9043 Operand.get() == S->getThrowExpr())
9044 return S;
9045
9046 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9047}
9048
9049template<typename Derived>
9050StmtResult
9051TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9052 ObjCAtSynchronizedStmt *S) {
9053 // Transform the object we are locking.
9054 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9055 if (Object.isInvalid())
9056 return StmtError();
9057 Object =
9058 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9059 Object.get());
9060 if (Object.isInvalid())
9061 return StmtError();
9062
9063 // Transform the body.
9064 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9065 if (Body.isInvalid())
9066 return StmtError();
9067
9068 // If nothing change, just retain the current statement.
9069 if (!getDerived().AlwaysRebuild() &&
9070 Object.get() == S->getSynchExpr() &&
9071 Body.get() == S->getSynchBody())
9072 return S;
9073
9074 // Build a new statement.
9075 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9076 Object.get(), Body.get());
9077}
9078
9079template<typename Derived>
9080StmtResult
9081TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9082 ObjCAutoreleasePoolStmt *S) {
9083 // Transform the body.
9084 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9085 if (Body.isInvalid())
9086 return StmtError();
9087
9088 // If nothing changed, just retain this statement.
9089 if (!getDerived().AlwaysRebuild() &&
9090 Body.get() == S->getSubStmt())
9091 return S;
9092
9093 // Build a new statement.
9094 return getDerived().RebuildObjCAutoreleasePoolStmt(
9095 S->getAtLoc(), Body.get());
9096}
9097
9098template<typename Derived>
9099StmtResult
9100TreeTransform<Derived>::TransformObjCForCollectionStmt(
9101 ObjCForCollectionStmt *S) {
9102 // Transform the element statement.
9103 StmtResult Element = getDerived().TransformStmt(
9104 S->getElement(), StmtDiscardKind::NotDiscarded);
9105 if (Element.isInvalid())
9106 return StmtError();
9107
9108 // Transform the collection expression.
9109 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9110 if (Collection.isInvalid())
9111 return StmtError();
9112
9113 // Transform the body.
9114 StmtResult Body = getDerived().TransformStmt(S->getBody());
9115 if (Body.isInvalid())
9116 return StmtError();
9117
9118 // If nothing changed, just retain this statement.
9119 if (!getDerived().AlwaysRebuild() &&
9120 Element.get() == S->getElement() &&
9121 Collection.get() == S->getCollection() &&
9122 Body.get() == S->getBody())
9123 return S;
9124
9125 // Build a new statement.
9126 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9127 Element.get(),
9128 Collection.get(),
9129 S->getRParenLoc(),
9130 Body.get());
9131}
9132
9133template <typename Derived>
9134StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9135 // Transform the exception declaration, if any.
9136 VarDecl *Var = nullptr;
9137 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9138 TypeSourceInfo *T =
9139 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9140 if (!T)
9141 return StmtError();
9142
9143 Var = getDerived().RebuildExceptionDecl(
9144 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9145 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9146 if (!Var || Var->isInvalidDecl())
9147 return StmtError();
9148 }
9149
9150 // Transform the actual exception handler.
9151 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9152 if (Handler.isInvalid())
9153 return StmtError();
9154
9155 if (!getDerived().AlwaysRebuild() && !Var &&
9156 Handler.get() == S->getHandlerBlock())
9157 return S;
9158
9159 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9160}
9161
9162template <typename Derived>
9163StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9164 // Transform the try block itself.
9165 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9166 if (TryBlock.isInvalid())
9167 return StmtError();
9168
9169 // Transform the handlers.
9170 bool HandlerChanged = false;
9171 SmallVector<Stmt *, 8> Handlers;
9172 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9173 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9174 if (Handler.isInvalid())
9175 return StmtError();
9176
9177 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9178 Handlers.push_back(Elt: Handler.getAs<Stmt>());
9179 }
9180
9181 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9182
9183 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9184 !HandlerChanged)
9185 return S;
9186
9187 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9188 Handlers);
9189}
9190
9191template<typename Derived>
9192StmtResult
9193TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9194 EnterExpressionEvaluationContext ForRangeInitContext(
9195 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9196 /*LambdaContextDecl=*/nullptr,
9197 Sema::ExpressionEvaluationContextRecord::EK_Other,
9198 getSema().getLangOpts().CPlusPlus23);
9199
9200 // P2718R0 - Lifetime extension in range-based for loops.
9201 if (getSema().getLangOpts().CPlusPlus23) {
9202 auto &LastRecord = getSema().currentEvaluationContext();
9203 LastRecord.InLifetimeExtendingContext = true;
9204 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9205 }
9206 StmtResult Init =
9207 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9208 if (Init.isInvalid())
9209 return StmtError();
9210
9211 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9212 if (Range.isInvalid())
9213 return StmtError();
9214
9215 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9216 assert(getSema().getLangOpts().CPlusPlus23 ||
9217 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9218 auto ForRangeLifetimeExtendTemps =
9219 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9220
9221 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9222 if (Begin.isInvalid())
9223 return StmtError();
9224 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9225 if (End.isInvalid())
9226 return StmtError();
9227
9228 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9229 if (Cond.isInvalid())
9230 return StmtError();
9231 if (Cond.get())
9232 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9233 if (Cond.isInvalid())
9234 return StmtError();
9235 if (Cond.get())
9236 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9237
9238 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9239 if (Inc.isInvalid())
9240 return StmtError();
9241 if (Inc.get())
9242 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9243
9244 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9245 if (LoopVar.isInvalid())
9246 return StmtError();
9247
9248 StmtResult NewStmt = S;
9249 if (getDerived().AlwaysRebuild() ||
9250 Init.get() != S->getInit() ||
9251 Range.get() != S->getRangeStmt() ||
9252 Begin.get() != S->getBeginStmt() ||
9253 End.get() != S->getEndStmt() ||
9254 Cond.get() != S->getCond() ||
9255 Inc.get() != S->getInc() ||
9256 LoopVar.get() != S->getLoopVarStmt()) {
9257 NewStmt = getDerived().RebuildCXXForRangeStmt(
9258 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9259 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9260 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9261 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9262 // Might not have attached any initializer to the loop variable.
9263 getSema().ActOnInitializerError(
9264 cast<DeclStmt>(Val: LoopVar.get())->getSingleDecl());
9265 return StmtError();
9266 }
9267 }
9268
9269 // OpenACC Restricts a while-loop inside of certain construct/clause
9270 // combinations, so diagnose that here in OpenACC mode.
9271 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9272 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9273
9274 StmtResult Body = getDerived().TransformStmt(S->getBody());
9275 if (Body.isInvalid())
9276 return StmtError();
9277
9278 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9279
9280 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9281 // it now so we have a new statement to attach the body to.
9282 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9283 NewStmt = getDerived().RebuildCXXForRangeStmt(
9284 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9285 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9286 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9287 if (NewStmt.isInvalid())
9288 return StmtError();
9289 }
9290
9291 if (NewStmt.get() == S)
9292 return S;
9293
9294 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9295}
9296
9297template<typename Derived>
9298StmtResult
9299TreeTransform<Derived>::TransformMSDependentExistsStmt(
9300 MSDependentExistsStmt *S) {
9301 // Transform the nested-name-specifier, if any.
9302 NestedNameSpecifierLoc QualifierLoc;
9303 if (S->getQualifierLoc()) {
9304 QualifierLoc
9305 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9306 if (!QualifierLoc)
9307 return StmtError();
9308 }
9309
9310 // Transform the declaration name.
9311 DeclarationNameInfo NameInfo = S->getNameInfo();
9312 if (NameInfo.getName()) {
9313 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9314 if (!NameInfo.getName())
9315 return StmtError();
9316 }
9317
9318 // Check whether anything changed.
9319 if (!getDerived().AlwaysRebuild() &&
9320 QualifierLoc == S->getQualifierLoc() &&
9321 NameInfo.getName() == S->getNameInfo().getName())
9322 return S;
9323
9324 // Determine whether this name exists, if we can.
9325 CXXScopeSpec SS;
9326 SS.Adopt(Other: QualifierLoc);
9327 bool Dependent = false;
9328 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9329 case IfExistsResult::Exists:
9330 if (S->isIfExists())
9331 break;
9332
9333 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9334
9335 case IfExistsResult::DoesNotExist:
9336 if (S->isIfNotExists())
9337 break;
9338
9339 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9340
9341 case IfExistsResult::Dependent:
9342 Dependent = true;
9343 break;
9344
9345 case IfExistsResult::Error:
9346 return StmtError();
9347 }
9348
9349 // We need to continue with the instantiation, so do so now.
9350 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9351 if (SubStmt.isInvalid())
9352 return StmtError();
9353
9354 // If we have resolved the name, just transform to the substatement.
9355 if (!Dependent)
9356 return SubStmt;
9357
9358 // The name is still dependent, so build a dependent expression again.
9359 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9360 S->isIfExists(),
9361 QualifierLoc,
9362 NameInfo,
9363 SubStmt.get());
9364}
9365
9366template<typename Derived>
9367ExprResult
9368TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9369 NestedNameSpecifierLoc QualifierLoc;
9370 if (E->getQualifierLoc()) {
9371 QualifierLoc
9372 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9373 if (!QualifierLoc)
9374 return ExprError();
9375 }
9376
9377 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9378 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9379 if (!PD)
9380 return ExprError();
9381
9382 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9383 if (Base.isInvalid())
9384 return ExprError();
9385
9386 return new (SemaRef.getASTContext())
9387 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9388 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9389 QualifierLoc, E->getMemberLoc());
9390}
9391
9392template <typename Derived>
9393ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9394 MSPropertySubscriptExpr *E) {
9395 auto BaseRes = getDerived().TransformExpr(E->getBase());
9396 if (BaseRes.isInvalid())
9397 return ExprError();
9398 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9399 if (IdxRes.isInvalid())
9400 return ExprError();
9401
9402 if (!getDerived().AlwaysRebuild() &&
9403 BaseRes.get() == E->getBase() &&
9404 IdxRes.get() == E->getIdx())
9405 return E;
9406
9407 return getDerived().RebuildArraySubscriptExpr(
9408 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9409}
9410
9411template <typename Derived>
9412StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9413 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9414 if (TryBlock.isInvalid())
9415 return StmtError();
9416
9417 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9418 if (Handler.isInvalid())
9419 return StmtError();
9420
9421 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9422 Handler.get() == S->getHandler())
9423 return S;
9424
9425 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9426 TryBlock.get(), Handler.get());
9427}
9428
9429template <typename Derived>
9430StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9431 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9432 if (Block.isInvalid())
9433 return StmtError();
9434
9435 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9436}
9437
9438template <typename Derived>
9439StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9440 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9441 if (FilterExpr.isInvalid())
9442 return StmtError();
9443
9444 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9445 if (Block.isInvalid())
9446 return StmtError();
9447
9448 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9449 Block.get());
9450}
9451
9452template <typename Derived>
9453StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9454 if (isa<SEHFinallyStmt>(Val: Handler))
9455 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Val: Handler));
9456 else
9457 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Val: Handler));
9458}
9459
9460template<typename Derived>
9461StmtResult
9462TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9463 return S;
9464}
9465
9466//===----------------------------------------------------------------------===//
9467// OpenMP directive transformation
9468//===----------------------------------------------------------------------===//
9469
9470template <typename Derived>
9471StmtResult
9472TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9473 // OMPCanonicalLoops are eliminated during transformation, since they will be
9474 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9475 // after transformation.
9476 return getDerived().TransformStmt(L->getLoopStmt());
9477}
9478
9479template <typename Derived>
9480StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9481 OMPExecutableDirective *D) {
9482
9483 // Transform the clauses
9484 llvm::SmallVector<OMPClause *, 16> TClauses;
9485 ArrayRef<OMPClause *> Clauses = D->clauses();
9486 TClauses.reserve(N: Clauses.size());
9487 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9488 I != E; ++I) {
9489 if (*I) {
9490 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9491 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9492 getDerived().getSema().OpenMP().EndOpenMPClause();
9493 if (Clause)
9494 TClauses.push_back(Elt: Clause);
9495 } else {
9496 TClauses.push_back(Elt: nullptr);
9497 }
9498 }
9499 StmtResult AssociatedStmt;
9500 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9501 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9502 D->getDirectiveKind(),
9503 /*CurScope=*/nullptr);
9504 StmtResult Body;
9505 {
9506 Sema::CompoundScopeRAII CompoundScope(getSema());
9507 Stmt *CS;
9508 if (D->getDirectiveKind() == OMPD_atomic ||
9509 D->getDirectiveKind() == OMPD_critical ||
9510 D->getDirectiveKind() == OMPD_section ||
9511 D->getDirectiveKind() == OMPD_master)
9512 CS = D->getAssociatedStmt();
9513 else
9514 CS = D->getRawStmt();
9515 Body = getDerived().TransformStmt(CS);
9516 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9517 getSema().getLangOpts().OpenMPIRBuilder)
9518 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9519 }
9520 AssociatedStmt =
9521 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9522 if (AssociatedStmt.isInvalid()) {
9523 return StmtError();
9524 }
9525 }
9526 if (TClauses.size() != Clauses.size()) {
9527 return StmtError();
9528 }
9529
9530 // Transform directive name for 'omp critical' directive.
9531 DeclarationNameInfo DirName;
9532 if (D->getDirectiveKind() == OMPD_critical) {
9533 DirName = cast<OMPCriticalDirective>(Val: D)->getDirectiveName();
9534 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9535 }
9536 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9537 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9538 CancelRegion = cast<OMPCancellationPointDirective>(Val: D)->getCancelRegion();
9539 } else if (D->getDirectiveKind() == OMPD_cancel) {
9540 CancelRegion = cast<OMPCancelDirective>(Val: D)->getCancelRegion();
9541 }
9542
9543 return getDerived().RebuildOMPExecutableDirective(
9544 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9545 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9546}
9547
9548/// This is mostly the same as above, but allows 'informational' class
9549/// directives when rebuilding the stmt. It still takes an
9550/// OMPExecutableDirective-type argument because we're reusing that as the
9551/// superclass for the 'assume' directive at present, instead of defining a
9552/// mostly-identical OMPInformationalDirective parent class.
9553template <typename Derived>
9554StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9555 OMPExecutableDirective *D) {
9556
9557 // Transform the clauses
9558 llvm::SmallVector<OMPClause *, 16> TClauses;
9559 ArrayRef<OMPClause *> Clauses = D->clauses();
9560 TClauses.reserve(N: Clauses.size());
9561 for (OMPClause *C : Clauses) {
9562 if (C) {
9563 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9564 OMPClause *Clause = getDerived().TransformOMPClause(C);
9565 getDerived().getSema().OpenMP().EndOpenMPClause();
9566 if (Clause)
9567 TClauses.push_back(Elt: Clause);
9568 } else {
9569 TClauses.push_back(Elt: nullptr);
9570 }
9571 }
9572 StmtResult AssociatedStmt;
9573 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9574 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9575 D->getDirectiveKind(),
9576 /*CurScope=*/nullptr);
9577 StmtResult Body;
9578 {
9579 Sema::CompoundScopeRAII CompoundScope(getSema());
9580 assert(D->getDirectiveKind() == OMPD_assume &&
9581 "Unexpected informational directive");
9582 Stmt *CS = D->getAssociatedStmt();
9583 Body = getDerived().TransformStmt(CS);
9584 }
9585 AssociatedStmt =
9586 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9587 if (AssociatedStmt.isInvalid())
9588 return StmtError();
9589 }
9590 if (TClauses.size() != Clauses.size())
9591 return StmtError();
9592
9593 DeclarationNameInfo DirName;
9594
9595 return getDerived().RebuildOMPInformationalDirective(
9596 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9597 D->getBeginLoc(), D->getEndLoc());
9598}
9599
9600template <typename Derived>
9601StmtResult
9602TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9603 // TODO: Fix This
9604 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9605 SemaRef.Diag(Loc: D->getBeginLoc(), DiagID: diag::err_omp_instantiation_not_supported)
9606 << getOpenMPDirectiveName(D: D->getDirectiveKind(), Ver: OMPVersion);
9607 return StmtError();
9608}
9609
9610template <typename Derived>
9611StmtResult
9612TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9613 DeclarationNameInfo DirName;
9614 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9615 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9616 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9617 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9618 return Res;
9619}
9620
9621template <typename Derived>
9622StmtResult
9623TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9624 DeclarationNameInfo DirName;
9625 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9626 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9627 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9628 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9629 return Res;
9630}
9631
9632template <typename Derived>
9633StmtResult
9634TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9635 DeclarationNameInfo DirName;
9636 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9637 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9638 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9639 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9640 return Res;
9641}
9642
9643template <typename Derived>
9644StmtResult
9645TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9646 DeclarationNameInfo DirName;
9647 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9648 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9649 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9650 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9651 return Res;
9652}
9653
9654template <typename Derived>
9655StmtResult
9656TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9657 DeclarationNameInfo DirName;
9658 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9659 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9660 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9661 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9662 return Res;
9663}
9664
9665template <typename Derived>
9666StmtResult
9667TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9668 DeclarationNameInfo DirName;
9669 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9670 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9671 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9672 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9673 return Res;
9674}
9675
9676template <typename Derived>
9677StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9678 OMPInterchangeDirective *D) {
9679 DeclarationNameInfo DirName;
9680 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9681 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9682 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9683 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9684 return Res;
9685}
9686
9687template <typename Derived>
9688StmtResult
9689TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9690 DeclarationNameInfo DirName;
9691 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9692 OMPD_for, DirName, nullptr, D->getBeginLoc());
9693 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9694 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9695 return Res;
9696}
9697
9698template <typename Derived>
9699StmtResult
9700TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9701 DeclarationNameInfo DirName;
9702 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9703 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9704 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9705 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9706 return Res;
9707}
9708
9709template <typename Derived>
9710StmtResult
9711TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9712 DeclarationNameInfo DirName;
9713 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9714 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9715 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9716 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9717 return Res;
9718}
9719
9720template <typename Derived>
9721StmtResult
9722TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9723 DeclarationNameInfo DirName;
9724 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9725 OMPD_section, DirName, nullptr, D->getBeginLoc());
9726 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9727 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9728 return Res;
9729}
9730
9731template <typename Derived>
9732StmtResult
9733TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9734 DeclarationNameInfo DirName;
9735 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9736 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9737 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9738 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9739 return Res;
9740}
9741
9742template <typename Derived>
9743StmtResult
9744TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9745 DeclarationNameInfo DirName;
9746 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9747 OMPD_single, DirName, nullptr, D->getBeginLoc());
9748 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9749 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9750 return Res;
9751}
9752
9753template <typename Derived>
9754StmtResult
9755TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9756 DeclarationNameInfo DirName;
9757 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9758 OMPD_master, DirName, nullptr, D->getBeginLoc());
9759 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9760 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9761 return Res;
9762}
9763
9764template <typename Derived>
9765StmtResult
9766TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9767 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9768 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9769 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9770 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9771 return Res;
9772}
9773
9774template <typename Derived>
9775StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9776 OMPParallelForDirective *D) {
9777 DeclarationNameInfo DirName;
9778 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9779 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9780 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9781 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9782 return Res;
9783}
9784
9785template <typename Derived>
9786StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9787 OMPParallelForSimdDirective *D) {
9788 DeclarationNameInfo DirName;
9789 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9790 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9791 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9792 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9793 return Res;
9794}
9795
9796template <typename Derived>
9797StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9798 OMPParallelMasterDirective *D) {
9799 DeclarationNameInfo DirName;
9800 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9801 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9802 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9803 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9804 return Res;
9805}
9806
9807template <typename Derived>
9808StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9809 OMPParallelMaskedDirective *D) {
9810 DeclarationNameInfo DirName;
9811 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9812 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9813 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9814 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9815 return Res;
9816}
9817
9818template <typename Derived>
9819StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9820 OMPParallelSectionsDirective *D) {
9821 DeclarationNameInfo DirName;
9822 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9823 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9824 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9825 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9826 return Res;
9827}
9828
9829template <typename Derived>
9830StmtResult
9831TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9832 DeclarationNameInfo DirName;
9833 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9834 OMPD_task, DirName, nullptr, D->getBeginLoc());
9835 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9836 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9837 return Res;
9838}
9839
9840template <typename Derived>
9841StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9842 OMPTaskyieldDirective *D) {
9843 DeclarationNameInfo DirName;
9844 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9845 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9846 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9847 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9848 return Res;
9849}
9850
9851template <typename Derived>
9852StmtResult
9853TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9854 DeclarationNameInfo DirName;
9855 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9856 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9857 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9858 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9859 return Res;
9860}
9861
9862template <typename Derived>
9863StmtResult
9864TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9865 DeclarationNameInfo DirName;
9866 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9867 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9868 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9869 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9870 return Res;
9871}
9872
9873template <typename Derived>
9874StmtResult
9875TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9876 DeclarationNameInfo DirName;
9877 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9878 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9879 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9880 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9881 return Res;
9882}
9883
9884template <typename Derived>
9885StmtResult
9886TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9887 DeclarationNameInfo DirName;
9888 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9889 OMPD_error, DirName, nullptr, D->getBeginLoc());
9890 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9891 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9892 return Res;
9893}
9894
9895template <typename Derived>
9896StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9897 OMPTaskgroupDirective *D) {
9898 DeclarationNameInfo DirName;
9899 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9900 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9901 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9902 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9903 return Res;
9904}
9905
9906template <typename Derived>
9907StmtResult
9908TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9909 DeclarationNameInfo DirName;
9910 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9911 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9912 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9913 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9914 return Res;
9915}
9916
9917template <typename Derived>
9918StmtResult
9919TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9920 DeclarationNameInfo DirName;
9921 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9922 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9923 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9924 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9925 return Res;
9926}
9927
9928template <typename Derived>
9929StmtResult
9930TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9931 DeclarationNameInfo DirName;
9932 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9933 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9934 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9935 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9936 return Res;
9937}
9938
9939template <typename Derived>
9940StmtResult
9941TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9942 DeclarationNameInfo DirName;
9943 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9944 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9945 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9946 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9947 return Res;
9948}
9949
9950template <typename Derived>
9951StmtResult
9952TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9953 DeclarationNameInfo DirName;
9954 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9955 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9956 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9957 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9958 return Res;
9959}
9960
9961template <typename Derived>
9962StmtResult
9963TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9964 DeclarationNameInfo DirName;
9965 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9966 OMPD_target, DirName, nullptr, D->getBeginLoc());
9967 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9968 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9969 return Res;
9970}
9971
9972template <typename Derived>
9973StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9974 OMPTargetDataDirective *D) {
9975 DeclarationNameInfo DirName;
9976 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9977 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9978 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9979 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9980 return Res;
9981}
9982
9983template <typename Derived>
9984StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9985 OMPTargetEnterDataDirective *D) {
9986 DeclarationNameInfo DirName;
9987 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9988 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9989 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9990 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9991 return Res;
9992}
9993
9994template <typename Derived>
9995StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9996 OMPTargetExitDataDirective *D) {
9997 DeclarationNameInfo DirName;
9998 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9999 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
10000 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10001 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10002 return Res;
10003}
10004
10005template <typename Derived>
10006StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
10007 OMPTargetParallelDirective *D) {
10008 DeclarationNameInfo DirName;
10009 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10010 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10011 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10012 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10013 return Res;
10014}
10015
10016template <typename Derived>
10017StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10018 OMPTargetParallelForDirective *D) {
10019 DeclarationNameInfo DirName;
10020 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10021 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10022 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10023 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10024 return Res;
10025}
10026
10027template <typename Derived>
10028StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10029 OMPTargetUpdateDirective *D) {
10030 DeclarationNameInfo DirName;
10031 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10032 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10033 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10034 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10035 return Res;
10036}
10037
10038template <typename Derived>
10039StmtResult
10040TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10041 DeclarationNameInfo DirName;
10042 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10043 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10044 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10045 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10046 return Res;
10047}
10048
10049template <typename Derived>
10050StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10051 OMPCancellationPointDirective *D) {
10052 DeclarationNameInfo DirName;
10053 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10054 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10055 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10056 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10057 return Res;
10058}
10059
10060template <typename Derived>
10061StmtResult
10062TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10063 DeclarationNameInfo DirName;
10064 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10065 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10066 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10067 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10068 return Res;
10069}
10070
10071template <typename Derived>
10072StmtResult
10073TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10074 DeclarationNameInfo DirName;
10075 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10076 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10077 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10078 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10079 return Res;
10080}
10081
10082template <typename Derived>
10083StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10084 OMPTaskLoopSimdDirective *D) {
10085 DeclarationNameInfo DirName;
10086 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10087 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10088 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10089 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10090 return Res;
10091}
10092
10093template <typename Derived>
10094StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10095 OMPMasterTaskLoopDirective *D) {
10096 DeclarationNameInfo DirName;
10097 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10098 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10099 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10100 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10101 return Res;
10102}
10103
10104template <typename Derived>
10105StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10106 OMPMaskedTaskLoopDirective *D) {
10107 DeclarationNameInfo DirName;
10108 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10109 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10110 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10111 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10112 return Res;
10113}
10114
10115template <typename Derived>
10116StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10117 OMPMasterTaskLoopSimdDirective *D) {
10118 DeclarationNameInfo DirName;
10119 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10120 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10121 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10122 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10123 return Res;
10124}
10125
10126template <typename Derived>
10127StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10128 OMPMaskedTaskLoopSimdDirective *D) {
10129 DeclarationNameInfo DirName;
10130 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10131 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10132 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10133 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10134 return Res;
10135}
10136
10137template <typename Derived>
10138StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10139 OMPParallelMasterTaskLoopDirective *D) {
10140 DeclarationNameInfo DirName;
10141 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10142 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10143 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10144 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10145 return Res;
10146}
10147
10148template <typename Derived>
10149StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10150 OMPParallelMaskedTaskLoopDirective *D) {
10151 DeclarationNameInfo DirName;
10152 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10153 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10154 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10155 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10156 return Res;
10157}
10158
10159template <typename Derived>
10160StmtResult
10161TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10162 OMPParallelMasterTaskLoopSimdDirective *D) {
10163 DeclarationNameInfo DirName;
10164 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10165 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10166 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10167 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10168 return Res;
10169}
10170
10171template <typename Derived>
10172StmtResult
10173TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10174 OMPParallelMaskedTaskLoopSimdDirective *D) {
10175 DeclarationNameInfo DirName;
10176 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10177 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10178 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10179 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10180 return Res;
10181}
10182
10183template <typename Derived>
10184StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10185 OMPDistributeDirective *D) {
10186 DeclarationNameInfo DirName;
10187 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10188 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10189 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10190 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10191 return Res;
10192}
10193
10194template <typename Derived>
10195StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10196 OMPDistributeParallelForDirective *D) {
10197 DeclarationNameInfo DirName;
10198 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10199 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10200 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10201 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10202 return Res;
10203}
10204
10205template <typename Derived>
10206StmtResult
10207TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10208 OMPDistributeParallelForSimdDirective *D) {
10209 DeclarationNameInfo DirName;
10210 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10211 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10212 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10213 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10214 return Res;
10215}
10216
10217template <typename Derived>
10218StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10219 OMPDistributeSimdDirective *D) {
10220 DeclarationNameInfo DirName;
10221 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10222 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10223 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10224 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10225 return Res;
10226}
10227
10228template <typename Derived>
10229StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10230 OMPTargetParallelForSimdDirective *D) {
10231 DeclarationNameInfo DirName;
10232 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10233 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10234 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10235 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10236 return Res;
10237}
10238
10239template <typename Derived>
10240StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10241 OMPTargetSimdDirective *D) {
10242 DeclarationNameInfo DirName;
10243 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10244 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10245 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10246 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10247 return Res;
10248}
10249
10250template <typename Derived>
10251StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10252 OMPTeamsDistributeDirective *D) {
10253 DeclarationNameInfo DirName;
10254 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10255 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10256 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10257 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10258 return Res;
10259}
10260
10261template <typename Derived>
10262StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10263 OMPTeamsDistributeSimdDirective *D) {
10264 DeclarationNameInfo DirName;
10265 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10266 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10267 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10268 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10269 return Res;
10270}
10271
10272template <typename Derived>
10273StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10274 OMPTeamsDistributeParallelForSimdDirective *D) {
10275 DeclarationNameInfo DirName;
10276 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10277 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10278 D->getBeginLoc());
10279 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10280 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10281 return Res;
10282}
10283
10284template <typename Derived>
10285StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10286 OMPTeamsDistributeParallelForDirective *D) {
10287 DeclarationNameInfo DirName;
10288 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10289 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10290 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10291 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10292 return Res;
10293}
10294
10295template <typename Derived>
10296StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10297 OMPTargetTeamsDirective *D) {
10298 DeclarationNameInfo DirName;
10299 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10300 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10301 auto Res = getDerived().TransformOMPExecutableDirective(D);
10302 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10303 return Res;
10304}
10305
10306template <typename Derived>
10307StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10308 OMPTargetTeamsDistributeDirective *D) {
10309 DeclarationNameInfo DirName;
10310 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10311 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10312 auto Res = getDerived().TransformOMPExecutableDirective(D);
10313 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10314 return Res;
10315}
10316
10317template <typename Derived>
10318StmtResult
10319TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10320 OMPTargetTeamsDistributeParallelForDirective *D) {
10321 DeclarationNameInfo DirName;
10322 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10323 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10324 D->getBeginLoc());
10325 auto Res = getDerived().TransformOMPExecutableDirective(D);
10326 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10327 return Res;
10328}
10329
10330template <typename Derived>
10331StmtResult TreeTransform<Derived>::
10332 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10333 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10334 DeclarationNameInfo DirName;
10335 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10336 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10337 D->getBeginLoc());
10338 auto Res = getDerived().TransformOMPExecutableDirective(D);
10339 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10340 return Res;
10341}
10342
10343template <typename Derived>
10344StmtResult
10345TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10346 OMPTargetTeamsDistributeSimdDirective *D) {
10347 DeclarationNameInfo DirName;
10348 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10349 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10350 auto Res = getDerived().TransformOMPExecutableDirective(D);
10351 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10352 return Res;
10353}
10354
10355template <typename Derived>
10356StmtResult
10357TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10358 DeclarationNameInfo DirName;
10359 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10360 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10361 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10362 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10363 return Res;
10364}
10365
10366template <typename Derived>
10367StmtResult
10368TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10369 DeclarationNameInfo DirName;
10370 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10371 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10372 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10373 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10374 return Res;
10375}
10376
10377template <typename Derived>
10378StmtResult
10379TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10380 DeclarationNameInfo DirName;
10381 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10382 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10383 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10384 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10385 return Res;
10386}
10387
10388template <typename Derived>
10389StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10390 OMPGenericLoopDirective *D) {
10391 DeclarationNameInfo DirName;
10392 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10393 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10394 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10395 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10396 return Res;
10397}
10398
10399template <typename Derived>
10400StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10401 OMPTeamsGenericLoopDirective *D) {
10402 DeclarationNameInfo DirName;
10403 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10404 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10405 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10406 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10407 return Res;
10408}
10409
10410template <typename Derived>
10411StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10412 OMPTargetTeamsGenericLoopDirective *D) {
10413 DeclarationNameInfo DirName;
10414 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10415 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10416 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10417 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10418 return Res;
10419}
10420
10421template <typename Derived>
10422StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10423 OMPParallelGenericLoopDirective *D) {
10424 DeclarationNameInfo DirName;
10425 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10426 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10427 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10428 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10429 return Res;
10430}
10431
10432template <typename Derived>
10433StmtResult
10434TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10435 OMPTargetParallelGenericLoopDirective *D) {
10436 DeclarationNameInfo DirName;
10437 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10438 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10439 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10440 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10441 return Res;
10442}
10443
10444//===----------------------------------------------------------------------===//
10445// OpenMP clause transformation
10446//===----------------------------------------------------------------------===//
10447template <typename Derived>
10448OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10449 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10450 if (Cond.isInvalid())
10451 return nullptr;
10452 return getDerived().RebuildOMPIfClause(
10453 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10454 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10455}
10456
10457template <typename Derived>
10458OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10459 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10460 if (Cond.isInvalid())
10461 return nullptr;
10462 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10463 C->getLParenLoc(), C->getEndLoc());
10464}
10465
10466template <typename Derived>
10467OMPClause *
10468TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10469 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10470 if (NumThreads.isInvalid())
10471 return nullptr;
10472 return getDerived().RebuildOMPNumThreadsClause(
10473 C->getModifier(), NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(),
10474 C->getModifierLoc(), C->getEndLoc());
10475}
10476
10477template <typename Derived>
10478OMPClause *
10479TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10480 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10481 if (E.isInvalid())
10482 return nullptr;
10483 return getDerived().RebuildOMPSafelenClause(
10484 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10485}
10486
10487template <typename Derived>
10488OMPClause *
10489TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10490 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10491 if (E.isInvalid())
10492 return nullptr;
10493 return getDerived().RebuildOMPAllocatorClause(
10494 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10495}
10496
10497template <typename Derived>
10498OMPClause *
10499TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10500 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10501 if (E.isInvalid())
10502 return nullptr;
10503 return getDerived().RebuildOMPSimdlenClause(
10504 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10505}
10506
10507template <typename Derived>
10508OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10509 SmallVector<Expr *, 4> TransformedSizes;
10510 TransformedSizes.reserve(N: C->getNumSizes());
10511 bool Changed = false;
10512 for (Expr *E : C->getSizesRefs()) {
10513 if (!E) {
10514 TransformedSizes.push_back(Elt: nullptr);
10515 continue;
10516 }
10517
10518 ExprResult T = getDerived().TransformExpr(E);
10519 if (T.isInvalid())
10520 return nullptr;
10521 if (E != T.get())
10522 Changed = true;
10523 TransformedSizes.push_back(Elt: T.get());
10524 }
10525
10526 if (!Changed && !getDerived().AlwaysRebuild())
10527 return C;
10528 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10529 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10530}
10531
10532template <typename Derived>
10533OMPClause *
10534TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10535 SmallVector<Expr *> TransformedArgs;
10536 TransformedArgs.reserve(N: C->getNumLoops());
10537 bool Changed = false;
10538 for (Expr *E : C->getArgsRefs()) {
10539 if (!E) {
10540 TransformedArgs.push_back(Elt: nullptr);
10541 continue;
10542 }
10543
10544 ExprResult T = getDerived().TransformExpr(E);
10545 if (T.isInvalid())
10546 return nullptr;
10547 if (E != T.get())
10548 Changed = true;
10549 TransformedArgs.push_back(Elt: T.get());
10550 }
10551
10552 if (!Changed && !getDerived().AlwaysRebuild())
10553 return C;
10554 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10555 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10556}
10557
10558template <typename Derived>
10559OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10560 if (!getDerived().AlwaysRebuild())
10561 return C;
10562 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10563}
10564
10565template <typename Derived>
10566OMPClause *
10567TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10568 ExprResult T = getDerived().TransformExpr(C->getFactor());
10569 if (T.isInvalid())
10570 return nullptr;
10571 Expr *Factor = T.get();
10572 bool Changed = Factor != C->getFactor();
10573
10574 if (!Changed && !getDerived().AlwaysRebuild())
10575 return C;
10576 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10577 EndLoc: C->getEndLoc());
10578}
10579
10580template <typename Derived>
10581OMPClause *
10582TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10583 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10584 if (E.isInvalid())
10585 return nullptr;
10586 return getDerived().RebuildOMPCollapseClause(
10587 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10588}
10589
10590template <typename Derived>
10591OMPClause *
10592TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10593 return getDerived().RebuildOMPDefaultClause(
10594 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10595 C->getLParenLoc(), C->getEndLoc());
10596}
10597
10598template <typename Derived>
10599OMPClause *
10600TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10601 return getDerived().RebuildOMPProcBindClause(
10602 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10603 C->getLParenLoc(), C->getEndLoc());
10604}
10605
10606template <typename Derived>
10607OMPClause *
10608TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10609 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10610 if (E.isInvalid())
10611 return nullptr;
10612 return getDerived().RebuildOMPScheduleClause(
10613 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10614 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10615 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10616 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10617}
10618
10619template <typename Derived>
10620OMPClause *
10621TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10622 ExprResult E;
10623 if (auto *Num = C->getNumForLoops()) {
10624 E = getDerived().TransformExpr(Num);
10625 if (E.isInvalid())
10626 return nullptr;
10627 }
10628 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10629 C->getLParenLoc(), E.get());
10630}
10631
10632template <typename Derived>
10633OMPClause *
10634TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10635 ExprResult E;
10636 if (Expr *Evt = C->getEventHandler()) {
10637 E = getDerived().TransformExpr(Evt);
10638 if (E.isInvalid())
10639 return nullptr;
10640 }
10641 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10642 C->getLParenLoc(), C->getEndLoc());
10643}
10644
10645template <typename Derived>
10646OMPClause *
10647TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10648 // No need to rebuild this clause, no template-dependent parameters.
10649 return C;
10650}
10651
10652template <typename Derived>
10653OMPClause *
10654TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10655 // No need to rebuild this clause, no template-dependent parameters.
10656 return C;
10657}
10658
10659template <typename Derived>
10660OMPClause *
10661TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10662 // No need to rebuild this clause, no template-dependent parameters.
10663 return C;
10664}
10665
10666template <typename Derived>
10667OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10668 // No need to rebuild this clause, no template-dependent parameters.
10669 return C;
10670}
10671
10672template <typename Derived>
10673OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10674 // No need to rebuild this clause, no template-dependent parameters.
10675 return C;
10676}
10677
10678template <typename Derived>
10679OMPClause *
10680TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10681 // No need to rebuild this clause, no template-dependent parameters.
10682 return C;
10683}
10684
10685template <typename Derived>
10686OMPClause *
10687TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10688 // No need to rebuild this clause, no template-dependent parameters.
10689 return C;
10690}
10691
10692template <typename Derived>
10693OMPClause *
10694TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10695 // No need to rebuild this clause, no template-dependent parameters.
10696 return C;
10697}
10698
10699template <typename Derived>
10700OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10701 // No need to rebuild this clause, no template-dependent parameters.
10702 return C;
10703}
10704
10705template <typename Derived>
10706OMPClause *
10707TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10708 return C;
10709}
10710
10711template <typename Derived>
10712OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10713 ExprResult E = getDerived().TransformExpr(C->getExpr());
10714 if (E.isInvalid())
10715 return nullptr;
10716 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10717 C->getLParenLoc(), C->getEndLoc());
10718}
10719
10720template <typename Derived>
10721OMPClause *
10722TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10723 return C;
10724}
10725
10726template <typename Derived>
10727OMPClause *
10728TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10729 return C;
10730}
10731template <typename Derived>
10732OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10733 OMPNoOpenMPRoutinesClause *C) {
10734 return C;
10735}
10736template <typename Derived>
10737OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10738 OMPNoOpenMPConstructsClause *C) {
10739 return C;
10740}
10741template <typename Derived>
10742OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10743 OMPNoParallelismClause *C) {
10744 return C;
10745}
10746
10747template <typename Derived>
10748OMPClause *
10749TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10750 // No need to rebuild this clause, no template-dependent parameters.
10751 return C;
10752}
10753
10754template <typename Derived>
10755OMPClause *
10756TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10757 // No need to rebuild this clause, no template-dependent parameters.
10758 return C;
10759}
10760
10761template <typename Derived>
10762OMPClause *
10763TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10764 // No need to rebuild this clause, no template-dependent parameters.
10765 return C;
10766}
10767
10768template <typename Derived>
10769OMPClause *
10770TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10771 // No need to rebuild this clause, no template-dependent parameters.
10772 return C;
10773}
10774
10775template <typename Derived>
10776OMPClause *
10777TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10778 // No need to rebuild this clause, no template-dependent parameters.
10779 return C;
10780}
10781
10782template <typename Derived>
10783OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10784 // No need to rebuild this clause, no template-dependent parameters.
10785 return C;
10786}
10787
10788template <typename Derived>
10789OMPClause *
10790TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10791 // No need to rebuild this clause, no template-dependent parameters.
10792 return C;
10793}
10794
10795template <typename Derived>
10796OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10797 // No need to rebuild this clause, no template-dependent parameters.
10798 return C;
10799}
10800
10801template <typename Derived>
10802OMPClause *
10803TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10804 // No need to rebuild this clause, no template-dependent parameters.
10805 return C;
10806}
10807
10808template <typename Derived>
10809OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10810 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10811 if (IVR.isInvalid())
10812 return nullptr;
10813
10814 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10815 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10816 for (Expr *E : llvm::drop_begin(RangeOrContainer: C->varlist())) {
10817 ExprResult ER = getDerived().TransformExpr(cast<Expr>(Val: E));
10818 if (ER.isInvalid())
10819 return nullptr;
10820 InteropInfo.PreferTypes.push_back(Elt: ER.get());
10821 }
10822 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10823 C->getBeginLoc(), C->getLParenLoc(),
10824 C->getVarLoc(), C->getEndLoc());
10825}
10826
10827template <typename Derived>
10828OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10829 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10830 if (ER.isInvalid())
10831 return nullptr;
10832 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10833 C->getLParenLoc(), C->getVarLoc(),
10834 C->getEndLoc());
10835}
10836
10837template <typename Derived>
10838OMPClause *
10839TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10840 ExprResult ER;
10841 if (Expr *IV = C->getInteropVar()) {
10842 ER = getDerived().TransformExpr(IV);
10843 if (ER.isInvalid())
10844 return nullptr;
10845 }
10846 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10847 C->getLParenLoc(), C->getVarLoc(),
10848 C->getEndLoc());
10849}
10850
10851template <typename Derived>
10852OMPClause *
10853TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10854 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10855 if (Cond.isInvalid())
10856 return nullptr;
10857 return getDerived().RebuildOMPNovariantsClause(
10858 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10859}
10860
10861template <typename Derived>
10862OMPClause *
10863TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10864 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10865 if (Cond.isInvalid())
10866 return nullptr;
10867 return getDerived().RebuildOMPNocontextClause(
10868 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10869}
10870
10871template <typename Derived>
10872OMPClause *
10873TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10874 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10875 if (ThreadID.isInvalid())
10876 return nullptr;
10877 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10878 C->getLParenLoc(), C->getEndLoc());
10879}
10880
10881template <typename Derived>
10882OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10883 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10884 if (E.isInvalid())
10885 return nullptr;
10886 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10887 C->getLParenLoc(), C->getEndLoc());
10888}
10889
10890template <typename Derived>
10891OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10892 OMPUnifiedAddressClause *C) {
10893 llvm_unreachable("unified_address clause cannot appear in dependent context");
10894}
10895
10896template <typename Derived>
10897OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10898 OMPUnifiedSharedMemoryClause *C) {
10899 llvm_unreachable(
10900 "unified_shared_memory clause cannot appear in dependent context");
10901}
10902
10903template <typename Derived>
10904OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10905 OMPReverseOffloadClause *C) {
10906 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10907}
10908
10909template <typename Derived>
10910OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10911 OMPDynamicAllocatorsClause *C) {
10912 llvm_unreachable(
10913 "dynamic_allocators clause cannot appear in dependent context");
10914}
10915
10916template <typename Derived>
10917OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10918 OMPAtomicDefaultMemOrderClause *C) {
10919 llvm_unreachable(
10920 "atomic_default_mem_order clause cannot appear in dependent context");
10921}
10922
10923template <typename Derived>
10924OMPClause *
10925TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
10926 llvm_unreachable("self_maps clause cannot appear in dependent context");
10927}
10928
10929template <typename Derived>
10930OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10931 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10932 C->getBeginLoc(), C->getLParenLoc(),
10933 C->getEndLoc());
10934}
10935
10936template <typename Derived>
10937OMPClause *
10938TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10939 return getDerived().RebuildOMPSeverityClause(
10940 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10941 C->getLParenLoc(), C->getEndLoc());
10942}
10943
10944template <typename Derived>
10945OMPClause *
10946TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10947 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10948 if (E.isInvalid())
10949 return nullptr;
10950 return getDerived().RebuildOMPMessageClause(
10951 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10952 C->getEndLoc());
10953}
10954
10955template <typename Derived>
10956OMPClause *
10957TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10958 llvm::SmallVector<Expr *, 16> Vars;
10959 Vars.reserve(N: C->varlist_size());
10960 for (auto *VE : C->varlist()) {
10961 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10962 if (EVar.isInvalid())
10963 return nullptr;
10964 Vars.push_back(Elt: EVar.get());
10965 }
10966 return getDerived().RebuildOMPPrivateClause(
10967 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10968}
10969
10970template <typename Derived>
10971OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10972 OMPFirstprivateClause *C) {
10973 llvm::SmallVector<Expr *, 16> Vars;
10974 Vars.reserve(N: C->varlist_size());
10975 for (auto *VE : C->varlist()) {
10976 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10977 if (EVar.isInvalid())
10978 return nullptr;
10979 Vars.push_back(Elt: EVar.get());
10980 }
10981 return getDerived().RebuildOMPFirstprivateClause(
10982 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10983}
10984
10985template <typename Derived>
10986OMPClause *
10987TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10988 llvm::SmallVector<Expr *, 16> Vars;
10989 Vars.reserve(N: C->varlist_size());
10990 for (auto *VE : C->varlist()) {
10991 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
10992 if (EVar.isInvalid())
10993 return nullptr;
10994 Vars.push_back(Elt: EVar.get());
10995 }
10996 return getDerived().RebuildOMPLastprivateClause(
10997 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10998 C->getLParenLoc(), C->getEndLoc());
10999}
11000
11001template <typename Derived>
11002OMPClause *
11003TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
11004 llvm::SmallVector<Expr *, 16> Vars;
11005 Vars.reserve(N: C->varlist_size());
11006 for (auto *VE : C->varlist()) {
11007 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11008 if (EVar.isInvalid())
11009 return nullptr;
11010 Vars.push_back(Elt: EVar.get());
11011 }
11012 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11013 C->getLParenLoc(), C->getEndLoc());
11014}
11015
11016template <typename Derived>
11017OMPClause *
11018TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11019 llvm::SmallVector<Expr *, 16> Vars;
11020 Vars.reserve(N: C->varlist_size());
11021 for (auto *VE : C->varlist()) {
11022 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11023 if (EVar.isInvalid())
11024 return nullptr;
11025 Vars.push_back(Elt: EVar.get());
11026 }
11027 CXXScopeSpec ReductionIdScopeSpec;
11028 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11029
11030 DeclarationNameInfo NameInfo = C->getNameInfo();
11031 if (NameInfo.getName()) {
11032 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11033 if (!NameInfo.getName())
11034 return nullptr;
11035 }
11036 // Build a list of all UDR decls with the same names ranged by the Scopes.
11037 // The Scope boundary is a duplication of the previous decl.
11038 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11039 for (auto *E : C->reduction_ops()) {
11040 // Transform all the decls.
11041 if (E) {
11042 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11043 UnresolvedSet<8> Decls;
11044 for (auto *D : ULE->decls()) {
11045 NamedDecl *InstD =
11046 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11047 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11048 }
11049 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11050 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11051 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11052 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11053 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11054 } else
11055 UnresolvedReductions.push_back(Elt: nullptr);
11056 }
11057 return getDerived().RebuildOMPReductionClause(
11058 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11059 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11060 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11061}
11062
11063template <typename Derived>
11064OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11065 OMPTaskReductionClause *C) {
11066 llvm::SmallVector<Expr *, 16> Vars;
11067 Vars.reserve(N: C->varlist_size());
11068 for (auto *VE : C->varlist()) {
11069 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11070 if (EVar.isInvalid())
11071 return nullptr;
11072 Vars.push_back(Elt: EVar.get());
11073 }
11074 CXXScopeSpec ReductionIdScopeSpec;
11075 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11076
11077 DeclarationNameInfo NameInfo = C->getNameInfo();
11078 if (NameInfo.getName()) {
11079 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11080 if (!NameInfo.getName())
11081 return nullptr;
11082 }
11083 // Build a list of all UDR decls with the same names ranged by the Scopes.
11084 // The Scope boundary is a duplication of the previous decl.
11085 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11086 for (auto *E : C->reduction_ops()) {
11087 // Transform all the decls.
11088 if (E) {
11089 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11090 UnresolvedSet<8> Decls;
11091 for (auto *D : ULE->decls()) {
11092 NamedDecl *InstD =
11093 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11094 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11095 }
11096 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11097 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11098 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11099 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11100 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11101 } else
11102 UnresolvedReductions.push_back(Elt: nullptr);
11103 }
11104 return getDerived().RebuildOMPTaskReductionClause(
11105 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11106 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11107}
11108
11109template <typename Derived>
11110OMPClause *
11111TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11112 llvm::SmallVector<Expr *, 16> Vars;
11113 Vars.reserve(N: C->varlist_size());
11114 for (auto *VE : C->varlist()) {
11115 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11116 if (EVar.isInvalid())
11117 return nullptr;
11118 Vars.push_back(Elt: EVar.get());
11119 }
11120 CXXScopeSpec ReductionIdScopeSpec;
11121 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11122
11123 DeclarationNameInfo NameInfo = C->getNameInfo();
11124 if (NameInfo.getName()) {
11125 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11126 if (!NameInfo.getName())
11127 return nullptr;
11128 }
11129 // Build a list of all UDR decls with the same names ranged by the Scopes.
11130 // The Scope boundary is a duplication of the previous decl.
11131 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11132 for (auto *E : C->reduction_ops()) {
11133 // Transform all the decls.
11134 if (E) {
11135 auto *ULE = cast<UnresolvedLookupExpr>(Val: E);
11136 UnresolvedSet<8> Decls;
11137 for (auto *D : ULE->decls()) {
11138 NamedDecl *InstD =
11139 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11140 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11141 }
11142 UnresolvedReductions.push_back(Elt: UnresolvedLookupExpr::Create(
11143 Context: SemaRef.Context, /*NamingClass=*/NamingClass: nullptr,
11144 QualifierLoc: ReductionIdScopeSpec.getWithLocInContext(Context&: SemaRef.Context), NameInfo,
11145 /*ADL=*/RequiresADL: true, Begin: Decls.begin(), End: Decls.end(),
11146 /*KnownDependent=*/KnownDependent: false, /*KnownInstantiationDependent=*/KnownInstantiationDependent: false));
11147 } else
11148 UnresolvedReductions.push_back(Elt: nullptr);
11149 }
11150 return getDerived().RebuildOMPInReductionClause(
11151 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11152 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11153}
11154
11155template <typename Derived>
11156OMPClause *
11157TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11158 llvm::SmallVector<Expr *, 16> Vars;
11159 Vars.reserve(N: C->varlist_size());
11160 for (auto *VE : C->varlist()) {
11161 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11162 if (EVar.isInvalid())
11163 return nullptr;
11164 Vars.push_back(Elt: EVar.get());
11165 }
11166 ExprResult Step = getDerived().TransformExpr(C->getStep());
11167 if (Step.isInvalid())
11168 return nullptr;
11169 return getDerived().RebuildOMPLinearClause(
11170 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11171 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11172 C->getEndLoc());
11173}
11174
11175template <typename Derived>
11176OMPClause *
11177TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11178 llvm::SmallVector<Expr *, 16> Vars;
11179 Vars.reserve(N: C->varlist_size());
11180 for (auto *VE : C->varlist()) {
11181 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11182 if (EVar.isInvalid())
11183 return nullptr;
11184 Vars.push_back(Elt: EVar.get());
11185 }
11186 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11187 if (Alignment.isInvalid())
11188 return nullptr;
11189 return getDerived().RebuildOMPAlignedClause(
11190 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11191 C->getColonLoc(), C->getEndLoc());
11192}
11193
11194template <typename Derived>
11195OMPClause *
11196TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11197 llvm::SmallVector<Expr *, 16> Vars;
11198 Vars.reserve(N: C->varlist_size());
11199 for (auto *VE : C->varlist()) {
11200 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11201 if (EVar.isInvalid())
11202 return nullptr;
11203 Vars.push_back(Elt: EVar.get());
11204 }
11205 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11206 C->getLParenLoc(), C->getEndLoc());
11207}
11208
11209template <typename Derived>
11210OMPClause *
11211TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11212 llvm::SmallVector<Expr *, 16> Vars;
11213 Vars.reserve(N: C->varlist_size());
11214 for (auto *VE : C->varlist()) {
11215 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11216 if (EVar.isInvalid())
11217 return nullptr;
11218 Vars.push_back(Elt: EVar.get());
11219 }
11220 return getDerived().RebuildOMPCopyprivateClause(
11221 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11222}
11223
11224template <typename Derived>
11225OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11226 llvm::SmallVector<Expr *, 16> Vars;
11227 Vars.reserve(N: C->varlist_size());
11228 for (auto *VE : C->varlist()) {
11229 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11230 if (EVar.isInvalid())
11231 return nullptr;
11232 Vars.push_back(Elt: EVar.get());
11233 }
11234 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11235 C->getLParenLoc(), C->getEndLoc());
11236}
11237
11238template <typename Derived>
11239OMPClause *
11240TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11241 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11242 if (E.isInvalid())
11243 return nullptr;
11244 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11245 C->getLParenLoc(), C->getEndLoc());
11246}
11247
11248template <typename Derived>
11249OMPClause *
11250TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11251 llvm::SmallVector<Expr *, 16> Vars;
11252 Expr *DepModifier = C->getModifier();
11253 if (DepModifier) {
11254 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11255 if (DepModRes.isInvalid())
11256 return nullptr;
11257 DepModifier = DepModRes.get();
11258 }
11259 Vars.reserve(N: C->varlist_size());
11260 for (auto *VE : C->varlist()) {
11261 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11262 if (EVar.isInvalid())
11263 return nullptr;
11264 Vars.push_back(Elt: EVar.get());
11265 }
11266 return getDerived().RebuildOMPDependClause(
11267 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11268 C->getOmpAllMemoryLoc()},
11269 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11270}
11271
11272template <typename Derived>
11273OMPClause *
11274TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11275 ExprResult E = getDerived().TransformExpr(C->getDevice());
11276 if (E.isInvalid())
11277 return nullptr;
11278 return getDerived().RebuildOMPDeviceClause(
11279 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11280 C->getModifierLoc(), C->getEndLoc());
11281}
11282
11283template <typename Derived, class T>
11284bool transformOMPMappableExprListClause(
11285 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11286 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11287 DeclarationNameInfo &MapperIdInfo,
11288 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11289 // Transform expressions in the list.
11290 Vars.reserve(N: C->varlist_size());
11291 for (auto *VE : C->varlist()) {
11292 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11293 if (EVar.isInvalid())
11294 return true;
11295 Vars.push_back(Elt: EVar.get());
11296 }
11297 // Transform mapper scope specifier and identifier.
11298 NestedNameSpecifierLoc QualifierLoc;
11299 if (C->getMapperQualifierLoc()) {
11300 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11301 C->getMapperQualifierLoc());
11302 if (!QualifierLoc)
11303 return true;
11304 }
11305 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11306 MapperIdInfo = C->getMapperIdInfo();
11307 if (MapperIdInfo.getName()) {
11308 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11309 if (!MapperIdInfo.getName())
11310 return true;
11311 }
11312 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11313 // the previous user-defined mapper lookup in dependent environment.
11314 for (auto *E : C->mapperlists()) {
11315 // Transform all the decls.
11316 if (E) {
11317 auto *ULE = cast<UnresolvedLookupExpr>(E);
11318 UnresolvedSet<8> Decls;
11319 for (auto *D : ULE->decls()) {
11320 NamedDecl *InstD =
11321 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11322 Decls.addDecl(D: InstD, AS: InstD->getAccess());
11323 }
11324 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11325 TT.getSema().Context, /*NamingClass=*/nullptr,
11326 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11327 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11328 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11329 } else {
11330 UnresolvedMappers.push_back(Elt: nullptr);
11331 }
11332 }
11333 return false;
11334}
11335
11336template <typename Derived>
11337OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11338 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11339 llvm::SmallVector<Expr *, 16> Vars;
11340 Expr *IteratorModifier = C->getIteratorModifier();
11341 if (IteratorModifier) {
11342 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11343 if (MapModRes.isInvalid())
11344 return nullptr;
11345 IteratorModifier = MapModRes.get();
11346 }
11347 CXXScopeSpec MapperIdScopeSpec;
11348 DeclarationNameInfo MapperIdInfo;
11349 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11350 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11351 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11352 return nullptr;
11353 return getDerived().RebuildOMPMapClause(
11354 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11355 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11356 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11357}
11358
11359template <typename Derived>
11360OMPClause *
11361TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11362 Expr *Allocator = C->getAllocator();
11363 if (Allocator) {
11364 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11365 if (AllocatorRes.isInvalid())
11366 return nullptr;
11367 Allocator = AllocatorRes.get();
11368 }
11369 Expr *Alignment = C->getAlignment();
11370 if (Alignment) {
11371 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11372 if (AlignmentRes.isInvalid())
11373 return nullptr;
11374 Alignment = AlignmentRes.get();
11375 }
11376 llvm::SmallVector<Expr *, 16> Vars;
11377 Vars.reserve(N: C->varlist_size());
11378 for (auto *VE : C->varlist()) {
11379 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11380 if (EVar.isInvalid())
11381 return nullptr;
11382 Vars.push_back(Elt: EVar.get());
11383 }
11384 return getDerived().RebuildOMPAllocateClause(
11385 Allocator, Alignment, C->getFirstAllocateModifier(),
11386 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11387 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11388 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11389}
11390
11391template <typename Derived>
11392OMPClause *
11393TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11394 llvm::SmallVector<Expr *, 3> Vars;
11395 Vars.reserve(N: C->varlist_size());
11396 for (auto *VE : C->varlist()) {
11397 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11398 if (EVar.isInvalid())
11399 return nullptr;
11400 Vars.push_back(Elt: EVar.get());
11401 }
11402 return getDerived().RebuildOMPNumTeamsClause(
11403 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11404}
11405
11406template <typename Derived>
11407OMPClause *
11408TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11409 llvm::SmallVector<Expr *, 3> Vars;
11410 Vars.reserve(N: C->varlist_size());
11411 for (auto *VE : C->varlist()) {
11412 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11413 if (EVar.isInvalid())
11414 return nullptr;
11415 Vars.push_back(Elt: EVar.get());
11416 }
11417 return getDerived().RebuildOMPThreadLimitClause(
11418 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11419}
11420
11421template <typename Derived>
11422OMPClause *
11423TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11424 ExprResult E = getDerived().TransformExpr(C->getPriority());
11425 if (E.isInvalid())
11426 return nullptr;
11427 return getDerived().RebuildOMPPriorityClause(
11428 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11429}
11430
11431template <typename Derived>
11432OMPClause *
11433TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11434 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11435 if (E.isInvalid())
11436 return nullptr;
11437 return getDerived().RebuildOMPGrainsizeClause(
11438 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11439 C->getModifierLoc(), C->getEndLoc());
11440}
11441
11442template <typename Derived>
11443OMPClause *
11444TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11445 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11446 if (E.isInvalid())
11447 return nullptr;
11448 return getDerived().RebuildOMPNumTasksClause(
11449 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11450 C->getModifierLoc(), C->getEndLoc());
11451}
11452
11453template <typename Derived>
11454OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11455 ExprResult E = getDerived().TransformExpr(C->getHint());
11456 if (E.isInvalid())
11457 return nullptr;
11458 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11459 C->getLParenLoc(), C->getEndLoc());
11460}
11461
11462template <typename Derived>
11463OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11464 OMPDistScheduleClause *C) {
11465 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11466 if (E.isInvalid())
11467 return nullptr;
11468 return getDerived().RebuildOMPDistScheduleClause(
11469 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11470 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11471}
11472
11473template <typename Derived>
11474OMPClause *
11475TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11476 // Rebuild Defaultmap Clause since we need to invoke the checking of
11477 // defaultmap(none:variable-category) after template initialization.
11478 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11479 C->getDefaultmapKind(),
11480 C->getBeginLoc(),
11481 C->getLParenLoc(),
11482 C->getDefaultmapModifierLoc(),
11483 C->getDefaultmapKindLoc(),
11484 C->getEndLoc());
11485}
11486
11487template <typename Derived>
11488OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11489 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11490 llvm::SmallVector<Expr *, 16> Vars;
11491 CXXScopeSpec MapperIdScopeSpec;
11492 DeclarationNameInfo MapperIdInfo;
11493 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11494 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11495 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11496 return nullptr;
11497 return getDerived().RebuildOMPToClause(
11498 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11499 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11500}
11501
11502template <typename Derived>
11503OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11504 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11505 llvm::SmallVector<Expr *, 16> Vars;
11506 CXXScopeSpec MapperIdScopeSpec;
11507 DeclarationNameInfo MapperIdInfo;
11508 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11509 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11510 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11511 return nullptr;
11512 return getDerived().RebuildOMPFromClause(
11513 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11514 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11515}
11516
11517template <typename Derived>
11518OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11519 OMPUseDevicePtrClause *C) {
11520 llvm::SmallVector<Expr *, 16> Vars;
11521 Vars.reserve(N: C->varlist_size());
11522 for (auto *VE : C->varlist()) {
11523 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11524 if (EVar.isInvalid())
11525 return nullptr;
11526 Vars.push_back(Elt: EVar.get());
11527 }
11528 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11529 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11530}
11531
11532template <typename Derived>
11533OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11534 OMPUseDeviceAddrClause *C) {
11535 llvm::SmallVector<Expr *, 16> Vars;
11536 Vars.reserve(N: C->varlist_size());
11537 for (auto *VE : C->varlist()) {
11538 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11539 if (EVar.isInvalid())
11540 return nullptr;
11541 Vars.push_back(Elt: EVar.get());
11542 }
11543 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11544 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11545}
11546
11547template <typename Derived>
11548OMPClause *
11549TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11550 llvm::SmallVector<Expr *, 16> Vars;
11551 Vars.reserve(N: C->varlist_size());
11552 for (auto *VE : C->varlist()) {
11553 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11554 if (EVar.isInvalid())
11555 return nullptr;
11556 Vars.push_back(Elt: EVar.get());
11557 }
11558 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11559 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11560}
11561
11562template <typename Derived>
11563OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11564 OMPHasDeviceAddrClause *C) {
11565 llvm::SmallVector<Expr *, 16> Vars;
11566 Vars.reserve(N: C->varlist_size());
11567 for (auto *VE : C->varlist()) {
11568 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11569 if (EVar.isInvalid())
11570 return nullptr;
11571 Vars.push_back(Elt: EVar.get());
11572 }
11573 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11574 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11575}
11576
11577template <typename Derived>
11578OMPClause *
11579TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11580 llvm::SmallVector<Expr *, 16> Vars;
11581 Vars.reserve(N: C->varlist_size());
11582 for (auto *VE : C->varlist()) {
11583 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11584 if (EVar.isInvalid())
11585 return nullptr;
11586 Vars.push_back(Elt: EVar.get());
11587 }
11588 return getDerived().RebuildOMPNontemporalClause(
11589 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11590}
11591
11592template <typename Derived>
11593OMPClause *
11594TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11595 llvm::SmallVector<Expr *, 16> Vars;
11596 Vars.reserve(N: C->varlist_size());
11597 for (auto *VE : C->varlist()) {
11598 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11599 if (EVar.isInvalid())
11600 return nullptr;
11601 Vars.push_back(Elt: EVar.get());
11602 }
11603 return getDerived().RebuildOMPInclusiveClause(
11604 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11605}
11606
11607template <typename Derived>
11608OMPClause *
11609TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11610 llvm::SmallVector<Expr *, 16> Vars;
11611 Vars.reserve(N: C->varlist_size());
11612 for (auto *VE : C->varlist()) {
11613 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11614 if (EVar.isInvalid())
11615 return nullptr;
11616 Vars.push_back(Elt: EVar.get());
11617 }
11618 return getDerived().RebuildOMPExclusiveClause(
11619 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11620}
11621
11622template <typename Derived>
11623OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11624 OMPUsesAllocatorsClause *C) {
11625 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11626 Data.reserve(N: C->getNumberOfAllocators());
11627 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11628 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11629 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11630 if (Allocator.isInvalid())
11631 continue;
11632 ExprResult AllocatorTraits;
11633 if (Expr *AT = D.AllocatorTraits) {
11634 AllocatorTraits = getDerived().TransformExpr(AT);
11635 if (AllocatorTraits.isInvalid())
11636 continue;
11637 }
11638 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11639 NewD.Allocator = Allocator.get();
11640 NewD.AllocatorTraits = AllocatorTraits.get();
11641 NewD.LParenLoc = D.LParenLoc;
11642 NewD.RParenLoc = D.RParenLoc;
11643 }
11644 return getDerived().RebuildOMPUsesAllocatorsClause(
11645 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11646}
11647
11648template <typename Derived>
11649OMPClause *
11650TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11651 SmallVector<Expr *, 4> Locators;
11652 Locators.reserve(N: C->varlist_size());
11653 ExprResult ModifierRes;
11654 if (Expr *Modifier = C->getModifier()) {
11655 ModifierRes = getDerived().TransformExpr(Modifier);
11656 if (ModifierRes.isInvalid())
11657 return nullptr;
11658 }
11659 for (Expr *E : C->varlist()) {
11660 ExprResult Locator = getDerived().TransformExpr(E);
11661 if (Locator.isInvalid())
11662 continue;
11663 Locators.push_back(Elt: Locator.get());
11664 }
11665 return getDerived().RebuildOMPAffinityClause(
11666 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11667 ModifierRes.get(), Locators);
11668}
11669
11670template <typename Derived>
11671OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11672 return getDerived().RebuildOMPOrderClause(
11673 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11674 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11675}
11676
11677template <typename Derived>
11678OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11679 return getDerived().RebuildOMPBindClause(
11680 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11681 C->getLParenLoc(), C->getEndLoc());
11682}
11683
11684template <typename Derived>
11685OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11686 OMPXDynCGroupMemClause *C) {
11687 ExprResult Size = getDerived().TransformExpr(C->getSize());
11688 if (Size.isInvalid())
11689 return nullptr;
11690 return getDerived().RebuildOMPXDynCGroupMemClause(
11691 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11692}
11693
11694template <typename Derived>
11695OMPClause *
11696TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11697 llvm::SmallVector<Expr *, 16> Vars;
11698 Vars.reserve(N: C->varlist_size());
11699 for (auto *VE : C->varlist()) {
11700 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(Val: VE));
11701 if (EVar.isInvalid())
11702 return nullptr;
11703 Vars.push_back(Elt: EVar.get());
11704 }
11705 return getDerived().RebuildOMPDoacrossClause(
11706 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11707 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11708}
11709
11710template <typename Derived>
11711OMPClause *
11712TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11713 SmallVector<const Attr *> NewAttrs;
11714 for (auto *A : C->getAttrs())
11715 NewAttrs.push_back(Elt: getDerived().TransformAttr(A));
11716 return getDerived().RebuildOMPXAttributeClause(
11717 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11718}
11719
11720template <typename Derived>
11721OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11722 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11723}
11724
11725//===----------------------------------------------------------------------===//
11726// OpenACC transformation
11727//===----------------------------------------------------------------------===//
11728namespace {
11729template <typename Derived>
11730class OpenACCClauseTransform final
11731 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11732 TreeTransform<Derived> &Self;
11733 ArrayRef<const OpenACCClause *> ExistingClauses;
11734 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11735 OpenACCClause *NewClause = nullptr;
11736
11737 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11738 llvm::SmallVector<Expr *> InstantiatedVarList;
11739 for (Expr *CurVar : VarList) {
11740 ExprResult Res = Self.TransformExpr(CurVar);
11741
11742 if (!Res.isUsable())
11743 continue;
11744
11745 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11746 ParsedClause.getClauseKind(),
11747 Res.get());
11748
11749 if (Res.isUsable())
11750 InstantiatedVarList.push_back(Elt: Res.get());
11751 }
11752
11753 return InstantiatedVarList;
11754 }
11755
11756public:
11757 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11758 ArrayRef<const OpenACCClause *> ExistingClauses,
11759 SemaOpenACC::OpenACCParsedClause &PC)
11760 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11761
11762 OpenACCClause *CreatedClause() const { return NewClause; }
11763
11764#define VISIT_CLAUSE(CLAUSE_NAME) \
11765 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11766#include "clang/Basic/OpenACCClauses.def"
11767};
11768
11769template <typename Derived>
11770void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11771 const OpenACCDefaultClause &C) {
11772 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11773
11774 NewClause = OpenACCDefaultClause::Create(
11775 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11776 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11777 EndLoc: ParsedClause.getEndLoc());
11778}
11779
11780template <typename Derived>
11781void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11782 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11783 assert(Cond && "If constructed with invalid Condition");
11784 Sema::ConditionResult Res = Self.TransformCondition(
11785 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11786
11787 if (Res.isInvalid() || !Res.get().second)
11788 return;
11789
11790 ParsedClause.setConditionDetails(Res.get().second);
11791
11792 NewClause = OpenACCIfClause::Create(
11793 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11794 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11795 EndLoc: ParsedClause.getEndLoc());
11796}
11797
11798template <typename Derived>
11799void OpenACCClauseTransform<Derived>::VisitSelfClause(
11800 const OpenACCSelfClause &C) {
11801
11802 // If this is an 'update' 'self' clause, this is actually a var list instead.
11803 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11804 llvm::SmallVector<Expr *> InstantiatedVarList;
11805 for (Expr *CurVar : C.getVarList()) {
11806 ExprResult Res = Self.TransformExpr(CurVar);
11807
11808 if (!Res.isUsable())
11809 continue;
11810
11811 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11812 ParsedClause.getClauseKind(),
11813 Res.get());
11814
11815 if (Res.isUsable())
11816 InstantiatedVarList.push_back(Elt: Res.get());
11817 }
11818
11819 ParsedClause.setVarListDetails(VarList: InstantiatedVarList,
11820 ModKind: OpenACCModifierKind::Invalid);
11821
11822 NewClause = OpenACCSelfClause::Create(
11823 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11824 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11825 ParsedClause.getEndLoc());
11826 } else {
11827
11828 if (C.hasConditionExpr()) {
11829 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11830 Sema::ConditionResult Res =
11831 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11832 Sema::ConditionKind::Boolean);
11833
11834 if (Res.isInvalid() || !Res.get().second)
11835 return;
11836
11837 ParsedClause.setConditionDetails(Res.get().second);
11838 }
11839
11840 NewClause = OpenACCSelfClause::Create(
11841 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11842 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11843 ParsedClause.getEndLoc());
11844 }
11845}
11846
11847template <typename Derived>
11848void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11849 const OpenACCNumGangsClause &C) {
11850 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11851
11852 for (Expr *CurIntExpr : C.getIntExprs()) {
11853 ExprResult Res = Self.TransformExpr(CurIntExpr);
11854
11855 if (!Res.isUsable())
11856 return;
11857
11858 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11859 C.getClauseKind(),
11860 C.getBeginLoc(), Res.get());
11861 if (!Res.isUsable())
11862 return;
11863
11864 InstantiatedIntExprs.push_back(Elt: Res.get());
11865 }
11866
11867 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11868 NewClause = OpenACCNumGangsClause::Create(
11869 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11870 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
11871 EndLoc: ParsedClause.getEndLoc());
11872}
11873
11874template <typename Derived>
11875void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11876 const OpenACCPrivateClause &C) {
11877 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11878 OpenACCModifierKind::Invalid);
11879
11880 NewClause = OpenACCPrivateClause::Create(
11881 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11882 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11883 EndLoc: ParsedClause.getEndLoc());
11884}
11885
11886template <typename Derived>
11887void OpenACCClauseTransform<Derived>::VisitHostClause(
11888 const OpenACCHostClause &C) {
11889 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11890 OpenACCModifierKind::Invalid);
11891
11892 NewClause = OpenACCHostClause::Create(
11893 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11894 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11895 EndLoc: ParsedClause.getEndLoc());
11896}
11897
11898template <typename Derived>
11899void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11900 const OpenACCDeviceClause &C) {
11901 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11902 OpenACCModifierKind::Invalid);
11903
11904 NewClause = OpenACCDeviceClause::Create(
11905 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11906 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11907 EndLoc: ParsedClause.getEndLoc());
11908}
11909
11910template <typename Derived>
11911void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11912 const OpenACCFirstPrivateClause &C) {
11913 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11914 OpenACCModifierKind::Invalid);
11915
11916 NewClause = OpenACCFirstPrivateClause::Create(
11917 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11918 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11919 EndLoc: ParsedClause.getEndLoc());
11920}
11921
11922template <typename Derived>
11923void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11924 const OpenACCNoCreateClause &C) {
11925 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11926 OpenACCModifierKind::Invalid);
11927
11928 NewClause = OpenACCNoCreateClause::Create(
11929 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11930 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11931 EndLoc: ParsedClause.getEndLoc());
11932}
11933
11934template <typename Derived>
11935void OpenACCClauseTransform<Derived>::VisitPresentClause(
11936 const OpenACCPresentClause &C) {
11937 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11938 OpenACCModifierKind::Invalid);
11939
11940 NewClause = OpenACCPresentClause::Create(
11941 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11942 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11943 EndLoc: ParsedClause.getEndLoc());
11944}
11945
11946template <typename Derived>
11947void OpenACCClauseTransform<Derived>::VisitCopyClause(
11948 const OpenACCCopyClause &C) {
11949 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11950 C.getModifierList());
11951
11952 NewClause = OpenACCCopyClause::Create(
11953 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11954 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11955 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11956 EndLoc: ParsedClause.getEndLoc());
11957}
11958
11959template <typename Derived>
11960void OpenACCClauseTransform<Derived>::VisitLinkClause(
11961 const OpenACCLinkClause &C) {
11962 llvm_unreachable("link clause not valid unless a decl transform");
11963}
11964
11965template <typename Derived>
11966void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
11967 const OpenACCDeviceResidentClause &C) {
11968 llvm_unreachable("device_resident clause not valid unless a decl transform");
11969}
11970template <typename Derived>
11971void OpenACCClauseTransform<Derived>::VisitNoHostClause(
11972 const OpenACCNoHostClause &C) {
11973 llvm_unreachable("nohost clause not valid unless a decl transform");
11974}
11975template <typename Derived>
11976void OpenACCClauseTransform<Derived>::VisitBindClause(
11977 const OpenACCBindClause &C) {
11978 llvm_unreachable("bind clause not valid unless a decl transform");
11979}
11980
11981template <typename Derived>
11982void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11983 const OpenACCCopyInClause &C) {
11984 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11985 C.getModifierList());
11986
11987 NewClause = OpenACCCopyInClause::Create(
11988 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11989 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11990 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11991 EndLoc: ParsedClause.getEndLoc());
11992}
11993
11994template <typename Derived>
11995void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11996 const OpenACCCopyOutClause &C) {
11997 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
11998 C.getModifierList());
11999
12000 NewClause = OpenACCCopyOutClause::Create(
12001 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12002 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12003 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12004 EndLoc: ParsedClause.getEndLoc());
12005}
12006
12007template <typename Derived>
12008void OpenACCClauseTransform<Derived>::VisitCreateClause(
12009 const OpenACCCreateClause &C) {
12010 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12011 C.getModifierList());
12012
12013 NewClause = OpenACCCreateClause::Create(
12014 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12015 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12016 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12017 EndLoc: ParsedClause.getEndLoc());
12018}
12019template <typename Derived>
12020void OpenACCClauseTransform<Derived>::VisitAttachClause(
12021 const OpenACCAttachClause &C) {
12022 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12023
12024 // Ensure each var is a pointer type.
12025 llvm::erase_if(VarList, [&](Expr *E) {
12026 return Self.getSema().OpenACC().CheckVarIsPointerType(
12027 OpenACCClauseKind::Attach, E);
12028 });
12029
12030 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12031 NewClause = OpenACCAttachClause::Create(
12032 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12033 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12034 EndLoc: ParsedClause.getEndLoc());
12035}
12036
12037template <typename Derived>
12038void OpenACCClauseTransform<Derived>::VisitDetachClause(
12039 const OpenACCDetachClause &C) {
12040 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12041
12042 // Ensure each var is a pointer type.
12043 llvm::erase_if(VarList, [&](Expr *E) {
12044 return Self.getSema().OpenACC().CheckVarIsPointerType(
12045 OpenACCClauseKind::Detach, E);
12046 });
12047
12048 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12049 NewClause = OpenACCDetachClause::Create(
12050 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12051 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12052 EndLoc: ParsedClause.getEndLoc());
12053}
12054
12055template <typename Derived>
12056void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12057 const OpenACCDeleteClause &C) {
12058 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12059 OpenACCModifierKind::Invalid);
12060 NewClause = OpenACCDeleteClause::Create(
12061 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12062 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12063 EndLoc: ParsedClause.getEndLoc());
12064}
12065
12066template <typename Derived>
12067void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12068 const OpenACCUseDeviceClause &C) {
12069 ParsedClause.setVarListDetails(VisitVarList(VarList: C.getVarList()),
12070 OpenACCModifierKind::Invalid);
12071 NewClause = OpenACCUseDeviceClause::Create(
12072 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12073 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12074 EndLoc: ParsedClause.getEndLoc());
12075}
12076
12077template <typename Derived>
12078void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12079 const OpenACCDevicePtrClause &C) {
12080 llvm::SmallVector<Expr *> VarList = VisitVarList(VarList: C.getVarList());
12081
12082 // Ensure each var is a pointer type.
12083 llvm::erase_if(VarList, [&](Expr *E) {
12084 return Self.getSema().OpenACC().CheckVarIsPointerType(
12085 OpenACCClauseKind::DevicePtr, E);
12086 });
12087
12088 ParsedClause.setVarListDetails(VarList, ModKind: OpenACCModifierKind::Invalid);
12089 NewClause = OpenACCDevicePtrClause::Create(
12090 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12091 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12092 EndLoc: ParsedClause.getEndLoc());
12093}
12094
12095template <typename Derived>
12096void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12097 const OpenACCNumWorkersClause &C) {
12098 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12099 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12100
12101 ExprResult Res = Self.TransformExpr(IntExpr);
12102 if (!Res.isUsable())
12103 return;
12104
12105 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12106 C.getClauseKind(),
12107 C.getBeginLoc(), Res.get());
12108 if (!Res.isUsable())
12109 return;
12110
12111 ParsedClause.setIntExprDetails(Res.get());
12112 NewClause = OpenACCNumWorkersClause::Create(
12113 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12114 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12115 EndLoc: ParsedClause.getEndLoc());
12116}
12117
12118template <typename Derived>
12119void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12120 const OpenACCDeviceNumClause &C) {
12121 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12122 assert(IntExpr && "device_num clause constructed with invalid int expr");
12123
12124 ExprResult Res = Self.TransformExpr(IntExpr);
12125 if (!Res.isUsable())
12126 return;
12127
12128 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12129 C.getClauseKind(),
12130 C.getBeginLoc(), Res.get());
12131 if (!Res.isUsable())
12132 return;
12133
12134 ParsedClause.setIntExprDetails(Res.get());
12135 NewClause = OpenACCDeviceNumClause::Create(
12136 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12137 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12138 EndLoc: ParsedClause.getEndLoc());
12139}
12140
12141template <typename Derived>
12142void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12143 const OpenACCDefaultAsyncClause &C) {
12144 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12145 assert(IntExpr && "default_async clause constructed with invalid int expr");
12146
12147 ExprResult Res = Self.TransformExpr(IntExpr);
12148 if (!Res.isUsable())
12149 return;
12150
12151 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12152 C.getClauseKind(),
12153 C.getBeginLoc(), Res.get());
12154 if (!Res.isUsable())
12155 return;
12156
12157 ParsedClause.setIntExprDetails(Res.get());
12158 NewClause = OpenACCDefaultAsyncClause::Create(
12159 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12160 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12161 EndLoc: ParsedClause.getEndLoc());
12162}
12163
12164template <typename Derived>
12165void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12166 const OpenACCVectorLengthClause &C) {
12167 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12168 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12169
12170 ExprResult Res = Self.TransformExpr(IntExpr);
12171 if (!Res.isUsable())
12172 return;
12173
12174 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12175 C.getClauseKind(),
12176 C.getBeginLoc(), Res.get());
12177 if (!Res.isUsable())
12178 return;
12179
12180 ParsedClause.setIntExprDetails(Res.get());
12181 NewClause = OpenACCVectorLengthClause::Create(
12182 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12183 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12184 EndLoc: ParsedClause.getEndLoc());
12185}
12186
12187template <typename Derived>
12188void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12189 const OpenACCAsyncClause &C) {
12190 if (C.hasIntExpr()) {
12191 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12192 if (!Res.isUsable())
12193 return;
12194
12195 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12196 C.getClauseKind(),
12197 C.getBeginLoc(), Res.get());
12198 if (!Res.isUsable())
12199 return;
12200 ParsedClause.setIntExprDetails(Res.get());
12201 }
12202
12203 NewClause = OpenACCAsyncClause::Create(
12204 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12205 LParenLoc: ParsedClause.getLParenLoc(),
12206 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12207 : nullptr,
12208 EndLoc: ParsedClause.getEndLoc());
12209}
12210
12211template <typename Derived>
12212void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12213 const OpenACCWorkerClause &C) {
12214 if (C.hasIntExpr()) {
12215 // restrictions on this expression are all "does it exist in certain
12216 // situations" that are not possible to be dependent, so the only check we
12217 // have is that it transforms, and is an int expression.
12218 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12219 if (!Res.isUsable())
12220 return;
12221
12222 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12223 C.getClauseKind(),
12224 C.getBeginLoc(), Res.get());
12225 if (!Res.isUsable())
12226 return;
12227 ParsedClause.setIntExprDetails(Res.get());
12228 }
12229
12230 NewClause = OpenACCWorkerClause::Create(
12231 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12232 LParenLoc: ParsedClause.getLParenLoc(),
12233 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12234 : nullptr,
12235 EndLoc: ParsedClause.getEndLoc());
12236}
12237
12238template <typename Derived>
12239void OpenACCClauseTransform<Derived>::VisitVectorClause(
12240 const OpenACCVectorClause &C) {
12241 if (C.hasIntExpr()) {
12242 // restrictions on this expression are all "does it exist in certain
12243 // situations" that are not possible to be dependent, so the only check we
12244 // have is that it transforms, and is an int expression.
12245 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12246 if (!Res.isUsable())
12247 return;
12248
12249 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12250 C.getClauseKind(),
12251 C.getBeginLoc(), Res.get());
12252 if (!Res.isUsable())
12253 return;
12254 ParsedClause.setIntExprDetails(Res.get());
12255 }
12256
12257 NewClause = OpenACCVectorClause::Create(
12258 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12259 LParenLoc: ParsedClause.getLParenLoc(),
12260 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12261 : nullptr,
12262 EndLoc: ParsedClause.getEndLoc());
12263}
12264
12265template <typename Derived>
12266void OpenACCClauseTransform<Derived>::VisitWaitClause(
12267 const OpenACCWaitClause &C) {
12268 if (C.hasExprs()) {
12269 Expr *DevNumExpr = nullptr;
12270 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12271
12272 // Instantiate devnum expr if it exists.
12273 if (C.getDevNumExpr()) {
12274 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12275 if (!Res.isUsable())
12276 return;
12277 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12278 C.getClauseKind(),
12279 C.getBeginLoc(), Res.get());
12280 if (!Res.isUsable())
12281 return;
12282
12283 DevNumExpr = Res.get();
12284 }
12285
12286 // Instantiate queue ids.
12287 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12288 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12289 if (!Res.isUsable())
12290 return;
12291 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12292 C.getClauseKind(),
12293 C.getBeginLoc(), Res.get());
12294 if (!Res.isUsable())
12295 return;
12296
12297 InstantiatedQueueIdExprs.push_back(Elt: Res.get());
12298 }
12299
12300 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12301 IntExprs: std::move(InstantiatedQueueIdExprs));
12302 }
12303
12304 NewClause = OpenACCWaitClause::Create(
12305 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12306 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12307 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12308 EndLoc: ParsedClause.getEndLoc());
12309}
12310
12311template <typename Derived>
12312void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12313 const OpenACCDeviceTypeClause &C) {
12314 // Nothing to transform here, just create a new version of 'C'.
12315 NewClause = OpenACCDeviceTypeClause::Create(
12316 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12317 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12318 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12319}
12320
12321template <typename Derived>
12322void OpenACCClauseTransform<Derived>::VisitAutoClause(
12323 const OpenACCAutoClause &C) {
12324 // Nothing to do, so just create a new node.
12325 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12326 BeginLoc: ParsedClause.getBeginLoc(),
12327 EndLoc: ParsedClause.getEndLoc());
12328}
12329
12330template <typename Derived>
12331void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12332 const OpenACCIndependentClause &C) {
12333 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12334 BeginLoc: ParsedClause.getBeginLoc(),
12335 EndLoc: ParsedClause.getEndLoc());
12336}
12337
12338template <typename Derived>
12339void OpenACCClauseTransform<Derived>::VisitSeqClause(
12340 const OpenACCSeqClause &C) {
12341 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12342 BeginLoc: ParsedClause.getBeginLoc(),
12343 EndLoc: ParsedClause.getEndLoc());
12344}
12345template <typename Derived>
12346void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12347 const OpenACCFinalizeClause &C) {
12348 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12349 BeginLoc: ParsedClause.getBeginLoc(),
12350 EndLoc: ParsedClause.getEndLoc());
12351}
12352
12353template <typename Derived>
12354void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12355 const OpenACCIfPresentClause &C) {
12356 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12357 BeginLoc: ParsedClause.getBeginLoc(),
12358 EndLoc: ParsedClause.getEndLoc());
12359}
12360
12361template <typename Derived>
12362void OpenACCClauseTransform<Derived>::VisitReductionClause(
12363 const OpenACCReductionClause &C) {
12364 SmallVector<Expr *> TransformedVars = VisitVarList(VarList: C.getVarList());
12365 SmallVector<Expr *> ValidVars;
12366
12367 for (Expr *Var : TransformedVars) {
12368 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12369 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12370 if (Res.isUsable())
12371 ValidVars.push_back(Elt: Res.get());
12372 }
12373
12374 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12375 ExistingClauses, ParsedClause.getDirectiveKind(),
12376 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12377 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12378}
12379
12380template <typename Derived>
12381void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12382 const OpenACCCollapseClause &C) {
12383 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12384 assert(LoopCount && "collapse clause constructed with invalid loop count");
12385
12386 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12387
12388 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12389 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12390 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12391
12392 NewLoopCount =
12393 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12394
12395 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12396 NewClause = OpenACCCollapseClause::Create(
12397 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12398 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12399 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12400}
12401
12402template <typename Derived>
12403void OpenACCClauseTransform<Derived>::VisitTileClause(
12404 const OpenACCTileClause &C) {
12405
12406 llvm::SmallVector<Expr *> TransformedExprs;
12407
12408 for (Expr *E : C.getSizeExprs()) {
12409 ExprResult NewSizeExpr = Self.TransformExpr(E);
12410
12411 if (!NewSizeExpr.isUsable())
12412 return;
12413
12414 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12415 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12416 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12417
12418 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12419
12420 if (!NewSizeExpr.isUsable())
12421 return;
12422 TransformedExprs.push_back(Elt: NewSizeExpr.get());
12423 }
12424
12425 ParsedClause.setIntExprDetails(TransformedExprs);
12426 NewClause = OpenACCTileClause::Create(
12427 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12428 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12429 EndLoc: ParsedClause.getEndLoc());
12430}
12431template <typename Derived>
12432void OpenACCClauseTransform<Derived>::VisitGangClause(
12433 const OpenACCGangClause &C) {
12434 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12435 llvm::SmallVector<Expr *> TransformedIntExprs;
12436
12437 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12438 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12439 if (!ER.isUsable())
12440 continue;
12441
12442 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12443 ParsedClause.getDirectiveKind(),
12444 C.getExpr(I).first, ER.get());
12445 if (!ER.isUsable())
12446 continue;
12447 TransformedGangKinds.push_back(Elt: C.getExpr(I).first);
12448 TransformedIntExprs.push_back(Elt: ER.get());
12449 }
12450
12451 NewClause = Self.getSema().OpenACC().CheckGangClause(
12452 ParsedClause.getDirectiveKind(), ExistingClauses,
12453 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12454 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12455}
12456} // namespace
12457template <typename Derived>
12458OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12459 ArrayRef<const OpenACCClause *> ExistingClauses,
12460 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12461
12462 SemaOpenACC::OpenACCParsedClause ParsedClause(
12463 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12464 ParsedClause.setEndLoc(OldClause->getEndLoc());
12465
12466 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(Val: OldClause))
12467 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12468
12469 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12470 ParsedClause};
12471 Transform.Visit(OldClause);
12472
12473 return Transform.CreatedClause();
12474}
12475
12476template <typename Derived>
12477llvm::SmallVector<OpenACCClause *>
12478TreeTransform<Derived>::TransformOpenACCClauseList(
12479 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12480 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12481 for (const auto *Clause : OldClauses) {
12482 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12483 TransformedClauses, DirKind, Clause))
12484 TransformedClauses.push_back(Elt: TransformedClause);
12485 }
12486 return TransformedClauses;
12487}
12488
12489template <typename Derived>
12490StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12491 OpenACCComputeConstruct *C) {
12492 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12493
12494 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12495 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12496 C->clauses());
12497
12498 if (getSema().OpenACC().ActOnStartStmtDirective(
12499 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12500 return StmtError();
12501
12502 // Transform Structured Block.
12503 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12504 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12505 C->clauses(), TransformedClauses);
12506 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12507 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12508 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12509
12510 return getDerived().RebuildOpenACCComputeConstruct(
12511 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12512 C->getEndLoc(), TransformedClauses, StrBlock);
12513}
12514
12515template <typename Derived>
12516StmtResult
12517TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12518
12519 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12520
12521 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12522 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12523 C->clauses());
12524
12525 if (getSema().OpenACC().ActOnStartStmtDirective(
12526 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12527 return StmtError();
12528
12529 // Transform Loop.
12530 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12531 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12532 C->clauses(), TransformedClauses);
12533 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12534 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12535 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12536
12537 return getDerived().RebuildOpenACCLoopConstruct(
12538 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12539 TransformedClauses, Loop);
12540}
12541
12542template <typename Derived>
12543StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12544 OpenACCCombinedConstruct *C) {
12545 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12546
12547 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12548 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12549 C->clauses());
12550
12551 if (getSema().OpenACC().ActOnStartStmtDirective(
12552 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12553 return StmtError();
12554
12555 // Transform Loop.
12556 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12557 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12558 C->clauses(), TransformedClauses);
12559 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12560 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12561 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12562
12563 return getDerived().RebuildOpenACCCombinedConstruct(
12564 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12565 C->getEndLoc(), TransformedClauses, Loop);
12566}
12567
12568template <typename Derived>
12569StmtResult
12570TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12571 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12572
12573 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12574 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12575 C->clauses());
12576 if (getSema().OpenACC().ActOnStartStmtDirective(
12577 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12578 return StmtError();
12579
12580 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12581 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12582 C->clauses(), TransformedClauses);
12583 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12584 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12585 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12586
12587 return getDerived().RebuildOpenACCDataConstruct(
12588 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12589 TransformedClauses, StrBlock);
12590}
12591
12592template <typename Derived>
12593StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12594 OpenACCEnterDataConstruct *C) {
12595 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12596
12597 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12598 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12599 C->clauses());
12600 if (getSema().OpenACC().ActOnStartStmtDirective(
12601 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12602 return StmtError();
12603
12604 return getDerived().RebuildOpenACCEnterDataConstruct(
12605 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12606 TransformedClauses);
12607}
12608
12609template <typename Derived>
12610StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12611 OpenACCExitDataConstruct *C) {
12612 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12613
12614 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12615 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12616 C->clauses());
12617 if (getSema().OpenACC().ActOnStartStmtDirective(
12618 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12619 return StmtError();
12620
12621 return getDerived().RebuildOpenACCExitDataConstruct(
12622 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12623 TransformedClauses);
12624}
12625
12626template <typename Derived>
12627StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12628 OpenACCHostDataConstruct *C) {
12629 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12630
12631 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12632 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12633 C->clauses());
12634 if (getSema().OpenACC().ActOnStartStmtDirective(
12635 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12636 return StmtError();
12637
12638 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12639 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12640 C->clauses(), TransformedClauses);
12641 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12642 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12643 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12644
12645 return getDerived().RebuildOpenACCHostDataConstruct(
12646 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12647 TransformedClauses, StrBlock);
12648}
12649
12650template <typename Derived>
12651StmtResult
12652TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12653 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12654
12655 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12656 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12657 C->clauses());
12658 if (getSema().OpenACC().ActOnStartStmtDirective(
12659 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12660 return StmtError();
12661
12662 return getDerived().RebuildOpenACCInitConstruct(
12663 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12664 TransformedClauses);
12665}
12666
12667template <typename Derived>
12668StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12669 OpenACCShutdownConstruct *C) {
12670 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12671
12672 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12673 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12674 C->clauses());
12675 if (getSema().OpenACC().ActOnStartStmtDirective(
12676 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12677 return StmtError();
12678
12679 return getDerived().RebuildOpenACCShutdownConstruct(
12680 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12681 TransformedClauses);
12682}
12683template <typename Derived>
12684StmtResult
12685TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12686 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12687
12688 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12689 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12690 C->clauses());
12691 if (getSema().OpenACC().ActOnStartStmtDirective(
12692 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12693 return StmtError();
12694
12695 return getDerived().RebuildOpenACCSetConstruct(
12696 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12697 TransformedClauses);
12698}
12699
12700template <typename Derived>
12701StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12702 OpenACCUpdateConstruct *C) {
12703 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12704
12705 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12706 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12707 C->clauses());
12708 if (getSema().OpenACC().ActOnStartStmtDirective(
12709 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12710 return StmtError();
12711
12712 return getDerived().RebuildOpenACCUpdateConstruct(
12713 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12714 TransformedClauses);
12715}
12716
12717template <typename Derived>
12718StmtResult
12719TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12720 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12721
12722 ExprResult DevNumExpr;
12723 if (C->hasDevNumExpr()) {
12724 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12725
12726 if (DevNumExpr.isUsable())
12727 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12728 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12729 C->getBeginLoc(), DevNumExpr.get());
12730 }
12731
12732 llvm::SmallVector<Expr *> QueueIdExprs;
12733
12734 for (Expr *QE : C->getQueueIdExprs()) {
12735 assert(QE && "Null queue id expr?");
12736 ExprResult NewEQ = getDerived().TransformExpr(QE);
12737
12738 if (!NewEQ.isUsable())
12739 break;
12740 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12741 OpenACCClauseKind::Invalid,
12742 C->getBeginLoc(), NewEQ.get());
12743 if (NewEQ.isUsable())
12744 QueueIdExprs.push_back(Elt: NewEQ.get());
12745 }
12746
12747 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12748 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12749 C->clauses());
12750
12751 if (getSema().OpenACC().ActOnStartStmtDirective(
12752 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12753 return StmtError();
12754
12755 return getDerived().RebuildOpenACCWaitConstruct(
12756 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12757 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12758 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12759}
12760template <typename Derived>
12761StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12762 OpenACCCacheConstruct *C) {
12763 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12764
12765 llvm::SmallVector<Expr *> TransformedVarList;
12766 for (Expr *Var : C->getVarList()) {
12767 assert(Var && "Null var listexpr?");
12768
12769 ExprResult NewVar = getDerived().TransformExpr(Var);
12770
12771 if (!NewVar.isUsable())
12772 break;
12773
12774 NewVar = getSema().OpenACC().ActOnVar(
12775 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12776 if (!NewVar.isUsable())
12777 break;
12778
12779 TransformedVarList.push_back(Elt: NewVar.get());
12780 }
12781
12782 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12783 C->getBeginLoc(), {}))
12784 return StmtError();
12785
12786 return getDerived().RebuildOpenACCCacheConstruct(
12787 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12788 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
12789 C->getEndLoc());
12790}
12791
12792template <typename Derived>
12793StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
12794 OpenACCAtomicConstruct *C) {
12795 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12796
12797 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12798 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12799 C->clauses());
12800
12801 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12802 C->getBeginLoc(), {}))
12803 return StmtError();
12804
12805 // Transform Associated Stmt.
12806 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12807 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
12808
12809 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
12810 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
12811 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
12812 AssocStmt);
12813
12814 return getDerived().RebuildOpenACCAtomicConstruct(
12815 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
12816 C->getEndLoc(), TransformedClauses, AssocStmt);
12817}
12818
12819template <typename Derived>
12820ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12821 OpenACCAsteriskSizeExpr *E) {
12822 if (getDerived().AlwaysRebuild())
12823 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12824 // Nothing can ever change, so there is never anything to transform.
12825 return E;
12826}
12827
12828//===----------------------------------------------------------------------===//
12829// Expression transformation
12830//===----------------------------------------------------------------------===//
12831template<typename Derived>
12832ExprResult
12833TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12834 return TransformExpr(E: E->getSubExpr());
12835}
12836
12837template <typename Derived>
12838ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12839 SYCLUniqueStableNameExpr *E) {
12840 if (!E->isTypeDependent())
12841 return E;
12842
12843 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12844
12845 if (!NewT)
12846 return ExprError();
12847
12848 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12849 return E;
12850
12851 return getDerived().RebuildSYCLUniqueStableNameExpr(
12852 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12853}
12854
12855template<typename Derived>
12856ExprResult
12857TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12858 if (!E->isTypeDependent())
12859 return E;
12860
12861 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12862 E->getIdentKind());
12863}
12864
12865template<typename Derived>
12866ExprResult
12867TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12868 NestedNameSpecifierLoc QualifierLoc;
12869 if (E->getQualifierLoc()) {
12870 QualifierLoc
12871 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12872 if (!QualifierLoc)
12873 return ExprError();
12874 }
12875
12876 ValueDecl *ND
12877 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12878 E->getDecl()));
12879 if (!ND || ND->isInvalidDecl())
12880 return ExprError();
12881
12882 NamedDecl *Found = ND;
12883 if (E->getFoundDecl() != E->getDecl()) {
12884 Found = cast_or_null<NamedDecl>(
12885 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12886 if (!Found)
12887 return ExprError();
12888 }
12889
12890 DeclarationNameInfo NameInfo = E->getNameInfo();
12891 if (NameInfo.getName()) {
12892 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12893 if (!NameInfo.getName())
12894 return ExprError();
12895 }
12896
12897 if (!getDerived().AlwaysRebuild() &&
12898 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12899 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12900 Found == E->getFoundDecl() &&
12901 NameInfo.getName() == E->getDecl()->getDeclName() &&
12902 !E->hasExplicitTemplateArgs()) {
12903
12904 // Mark it referenced in the new context regardless.
12905 // FIXME: this is a bit instantiation-specific.
12906 SemaRef.MarkDeclRefReferenced(E);
12907
12908 return E;
12909 }
12910
12911 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12912 if (E->hasExplicitTemplateArgs()) {
12913 TemplateArgs = &TransArgs;
12914 TransArgs.setLAngleLoc(E->getLAngleLoc());
12915 TransArgs.setRAngleLoc(E->getRAngleLoc());
12916 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12917 E->getNumTemplateArgs(),
12918 TransArgs))
12919 return ExprError();
12920 }
12921
12922 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12923 Found, TemplateArgs);
12924}
12925
12926template<typename Derived>
12927ExprResult
12928TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12929 return E;
12930}
12931
12932template <typename Derived>
12933ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12934 FixedPointLiteral *E) {
12935 return E;
12936}
12937
12938template<typename Derived>
12939ExprResult
12940TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12941 return E;
12942}
12943
12944template<typename Derived>
12945ExprResult
12946TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12947 return E;
12948}
12949
12950template<typename Derived>
12951ExprResult
12952TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12953 return E;
12954}
12955
12956template<typename Derived>
12957ExprResult
12958TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12959 return E;
12960}
12961
12962template<typename Derived>
12963ExprResult
12964TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12965 return getDerived().TransformCallExpr(E);
12966}
12967
12968template<typename Derived>
12969ExprResult
12970TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12971 ExprResult ControllingExpr;
12972 TypeSourceInfo *ControllingType = nullptr;
12973 if (E->isExprPredicate())
12974 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12975 else
12976 ControllingType = getDerived().TransformType(E->getControllingType());
12977
12978 if (ControllingExpr.isInvalid() && !ControllingType)
12979 return ExprError();
12980
12981 SmallVector<Expr *, 4> AssocExprs;
12982 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12983 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12984 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12985 if (TSI) {
12986 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12987 if (!AssocType)
12988 return ExprError();
12989 AssocTypes.push_back(Elt: AssocType);
12990 } else {
12991 AssocTypes.push_back(Elt: nullptr);
12992 }
12993
12994 ExprResult AssocExpr =
12995 getDerived().TransformExpr(Assoc.getAssociationExpr());
12996 if (AssocExpr.isInvalid())
12997 return ExprError();
12998 AssocExprs.push_back(Elt: AssocExpr.get());
12999 }
13000
13001 if (!ControllingType)
13002 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
13003 E->getDefaultLoc(),
13004 E->getRParenLoc(),
13005 ControllingExpr.get(),
13006 AssocTypes,
13007 AssocExprs);
13008 return getDerived().RebuildGenericSelectionExpr(
13009 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13010 ControllingType, AssocTypes, AssocExprs);
13011}
13012
13013template<typename Derived>
13014ExprResult
13015TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13016 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13017 if (SubExpr.isInvalid())
13018 return ExprError();
13019
13020 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13021 return E;
13022
13023 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13024 E->getRParen());
13025}
13026
13027/// The operand of a unary address-of operator has special rules: it's
13028/// allowed to refer to a non-static member of a class even if there's no 'this'
13029/// object available.
13030template<typename Derived>
13031ExprResult
13032TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13033 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(Val: E))
13034 return getDerived().TransformDependentScopeDeclRefExpr(
13035 DRE, /*IsAddressOfOperand=*/true, nullptr);
13036 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: E))
13037 return getDerived().TransformUnresolvedLookupExpr(
13038 ULE, /*IsAddressOfOperand=*/true);
13039 else
13040 return getDerived().TransformExpr(E);
13041}
13042
13043template<typename Derived>
13044ExprResult
13045TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13046 ExprResult SubExpr;
13047 if (E->getOpcode() == UO_AddrOf)
13048 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13049 else
13050 SubExpr = TransformExpr(E: E->getSubExpr());
13051 if (SubExpr.isInvalid())
13052 return ExprError();
13053
13054 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13055 return E;
13056
13057 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13058 E->getOpcode(),
13059 SubExpr.get());
13060}
13061
13062template<typename Derived>
13063ExprResult
13064TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13065 // Transform the type.
13066 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13067 if (!Type)
13068 return ExprError();
13069
13070 // Transform all of the components into components similar to what the
13071 // parser uses.
13072 // FIXME: It would be slightly more efficient in the non-dependent case to
13073 // just map FieldDecls, rather than requiring the rebuilder to look for
13074 // the fields again. However, __builtin_offsetof is rare enough in
13075 // template code that we don't care.
13076 bool ExprChanged = false;
13077 typedef Sema::OffsetOfComponent Component;
13078 SmallVector<Component, 4> Components;
13079 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13080 const OffsetOfNode &ON = E->getComponent(Idx: I);
13081 Component Comp;
13082 Comp.isBrackets = true;
13083 Comp.LocStart = ON.getSourceRange().getBegin();
13084 Comp.LocEnd = ON.getSourceRange().getEnd();
13085 switch (ON.getKind()) {
13086 case OffsetOfNode::Array: {
13087 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13088 ExprResult Index = getDerived().TransformExpr(FromIndex);
13089 if (Index.isInvalid())
13090 return ExprError();
13091
13092 ExprChanged = ExprChanged || Index.get() != FromIndex;
13093 Comp.isBrackets = true;
13094 Comp.U.E = Index.get();
13095 break;
13096 }
13097
13098 case OffsetOfNode::Field:
13099 case OffsetOfNode::Identifier:
13100 Comp.isBrackets = false;
13101 Comp.U.IdentInfo = ON.getFieldName();
13102 if (!Comp.U.IdentInfo)
13103 continue;
13104
13105 break;
13106
13107 case OffsetOfNode::Base:
13108 // Will be recomputed during the rebuild.
13109 continue;
13110 }
13111
13112 Components.push_back(Elt: Comp);
13113 }
13114
13115 // If nothing changed, retain the existing expression.
13116 if (!getDerived().AlwaysRebuild() &&
13117 Type == E->getTypeSourceInfo() &&
13118 !ExprChanged)
13119 return E;
13120
13121 // Build a new offsetof expression.
13122 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13123 Components, E->getRParenLoc());
13124}
13125
13126template<typename Derived>
13127ExprResult
13128TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13129 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13130 "opaque value expression requires transformation");
13131 return E;
13132}
13133
13134template <typename Derived>
13135ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13136 llvm::SmallVector<Expr *, 8> Children;
13137 bool Changed = false;
13138 for (Expr *C : E->subExpressions()) {
13139 ExprResult NewC = getDerived().TransformExpr(C);
13140 if (NewC.isInvalid())
13141 return ExprError();
13142 Children.push_back(Elt: NewC.get());
13143
13144 Changed |= NewC.get() != C;
13145 }
13146 if (!getDerived().AlwaysRebuild() && !Changed)
13147 return E;
13148 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13149 Children, E->getType());
13150}
13151
13152template<typename Derived>
13153ExprResult
13154TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13155 // Rebuild the syntactic form. The original syntactic form has
13156 // opaque-value expressions in it, so strip those away and rebuild
13157 // the result. This is a really awful way of doing this, but the
13158 // better solution (rebuilding the semantic expressions and
13159 // rebinding OVEs as necessary) doesn't work; we'd need
13160 // TreeTransform to not strip away implicit conversions.
13161 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13162 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13163 if (result.isInvalid()) return ExprError();
13164
13165 // If that gives us a pseudo-object result back, the pseudo-object
13166 // expression must have been an lvalue-to-rvalue conversion which we
13167 // should reapply.
13168 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13169 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13170
13171 return result;
13172}
13173
13174template<typename Derived>
13175ExprResult
13176TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13177 UnaryExprOrTypeTraitExpr *E) {
13178 if (E->isArgumentType()) {
13179 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13180
13181 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13182 if (!NewT)
13183 return ExprError();
13184
13185 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13186 return E;
13187
13188 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13189 E->getKind(),
13190 E->getSourceRange());
13191 }
13192
13193 // C++0x [expr.sizeof]p1:
13194 // The operand is either an expression, which is an unevaluated operand
13195 // [...]
13196 EnterExpressionEvaluationContext Unevaluated(
13197 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13198 Sema::ReuseLambdaContextDecl);
13199
13200 // Try to recover if we have something like sizeof(T::X) where X is a type.
13201 // Notably, there must be *exactly* one set of parens if X is a type.
13202 TypeSourceInfo *RecoveryTSI = nullptr;
13203 ExprResult SubExpr;
13204 auto *PE = dyn_cast<ParenExpr>(Val: E->getArgumentExpr());
13205 if (auto *DRE =
13206 PE ? dyn_cast<DependentScopeDeclRefExpr>(Val: PE->getSubExpr()) : nullptr)
13207 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13208 PE, DRE, false, &RecoveryTSI);
13209 else
13210 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13211
13212 if (RecoveryTSI) {
13213 return getDerived().RebuildUnaryExprOrTypeTrait(
13214 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13215 } else if (SubExpr.isInvalid())
13216 return ExprError();
13217
13218 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13219 return E;
13220
13221 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13222 E->getOperatorLoc(),
13223 E->getKind(),
13224 E->getSourceRange());
13225}
13226
13227template<typename Derived>
13228ExprResult
13229TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13230 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13231 if (LHS.isInvalid())
13232 return ExprError();
13233
13234 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13235 if (RHS.isInvalid())
13236 return ExprError();
13237
13238
13239 if (!getDerived().AlwaysRebuild() &&
13240 LHS.get() == E->getLHS() &&
13241 RHS.get() == E->getRHS())
13242 return E;
13243
13244 return getDerived().RebuildArraySubscriptExpr(
13245 LHS.get(),
13246 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13247}
13248
13249template <typename Derived>
13250ExprResult
13251TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13252 ExprResult Base = getDerived().TransformExpr(E->getBase());
13253 if (Base.isInvalid())
13254 return ExprError();
13255
13256 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13257 if (RowIdx.isInvalid())
13258 return ExprError();
13259
13260 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13261 if (ColumnIdx.isInvalid())
13262 return ExprError();
13263
13264 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13265 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13266 return E;
13267
13268 return getDerived().RebuildMatrixSubscriptExpr(
13269 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13270}
13271
13272template <typename Derived>
13273ExprResult
13274TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13275 ExprResult Base = getDerived().TransformExpr(E->getBase());
13276 if (Base.isInvalid())
13277 return ExprError();
13278
13279 ExprResult LowerBound;
13280 if (E->getLowerBound()) {
13281 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13282 if (LowerBound.isInvalid())
13283 return ExprError();
13284 }
13285
13286 ExprResult Length;
13287 if (E->getLength()) {
13288 Length = getDerived().TransformExpr(E->getLength());
13289 if (Length.isInvalid())
13290 return ExprError();
13291 }
13292
13293 ExprResult Stride;
13294 if (E->isOMPArraySection()) {
13295 if (Expr *Str = E->getStride()) {
13296 Stride = getDerived().TransformExpr(Str);
13297 if (Stride.isInvalid())
13298 return ExprError();
13299 }
13300 }
13301
13302 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13303 LowerBound.get() == E->getLowerBound() &&
13304 Length.get() == E->getLength() &&
13305 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13306 return E;
13307
13308 return getDerived().RebuildArraySectionExpr(
13309 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13310 LowerBound.get(), E->getColonLocFirst(),
13311 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13312 Length.get(), Stride.get(), E->getRBracketLoc());
13313}
13314
13315template <typename Derived>
13316ExprResult
13317TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13318 ExprResult Base = getDerived().TransformExpr(E->getBase());
13319 if (Base.isInvalid())
13320 return ExprError();
13321
13322 SmallVector<Expr *, 4> Dims;
13323 bool ErrorFound = false;
13324 for (Expr *Dim : E->getDimensions()) {
13325 ExprResult DimRes = getDerived().TransformExpr(Dim);
13326 if (DimRes.isInvalid()) {
13327 ErrorFound = true;
13328 continue;
13329 }
13330 Dims.push_back(Elt: DimRes.get());
13331 }
13332
13333 if (ErrorFound)
13334 return ExprError();
13335 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13336 E->getRParenLoc(), Dims,
13337 E->getBracketsRanges());
13338}
13339
13340template <typename Derived>
13341ExprResult
13342TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13343 unsigned NumIterators = E->numOfIterators();
13344 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13345
13346 bool ErrorFound = false;
13347 bool NeedToRebuild = getDerived().AlwaysRebuild();
13348 for (unsigned I = 0; I < NumIterators; ++I) {
13349 auto *D = cast<VarDecl>(Val: E->getIteratorDecl(I));
13350 Data[I].DeclIdent = D->getIdentifier();
13351 Data[I].DeclIdentLoc = D->getLocation();
13352 if (D->getLocation() == D->getBeginLoc()) {
13353 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13354 "Implicit type must be int.");
13355 } else {
13356 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13357 QualType DeclTy = getDerived().TransformType(D->getType());
13358 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13359 }
13360 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13361 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13362 ExprResult End = getDerived().TransformExpr(Range.End);
13363 ExprResult Step = getDerived().TransformExpr(Range.Step);
13364 ErrorFound = ErrorFound ||
13365 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13366 !Data[I].Type.get().isNull())) ||
13367 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13368 if (ErrorFound)
13369 continue;
13370 Data[I].Range.Begin = Begin.get();
13371 Data[I].Range.End = End.get();
13372 Data[I].Range.Step = Step.get();
13373 Data[I].AssignLoc = E->getAssignLoc(I);
13374 Data[I].ColonLoc = E->getColonLoc(I);
13375 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13376 NeedToRebuild =
13377 NeedToRebuild ||
13378 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13379 D->getType().getTypePtrOrNull()) ||
13380 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13381 Range.Step != Data[I].Range.Step;
13382 }
13383 if (ErrorFound)
13384 return ExprError();
13385 if (!NeedToRebuild)
13386 return E;
13387
13388 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13389 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13390 if (!Res.isUsable())
13391 return Res;
13392 auto *IE = cast<OMPIteratorExpr>(Val: Res.get());
13393 for (unsigned I = 0; I < NumIterators; ++I)
13394 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13395 IE->getIteratorDecl(I));
13396 return Res;
13397}
13398
13399template<typename Derived>
13400ExprResult
13401TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13402 // Transform the callee.
13403 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13404 if (Callee.isInvalid())
13405 return ExprError();
13406
13407 // Transform arguments.
13408 bool ArgChanged = false;
13409 SmallVector<Expr*, 8> Args;
13410 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13411 &ArgChanged))
13412 return ExprError();
13413
13414 if (!getDerived().AlwaysRebuild() &&
13415 Callee.get() == E->getCallee() &&
13416 !ArgChanged)
13417 return SemaRef.MaybeBindToTemporary(E);
13418
13419 // FIXME: Wrong source location information for the '('.
13420 SourceLocation FakeLParenLoc
13421 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13422
13423 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13424 if (E->hasStoredFPFeatures()) {
13425 FPOptionsOverride NewOverrides = E->getFPFeatures();
13426 getSema().CurFPFeatures =
13427 NewOverrides.applyOverrides(getSema().getLangOpts());
13428 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13429 }
13430
13431 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13432 Args,
13433 E->getRParenLoc());
13434}
13435
13436template<typename Derived>
13437ExprResult
13438TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13439 ExprResult Base = getDerived().TransformExpr(E->getBase());
13440 if (Base.isInvalid())
13441 return ExprError();
13442
13443 NestedNameSpecifierLoc QualifierLoc;
13444 if (E->hasQualifier()) {
13445 QualifierLoc
13446 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13447
13448 if (!QualifierLoc)
13449 return ExprError();
13450 }
13451 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13452
13453 ValueDecl *Member
13454 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13455 E->getMemberDecl()));
13456 if (!Member)
13457 return ExprError();
13458
13459 NamedDecl *FoundDecl = E->getFoundDecl();
13460 if (FoundDecl == E->getMemberDecl()) {
13461 FoundDecl = Member;
13462 } else {
13463 FoundDecl = cast_or_null<NamedDecl>(
13464 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13465 if (!FoundDecl)
13466 return ExprError();
13467 }
13468
13469 if (!getDerived().AlwaysRebuild() &&
13470 Base.get() == E->getBase() &&
13471 QualifierLoc == E->getQualifierLoc() &&
13472 Member == E->getMemberDecl() &&
13473 FoundDecl == E->getFoundDecl() &&
13474 !E->hasExplicitTemplateArgs()) {
13475
13476 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13477 // for Openmp where the field need to be privatizized in the case.
13478 if (!(isa<CXXThisExpr>(Val: E->getBase()) &&
13479 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13480 cast<ValueDecl>(Val: Member)))) {
13481 // Mark it referenced in the new context regardless.
13482 // FIXME: this is a bit instantiation-specific.
13483 SemaRef.MarkMemberReferenced(E);
13484 return E;
13485 }
13486 }
13487
13488 TemplateArgumentListInfo TransArgs;
13489 if (E->hasExplicitTemplateArgs()) {
13490 TransArgs.setLAngleLoc(E->getLAngleLoc());
13491 TransArgs.setRAngleLoc(E->getRAngleLoc());
13492 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13493 E->getNumTemplateArgs(),
13494 TransArgs))
13495 return ExprError();
13496 }
13497
13498 // FIXME: Bogus source location for the operator
13499 SourceLocation FakeOperatorLoc =
13500 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13501
13502 // FIXME: to do this check properly, we will need to preserve the
13503 // first-qualifier-in-scope here, just in case we had a dependent
13504 // base (and therefore couldn't do the check) and a
13505 // nested-name-qualifier (and therefore could do the lookup).
13506 NamedDecl *FirstQualifierInScope = nullptr;
13507 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13508 if (MemberNameInfo.getName()) {
13509 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13510 if (!MemberNameInfo.getName())
13511 return ExprError();
13512 }
13513
13514 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13515 E->isArrow(),
13516 QualifierLoc,
13517 TemplateKWLoc,
13518 MemberNameInfo,
13519 Member,
13520 FoundDecl,
13521 (E->hasExplicitTemplateArgs()
13522 ? &TransArgs : nullptr),
13523 FirstQualifierInScope);
13524}
13525
13526template<typename Derived>
13527ExprResult
13528TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13529 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13530 if (LHS.isInvalid())
13531 return ExprError();
13532
13533 ExprResult RHS =
13534 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13535 if (RHS.isInvalid())
13536 return ExprError();
13537
13538 if (!getDerived().AlwaysRebuild() &&
13539 LHS.get() == E->getLHS() &&
13540 RHS.get() == E->getRHS())
13541 return E;
13542
13543 if (E->isCompoundAssignmentOp())
13544 // FPFeatures has already been established from trailing storage
13545 return getDerived().RebuildBinaryOperator(
13546 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13547 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13548 FPOptionsOverride NewOverrides(E->getFPFeatures());
13549 getSema().CurFPFeatures =
13550 NewOverrides.applyOverrides(getSema().getLangOpts());
13551 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13552 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13553 LHS.get(), RHS.get());
13554}
13555
13556template <typename Derived>
13557ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13558 CXXRewrittenBinaryOperator *E) {
13559 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13560
13561 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13562 if (LHS.isInvalid())
13563 return ExprError();
13564
13565 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13566 if (RHS.isInvalid())
13567 return ExprError();
13568
13569 // Extract the already-resolved callee declarations so that we can restrict
13570 // ourselves to using them as the unqualified lookup results when rebuilding.
13571 UnresolvedSet<2> UnqualLookups;
13572 bool ChangedAnyLookups = false;
13573 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13574 const_cast<Expr *>(Decomp.InnerBinOp)};
13575 for (Expr *PossibleBinOp : PossibleBinOps) {
13576 auto *Op = dyn_cast<CXXOperatorCallExpr>(Val: PossibleBinOp->IgnoreImplicit());
13577 if (!Op)
13578 continue;
13579 auto *Callee = dyn_cast<DeclRefExpr>(Val: Op->getCallee()->IgnoreImplicit());
13580 if (!Callee || isa<CXXMethodDecl>(Val: Callee->getDecl()))
13581 continue;
13582
13583 // Transform the callee in case we built a call to a local extern
13584 // declaration.
13585 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13586 E->getOperatorLoc(), Callee->getFoundDecl()));
13587 if (!Found)
13588 return ExprError();
13589 if (Found != Callee->getFoundDecl())
13590 ChangedAnyLookups = true;
13591 UnqualLookups.addDecl(D: Found);
13592 }
13593
13594 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13595 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13596 // Mark all functions used in the rewrite as referenced. Note that when
13597 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13598 // function calls, and/or there might be a user-defined conversion sequence
13599 // applied to the operands of the <.
13600 // FIXME: this is a bit instantiation-specific.
13601 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13602 SemaRef.MarkDeclarationsReferencedInExpr(E, SkipLocalVariables: false, StopAt);
13603 return E;
13604 }
13605
13606 return getDerived().RebuildCXXRewrittenBinaryOperator(
13607 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13608}
13609
13610template<typename Derived>
13611ExprResult
13612TreeTransform<Derived>::TransformCompoundAssignOperator(
13613 CompoundAssignOperator *E) {
13614 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13615 FPOptionsOverride NewOverrides(E->getFPFeatures());
13616 getSema().CurFPFeatures =
13617 NewOverrides.applyOverrides(getSema().getLangOpts());
13618 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13619 return getDerived().TransformBinaryOperator(E);
13620}
13621
13622template<typename Derived>
13623ExprResult TreeTransform<Derived>::
13624TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13625 // Just rebuild the common and RHS expressions and see whether we
13626 // get any changes.
13627
13628 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13629 if (commonExpr.isInvalid())
13630 return ExprError();
13631
13632 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13633 if (rhs.isInvalid())
13634 return ExprError();
13635
13636 if (!getDerived().AlwaysRebuild() &&
13637 commonExpr.get() == e->getCommon() &&
13638 rhs.get() == e->getFalseExpr())
13639 return e;
13640
13641 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13642 e->getQuestionLoc(),
13643 nullptr,
13644 e->getColonLoc(),
13645 rhs.get());
13646}
13647
13648template<typename Derived>
13649ExprResult
13650TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13651 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13652 if (Cond.isInvalid())
13653 return ExprError();
13654
13655 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13656 if (LHS.isInvalid())
13657 return ExprError();
13658
13659 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13660 if (RHS.isInvalid())
13661 return ExprError();
13662
13663 if (!getDerived().AlwaysRebuild() &&
13664 Cond.get() == E->getCond() &&
13665 LHS.get() == E->getLHS() &&
13666 RHS.get() == E->getRHS())
13667 return E;
13668
13669 return getDerived().RebuildConditionalOperator(Cond.get(),
13670 E->getQuestionLoc(),
13671 LHS.get(),
13672 E->getColonLoc(),
13673 RHS.get());
13674}
13675
13676template<typename Derived>
13677ExprResult
13678TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13679 // Implicit casts are eliminated during transformation, since they
13680 // will be recomputed by semantic analysis after transformation.
13681 return getDerived().TransformExpr(E->getSubExprAsWritten());
13682}
13683
13684template<typename Derived>
13685ExprResult
13686TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13687 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13688 if (!Type)
13689 return ExprError();
13690
13691 ExprResult SubExpr
13692 = getDerived().TransformExpr(E->getSubExprAsWritten());
13693 if (SubExpr.isInvalid())
13694 return ExprError();
13695
13696 if (!getDerived().AlwaysRebuild() &&
13697 Type == E->getTypeInfoAsWritten() &&
13698 SubExpr.get() == E->getSubExpr())
13699 return E;
13700
13701 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13702 Type,
13703 E->getRParenLoc(),
13704 SubExpr.get());
13705}
13706
13707template<typename Derived>
13708ExprResult
13709TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13710 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13711 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13712 if (!NewT)
13713 return ExprError();
13714
13715 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13716 if (Init.isInvalid())
13717 return ExprError();
13718
13719 if (!getDerived().AlwaysRebuild() &&
13720 OldT == NewT &&
13721 Init.get() == E->getInitializer())
13722 return SemaRef.MaybeBindToTemporary(E);
13723
13724 // Note: the expression type doesn't necessarily match the
13725 // type-as-written, but that's okay, because it should always be
13726 // derivable from the initializer.
13727
13728 return getDerived().RebuildCompoundLiteralExpr(
13729 E->getLParenLoc(), NewT,
13730 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13731}
13732
13733template<typename Derived>
13734ExprResult
13735TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13736 ExprResult Base = getDerived().TransformExpr(E->getBase());
13737 if (Base.isInvalid())
13738 return ExprError();
13739
13740 if (!getDerived().AlwaysRebuild() &&
13741 Base.get() == E->getBase())
13742 return E;
13743
13744 // FIXME: Bad source location
13745 SourceLocation FakeOperatorLoc =
13746 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
13747 return getDerived().RebuildExtVectorElementExpr(
13748 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13749 E->getAccessor());
13750}
13751
13752template<typename Derived>
13753ExprResult
13754TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13755 if (InitListExpr *Syntactic = E->getSyntacticForm())
13756 E = Syntactic;
13757
13758 bool InitChanged = false;
13759
13760 EnterExpressionEvaluationContext Context(
13761 getSema(), EnterExpressionEvaluationContext::InitList);
13762
13763 SmallVector<Expr*, 4> Inits;
13764 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13765 Inits, &InitChanged))
13766 return ExprError();
13767
13768 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13769 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13770 // in some cases. We can't reuse it in general, because the syntactic and
13771 // semantic forms are linked, and we can't know that semantic form will
13772 // match even if the syntactic form does.
13773 }
13774
13775 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13776 E->getRBraceLoc());
13777}
13778
13779template<typename Derived>
13780ExprResult
13781TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13782 Designation Desig;
13783
13784 // transform the initializer value
13785 ExprResult Init = getDerived().TransformExpr(E->getInit());
13786 if (Init.isInvalid())
13787 return ExprError();
13788
13789 // transform the designators.
13790 SmallVector<Expr*, 4> ArrayExprs;
13791 bool ExprChanged = false;
13792 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13793 if (D.isFieldDesignator()) {
13794 if (D.getFieldDecl()) {
13795 FieldDecl *Field = cast_or_null<FieldDecl>(
13796 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13797 if (Field != D.getFieldDecl())
13798 // Rebuild the expression when the transformed FieldDecl is
13799 // different to the already assigned FieldDecl.
13800 ExprChanged = true;
13801 if (Field->isAnonymousStructOrUnion())
13802 continue;
13803 } else {
13804 // Ensure that the designator expression is rebuilt when there isn't
13805 // a resolved FieldDecl in the designator as we don't want to assign
13806 // a FieldDecl to a pattern designator that will be instantiated again.
13807 ExprChanged = true;
13808 }
13809 Desig.AddDesignator(D: Designator::CreateFieldDesignator(
13810 FieldName: D.getFieldName(), DotLoc: D.getDotLoc(), FieldLoc: D.getFieldLoc()));
13811 continue;
13812 }
13813
13814 if (D.isArrayDesignator()) {
13815 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13816 if (Index.isInvalid())
13817 return ExprError();
13818
13819 Desig.AddDesignator(
13820 D: Designator::CreateArrayDesignator(Index: Index.get(), LBracketLoc: D.getLBracketLoc()));
13821
13822 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
13823 ArrayExprs.push_back(Elt: Index.get());
13824 continue;
13825 }
13826
13827 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13828 ExprResult Start
13829 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13830 if (Start.isInvalid())
13831 return ExprError();
13832
13833 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13834 if (End.isInvalid())
13835 return ExprError();
13836
13837 Desig.AddDesignator(D: Designator::CreateArrayRangeDesignator(
13838 Start: Start.get(), End: End.get(), LBracketLoc: D.getLBracketLoc(), EllipsisLoc: D.getEllipsisLoc()));
13839
13840 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13841 End.get() != E->getArrayRangeEnd(D);
13842
13843 ArrayExprs.push_back(Elt: Start.get());
13844 ArrayExprs.push_back(Elt: End.get());
13845 }
13846
13847 if (!getDerived().AlwaysRebuild() &&
13848 Init.get() == E->getInit() &&
13849 !ExprChanged)
13850 return E;
13851
13852 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13853 E->getEqualOrColonLoc(),
13854 E->usesGNUSyntax(), Init.get());
13855}
13856
13857// Seems that if TransformInitListExpr() only works on the syntactic form of an
13858// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13859template<typename Derived>
13860ExprResult
13861TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13862 DesignatedInitUpdateExpr *E) {
13863 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13864 "initializer");
13865 return ExprError();
13866}
13867
13868template<typename Derived>
13869ExprResult
13870TreeTransform<Derived>::TransformNoInitExpr(
13871 NoInitExpr *E) {
13872 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13873 return ExprError();
13874}
13875
13876template<typename Derived>
13877ExprResult
13878TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13879 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13880 return ExprError();
13881}
13882
13883template<typename Derived>
13884ExprResult
13885TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13886 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13887 return ExprError();
13888}
13889
13890template<typename Derived>
13891ExprResult
13892TreeTransform<Derived>::TransformImplicitValueInitExpr(
13893 ImplicitValueInitExpr *E) {
13894 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13895
13896 // FIXME: Will we ever have proper type location here? Will we actually
13897 // need to transform the type?
13898 QualType T = getDerived().TransformType(E->getType());
13899 if (T.isNull())
13900 return ExprError();
13901
13902 if (!getDerived().AlwaysRebuild() &&
13903 T == E->getType())
13904 return E;
13905
13906 return getDerived().RebuildImplicitValueInitExpr(T);
13907}
13908
13909template<typename Derived>
13910ExprResult
13911TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13912 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13913 if (!TInfo)
13914 return ExprError();
13915
13916 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13917 if (SubExpr.isInvalid())
13918 return ExprError();
13919
13920 if (!getDerived().AlwaysRebuild() &&
13921 TInfo == E->getWrittenTypeInfo() &&
13922 SubExpr.get() == E->getSubExpr())
13923 return E;
13924
13925 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13926 TInfo, E->getRParenLoc());
13927}
13928
13929template<typename Derived>
13930ExprResult
13931TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13932 bool ArgumentChanged = false;
13933 SmallVector<Expr*, 4> Inits;
13934 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
13935 ArgChanged: &ArgumentChanged))
13936 return ExprError();
13937
13938 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13939 Inits,
13940 E->getRParenLoc());
13941}
13942
13943/// Transform an address-of-label expression.
13944///
13945/// By default, the transformation of an address-of-label expression always
13946/// rebuilds the expression, so that the label identifier can be resolved to
13947/// the corresponding label statement by semantic analysis.
13948template<typename Derived>
13949ExprResult
13950TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13951 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13952 E->getLabel());
13953 if (!LD)
13954 return ExprError();
13955
13956 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13957 cast<LabelDecl>(Val: LD));
13958}
13959
13960template<typename Derived>
13961ExprResult
13962TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13963 SemaRef.ActOnStartStmtExpr();
13964 StmtResult SubStmt
13965 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13966 if (SubStmt.isInvalid()) {
13967 SemaRef.ActOnStmtExprError();
13968 return ExprError();
13969 }
13970
13971 unsigned OldDepth = E->getTemplateDepth();
13972 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13973
13974 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13975 SubStmt.get() == E->getSubStmt()) {
13976 // Calling this an 'error' is unintuitive, but it does the right thing.
13977 SemaRef.ActOnStmtExprError();
13978 return SemaRef.MaybeBindToTemporary(E);
13979 }
13980
13981 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13982 E->getRParenLoc(), NewDepth);
13983}
13984
13985template<typename Derived>
13986ExprResult
13987TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13988 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13989 if (Cond.isInvalid())
13990 return ExprError();
13991
13992 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13993 if (LHS.isInvalid())
13994 return ExprError();
13995
13996 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13997 if (RHS.isInvalid())
13998 return ExprError();
13999
14000 if (!getDerived().AlwaysRebuild() &&
14001 Cond.get() == E->getCond() &&
14002 LHS.get() == E->getLHS() &&
14003 RHS.get() == E->getRHS())
14004 return E;
14005
14006 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14007 Cond.get(), LHS.get(), RHS.get(),
14008 E->getRParenLoc());
14009}
14010
14011template<typename Derived>
14012ExprResult
14013TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14014 return E;
14015}
14016
14017template<typename Derived>
14018ExprResult
14019TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14020 switch (E->getOperator()) {
14021 case OO_New:
14022 case OO_Delete:
14023 case OO_Array_New:
14024 case OO_Array_Delete:
14025 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14026
14027 case OO_Subscript:
14028 case OO_Call: {
14029 // This is a call to an object's operator().
14030 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14031
14032 // Transform the object itself.
14033 ExprResult Object = getDerived().TransformExpr(E->getArg(Arg: 0));
14034 if (Object.isInvalid())
14035 return ExprError();
14036
14037 // FIXME: Poor location information
14038 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
14039 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
14040
14041 // Transform the call arguments.
14042 SmallVector<Expr*, 8> Args;
14043 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14044 Args))
14045 return ExprError();
14046
14047 if (E->getOperator() == OO_Subscript)
14048 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14049 Args, E->getEndLoc());
14050
14051 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14052 E->getEndLoc());
14053 }
14054
14055#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14056 case OO_##Name: \
14057 break;
14058
14059#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14060#include "clang/Basic/OperatorKinds.def"
14061
14062 case OO_Conditional:
14063 llvm_unreachable("conditional operator is not actually overloadable");
14064
14065 case OO_None:
14066 case NUM_OVERLOADED_OPERATORS:
14067 llvm_unreachable("not an overloaded operator?");
14068 }
14069
14070 ExprResult First;
14071 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14072 First = getDerived().TransformAddressOfOperand(E->getArg(Arg: 0));
14073 else
14074 First = getDerived().TransformExpr(E->getArg(Arg: 0));
14075 if (First.isInvalid())
14076 return ExprError();
14077
14078 ExprResult Second;
14079 if (E->getNumArgs() == 2) {
14080 Second =
14081 getDerived().TransformInitializer(E->getArg(Arg: 1), /*NotCopyInit=*/false);
14082 if (Second.isInvalid())
14083 return ExprError();
14084 }
14085
14086 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14087 FPOptionsOverride NewOverrides(E->getFPFeatures());
14088 getSema().CurFPFeatures =
14089 NewOverrides.applyOverrides(getSema().getLangOpts());
14090 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14091
14092 Expr *Callee = E->getCallee();
14093 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Val: Callee)) {
14094 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14095 Sema::LookupOrdinaryName);
14096 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14097 return ExprError();
14098
14099 return getDerived().RebuildCXXOperatorCallExpr(
14100 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14101 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14102 }
14103
14104 UnresolvedSet<1> Functions;
14105 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Val: Callee))
14106 Callee = ICE->getSubExprAsWritten();
14107 NamedDecl *DR = cast<DeclRefExpr>(Val: Callee)->getDecl();
14108 ValueDecl *VD = cast_or_null<ValueDecl>(
14109 getDerived().TransformDecl(DR->getLocation(), DR));
14110 if (!VD)
14111 return ExprError();
14112
14113 if (!isa<CXXMethodDecl>(Val: VD))
14114 Functions.addDecl(D: VD);
14115
14116 return getDerived().RebuildCXXOperatorCallExpr(
14117 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14118 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14119}
14120
14121template<typename Derived>
14122ExprResult
14123TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14124 return getDerived().TransformCallExpr(E);
14125}
14126
14127template <typename Derived>
14128ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14129 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14130 getSema().CurContext != E->getParentContext();
14131
14132 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14133 return E;
14134
14135 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14136 E->getBeginLoc(), E->getEndLoc(),
14137 getSema().CurContext);
14138}
14139
14140template <typename Derived>
14141ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14142 return E;
14143}
14144
14145template<typename Derived>
14146ExprResult
14147TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14148 // Transform the callee.
14149 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14150 if (Callee.isInvalid())
14151 return ExprError();
14152
14153 // Transform exec config.
14154 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14155 if (EC.isInvalid())
14156 return ExprError();
14157
14158 // Transform arguments.
14159 bool ArgChanged = false;
14160 SmallVector<Expr*, 8> Args;
14161 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14162 &ArgChanged))
14163 return ExprError();
14164
14165 if (!getDerived().AlwaysRebuild() &&
14166 Callee.get() == E->getCallee() &&
14167 !ArgChanged)
14168 return SemaRef.MaybeBindToTemporary(E);
14169
14170 // FIXME: Wrong source location information for the '('.
14171 SourceLocation FakeLParenLoc
14172 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14173 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14174 Args,
14175 E->getRParenLoc(), EC.get());
14176}
14177
14178template<typename Derived>
14179ExprResult
14180TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14181 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14182 if (!Type)
14183 return ExprError();
14184
14185 ExprResult SubExpr
14186 = getDerived().TransformExpr(E->getSubExprAsWritten());
14187 if (SubExpr.isInvalid())
14188 return ExprError();
14189
14190 if (!getDerived().AlwaysRebuild() &&
14191 Type == E->getTypeInfoAsWritten() &&
14192 SubExpr.get() == E->getSubExpr())
14193 return E;
14194 return getDerived().RebuildCXXNamedCastExpr(
14195 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14196 Type, E->getAngleBrackets().getEnd(),
14197 // FIXME. this should be '(' location
14198 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14199}
14200
14201template<typename Derived>
14202ExprResult
14203TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14204 TypeSourceInfo *TSI =
14205 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14206 if (!TSI)
14207 return ExprError();
14208
14209 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14210 if (Sub.isInvalid())
14211 return ExprError();
14212
14213 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14214 Sub.get(), BCE->getEndLoc());
14215}
14216
14217template<typename Derived>
14218ExprResult
14219TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14220 return getDerived().TransformCXXNamedCastExpr(E);
14221}
14222
14223template<typename Derived>
14224ExprResult
14225TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14226 return getDerived().TransformCXXNamedCastExpr(E);
14227}
14228
14229template<typename Derived>
14230ExprResult
14231TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14232 CXXReinterpretCastExpr *E) {
14233 return getDerived().TransformCXXNamedCastExpr(E);
14234}
14235
14236template<typename Derived>
14237ExprResult
14238TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14239 return getDerived().TransformCXXNamedCastExpr(E);
14240}
14241
14242template<typename Derived>
14243ExprResult
14244TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14245 return getDerived().TransformCXXNamedCastExpr(E);
14246}
14247
14248template<typename Derived>
14249ExprResult
14250TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14251 CXXFunctionalCastExpr *E) {
14252 TypeSourceInfo *Type =
14253 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14254 if (!Type)
14255 return ExprError();
14256
14257 ExprResult SubExpr
14258 = getDerived().TransformExpr(E->getSubExprAsWritten());
14259 if (SubExpr.isInvalid())
14260 return ExprError();
14261
14262 if (!getDerived().AlwaysRebuild() &&
14263 Type == E->getTypeInfoAsWritten() &&
14264 SubExpr.get() == E->getSubExpr())
14265 return E;
14266
14267 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14268 E->getLParenLoc(),
14269 SubExpr.get(),
14270 E->getRParenLoc(),
14271 E->isListInitialization());
14272}
14273
14274template<typename Derived>
14275ExprResult
14276TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14277 if (E->isTypeOperand()) {
14278 TypeSourceInfo *TInfo
14279 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14280 if (!TInfo)
14281 return ExprError();
14282
14283 if (!getDerived().AlwaysRebuild() &&
14284 TInfo == E->getTypeOperandSourceInfo())
14285 return E;
14286
14287 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14288 TInfo, E->getEndLoc());
14289 }
14290
14291 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14292 // type. We must not unilaterally enter unevaluated context here, as then
14293 // semantic processing can re-transform an already transformed operand.
14294 Expr *Op = E->getExprOperand();
14295 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14296 if (E->isGLValue())
14297 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14298 if (cast<CXXRecordDecl>(Val: RecordT->getDecl())->isPolymorphic())
14299 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14300
14301 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14302 Sema::ReuseLambdaContextDecl);
14303
14304 ExprResult SubExpr = getDerived().TransformExpr(Op);
14305 if (SubExpr.isInvalid())
14306 return ExprError();
14307
14308 if (!getDerived().AlwaysRebuild() &&
14309 SubExpr.get() == E->getExprOperand())
14310 return E;
14311
14312 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14313 SubExpr.get(), E->getEndLoc());
14314}
14315
14316template<typename Derived>
14317ExprResult
14318TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14319 if (E->isTypeOperand()) {
14320 TypeSourceInfo *TInfo
14321 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14322 if (!TInfo)
14323 return ExprError();
14324
14325 if (!getDerived().AlwaysRebuild() &&
14326 TInfo == E->getTypeOperandSourceInfo())
14327 return E;
14328
14329 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14330 TInfo, E->getEndLoc());
14331 }
14332
14333 EnterExpressionEvaluationContext Unevaluated(
14334 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14335
14336 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14337 if (SubExpr.isInvalid())
14338 return ExprError();
14339
14340 if (!getDerived().AlwaysRebuild() &&
14341 SubExpr.get() == E->getExprOperand())
14342 return E;
14343
14344 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14345 SubExpr.get(), E->getEndLoc());
14346}
14347
14348template<typename Derived>
14349ExprResult
14350TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14351 return E;
14352}
14353
14354template<typename Derived>
14355ExprResult
14356TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14357 CXXNullPtrLiteralExpr *E) {
14358 return E;
14359}
14360
14361template<typename Derived>
14362ExprResult
14363TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14364
14365 // In lambdas, the qualifiers of the type depends of where in
14366 // the call operator `this` appear, and we do not have a good way to
14367 // rebuild this information, so we transform the type.
14368 //
14369 // In other contexts, the type of `this` may be overrided
14370 // for type deduction, so we need to recompute it.
14371 //
14372 // Always recompute the type if we're in the body of a lambda, and
14373 // 'this' is dependent on a lambda's explicit object parameter.
14374 QualType T = [&]() {
14375 auto &S = getSema();
14376 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14377 return S.getCurrentThisType();
14378 if (S.getCurLambda())
14379 return getDerived().TransformType(E->getType());
14380 return S.getCurrentThisType();
14381 }();
14382
14383 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14384 // Mark it referenced in the new context regardless.
14385 // FIXME: this is a bit instantiation-specific.
14386 getSema().MarkThisReferenced(E);
14387 return E;
14388 }
14389
14390 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14391}
14392
14393template<typename Derived>
14394ExprResult
14395TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14396 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14397 if (SubExpr.isInvalid())
14398 return ExprError();
14399
14400 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14401
14402 if (!getDerived().AlwaysRebuild() &&
14403 SubExpr.get() == E->getSubExpr())
14404 return E;
14405
14406 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14407 E->isThrownVariableInScope());
14408}
14409
14410template<typename Derived>
14411ExprResult
14412TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14413 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14414 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14415 if (!Param)
14416 return ExprError();
14417
14418 ExprResult InitRes;
14419 if (E->hasRewrittenInit()) {
14420 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14421 if (InitRes.isInvalid())
14422 return ExprError();
14423 }
14424
14425 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14426 E->getUsedContext() == SemaRef.CurContext &&
14427 InitRes.get() == E->getRewrittenExpr())
14428 return E;
14429
14430 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14431 InitRes.get());
14432}
14433
14434template<typename Derived>
14435ExprResult
14436TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14437 FieldDecl *Field = cast_or_null<FieldDecl>(
14438 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14439 if (!Field)
14440 return ExprError();
14441
14442 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14443 E->getUsedContext() == SemaRef.CurContext)
14444 return E;
14445
14446 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14447}
14448
14449template<typename Derived>
14450ExprResult
14451TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14452 CXXScalarValueInitExpr *E) {
14453 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14454 if (!T)
14455 return ExprError();
14456
14457 if (!getDerived().AlwaysRebuild() &&
14458 T == E->getTypeSourceInfo())
14459 return E;
14460
14461 return getDerived().RebuildCXXScalarValueInitExpr(T,
14462 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14463 E->getRParenLoc());
14464}
14465
14466template<typename Derived>
14467ExprResult
14468TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14469 // Transform the type that we're allocating
14470 TypeSourceInfo *AllocTypeInfo =
14471 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14472 if (!AllocTypeInfo)
14473 return ExprError();
14474
14475 // Transform the size of the array we're allocating (if any).
14476 std::optional<Expr *> ArraySize;
14477 if (E->isArray()) {
14478 ExprResult NewArraySize;
14479 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14480 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14481 if (NewArraySize.isInvalid())
14482 return ExprError();
14483 }
14484 ArraySize = NewArraySize.get();
14485 }
14486
14487 // Transform the placement arguments (if any).
14488 bool ArgumentChanged = false;
14489 SmallVector<Expr*, 8> PlacementArgs;
14490 if (getDerived().TransformExprs(E->getPlacementArgs(),
14491 E->getNumPlacementArgs(), true,
14492 PlacementArgs, &ArgumentChanged))
14493 return ExprError();
14494
14495 // Transform the initializer (if any).
14496 Expr *OldInit = E->getInitializer();
14497 ExprResult NewInit;
14498 if (OldInit)
14499 NewInit = getDerived().TransformInitializer(OldInit, true);
14500 if (NewInit.isInvalid())
14501 return ExprError();
14502
14503 // Transform new operator and delete operator.
14504 FunctionDecl *OperatorNew = nullptr;
14505 if (E->getOperatorNew()) {
14506 OperatorNew = cast_or_null<FunctionDecl>(
14507 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14508 if (!OperatorNew)
14509 return ExprError();
14510 }
14511
14512 FunctionDecl *OperatorDelete = nullptr;
14513 if (E->getOperatorDelete()) {
14514 OperatorDelete = cast_or_null<FunctionDecl>(
14515 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14516 if (!OperatorDelete)
14517 return ExprError();
14518 }
14519
14520 if (!getDerived().AlwaysRebuild() &&
14521 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14522 ArraySize == E->getArraySize() &&
14523 NewInit.get() == OldInit &&
14524 OperatorNew == E->getOperatorNew() &&
14525 OperatorDelete == E->getOperatorDelete() &&
14526 !ArgumentChanged) {
14527 // Mark any declarations we need as referenced.
14528 // FIXME: instantiation-specific.
14529 if (OperatorNew)
14530 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14531 if (OperatorDelete)
14532 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14533
14534 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14535 QualType ElementType
14536 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14537 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14538 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: RecordT->getDecl());
14539 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
14540 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Destructor);
14541 }
14542 }
14543 }
14544
14545 return E;
14546 }
14547
14548 QualType AllocType = AllocTypeInfo->getType();
14549 if (!ArraySize) {
14550 // If no array size was specified, but the new expression was
14551 // instantiated with an array type (e.g., "new T" where T is
14552 // instantiated with "int[4]"), extract the outer bound from the
14553 // array type as our array size. We do this with constant and
14554 // dependently-sized array types.
14555 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14556 if (!ArrayT) {
14557 // Do nothing
14558 } else if (const ConstantArrayType *ConsArrayT
14559 = dyn_cast<ConstantArrayType>(Val: ArrayT)) {
14560 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14561 type: SemaRef.Context.getSizeType(),
14562 /*FIXME:*/ l: E->getBeginLoc());
14563 AllocType = ConsArrayT->getElementType();
14564 } else if (const DependentSizedArrayType *DepArrayT
14565 = dyn_cast<DependentSizedArrayType>(Val: ArrayT)) {
14566 if (DepArrayT->getSizeExpr()) {
14567 ArraySize = DepArrayT->getSizeExpr();
14568 AllocType = DepArrayT->getElementType();
14569 }
14570 }
14571 }
14572
14573 return getDerived().RebuildCXXNewExpr(
14574 E->getBeginLoc(), E->isGlobalNew(),
14575 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14576 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14577 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14578}
14579
14580template<typename Derived>
14581ExprResult
14582TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14583 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14584 if (Operand.isInvalid())
14585 return ExprError();
14586
14587 // Transform the delete operator, if known.
14588 FunctionDecl *OperatorDelete = nullptr;
14589 if (E->getOperatorDelete()) {
14590 OperatorDelete = cast_or_null<FunctionDecl>(
14591 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14592 if (!OperatorDelete)
14593 return ExprError();
14594 }
14595
14596 if (!getDerived().AlwaysRebuild() &&
14597 Operand.get() == E->getArgument() &&
14598 OperatorDelete == E->getOperatorDelete()) {
14599 // Mark any declarations we need as referenced.
14600 // FIXME: instantiation-specific.
14601 if (OperatorDelete)
14602 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14603
14604 if (!E->getArgument()->isTypeDependent()) {
14605 QualType Destroyed = SemaRef.Context.getBaseElementType(
14606 QT: E->getDestroyedType());
14607 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14608 CXXRecordDecl *Record = cast<CXXRecordDecl>(Val: DestroyedRec->getDecl());
14609 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
14610 Func: SemaRef.LookupDestructor(Class: Record));
14611 }
14612 }
14613
14614 return E;
14615 }
14616
14617 return getDerived().RebuildCXXDeleteExpr(
14618 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14619}
14620
14621template<typename Derived>
14622ExprResult
14623TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14624 CXXPseudoDestructorExpr *E) {
14625 ExprResult Base = getDerived().TransformExpr(E->getBase());
14626 if (Base.isInvalid())
14627 return ExprError();
14628
14629 ParsedType ObjectTypePtr;
14630 bool MayBePseudoDestructor = false;
14631 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14632 OpLoc: E->getOperatorLoc(),
14633 OpKind: E->isArrow()? tok::arrow : tok::period,
14634 ObjectType&: ObjectTypePtr,
14635 MayBePseudoDestructor);
14636 if (Base.isInvalid())
14637 return ExprError();
14638
14639 QualType ObjectType = ObjectTypePtr.get();
14640 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14641 if (QualifierLoc) {
14642 QualifierLoc
14643 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14644 if (!QualifierLoc)
14645 return ExprError();
14646 }
14647 CXXScopeSpec SS;
14648 SS.Adopt(Other: QualifierLoc);
14649
14650 PseudoDestructorTypeStorage Destroyed;
14651 if (E->getDestroyedTypeInfo()) {
14652 TypeSourceInfo *DestroyedTypeInfo
14653 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14654 ObjectType, nullptr, SS);
14655 if (!DestroyedTypeInfo)
14656 return ExprError();
14657 Destroyed = DestroyedTypeInfo;
14658 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14659 // We aren't likely to be able to resolve the identifier down to a type
14660 // now anyway, so just retain the identifier.
14661 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14662 E->getDestroyedTypeLoc());
14663 } else {
14664 // Look for a destructor known with the given name.
14665 ParsedType T = SemaRef.getDestructorName(
14666 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14667 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14668 if (!T)
14669 return ExprError();
14670
14671 Destroyed
14672 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14673 Loc: E->getDestroyedTypeLoc());
14674 }
14675
14676 TypeSourceInfo *ScopeTypeInfo = nullptr;
14677 if (E->getScopeTypeInfo()) {
14678 CXXScopeSpec EmptySS;
14679 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14680 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14681 if (!ScopeTypeInfo)
14682 return ExprError();
14683 }
14684
14685 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14686 E->getOperatorLoc(),
14687 E->isArrow(),
14688 SS,
14689 ScopeTypeInfo,
14690 E->getColonColonLoc(),
14691 E->getTildeLoc(),
14692 Destroyed);
14693}
14694
14695template <typename Derived>
14696bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14697 bool RequiresADL,
14698 LookupResult &R) {
14699 // Transform all the decls.
14700 bool AllEmptyPacks = true;
14701 for (auto *OldD : Old->decls()) {
14702 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14703 if (!InstD) {
14704 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14705 // This can happen because of dependent hiding.
14706 if (isa<UsingShadowDecl>(Val: OldD))
14707 continue;
14708 else {
14709 R.clear();
14710 return true;
14711 }
14712 }
14713
14714 // Expand using pack declarations.
14715 NamedDecl *SingleDecl = cast<NamedDecl>(Val: InstD);
14716 ArrayRef<NamedDecl*> Decls = SingleDecl;
14717 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: InstD))
14718 Decls = UPD->expansions();
14719
14720 // Expand using declarations.
14721 for (auto *D : Decls) {
14722 if (auto *UD = dyn_cast<UsingDecl>(Val: D)) {
14723 for (auto *SD : UD->shadows())
14724 R.addDecl(D: SD);
14725 } else {
14726 R.addDecl(D);
14727 }
14728 }
14729
14730 AllEmptyPacks &= Decls.empty();
14731 }
14732
14733 // C++ [temp.res]/8.4.2:
14734 // The program is ill-formed, no diagnostic required, if [...] lookup for
14735 // a name in the template definition found a using-declaration, but the
14736 // lookup in the corresponding scope in the instantiation odoes not find
14737 // any declarations because the using-declaration was a pack expansion and
14738 // the corresponding pack is empty
14739 if (AllEmptyPacks && !RequiresADL) {
14740 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14741 << isa<UnresolvedMemberExpr>(Val: Old) << Old->getName();
14742 return true;
14743 }
14744
14745 // Resolve a kind, but don't do any further analysis. If it's
14746 // ambiguous, the callee needs to deal with it.
14747 R.resolveKind();
14748
14749 if (Old->hasTemplateKeyword() && !R.empty()) {
14750 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14751 getSema().FilterAcceptableTemplateNames(R,
14752 /*AllowFunctionTemplates=*/true,
14753 /*AllowDependent=*/true);
14754 if (R.empty()) {
14755 // If a 'template' keyword was used, a lookup that finds only non-template
14756 // names is an error.
14757 getSema().Diag(R.getNameLoc(),
14758 diag::err_template_kw_refers_to_non_template)
14759 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14760 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14761 getSema().Diag(FoundDecl->getLocation(),
14762 diag::note_template_kw_refers_to_non_template)
14763 << R.getLookupName();
14764 return true;
14765 }
14766 }
14767
14768 return false;
14769}
14770
14771template <typename Derived>
14772ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14773 UnresolvedLookupExpr *Old) {
14774 return TransformUnresolvedLookupExpr(Old, /*IsAddressOfOperand=*/false);
14775}
14776
14777template <typename Derived>
14778ExprResult
14779TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14780 bool IsAddressOfOperand) {
14781 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14782 Sema::LookupOrdinaryName);
14783
14784 // Transform the declaration set.
14785 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
14786 return ExprError();
14787
14788 // Rebuild the nested-name qualifier, if present.
14789 CXXScopeSpec SS;
14790 if (Old->getQualifierLoc()) {
14791 NestedNameSpecifierLoc QualifierLoc
14792 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14793 if (!QualifierLoc)
14794 return ExprError();
14795
14796 SS.Adopt(Other: QualifierLoc);
14797 }
14798
14799 if (Old->getNamingClass()) {
14800 CXXRecordDecl *NamingClass
14801 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14802 Old->getNameLoc(),
14803 Old->getNamingClass()));
14804 if (!NamingClass) {
14805 R.clear();
14806 return ExprError();
14807 }
14808
14809 R.setNamingClass(NamingClass);
14810 }
14811
14812 // Rebuild the template arguments, if any.
14813 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14814 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14815 if (Old->hasExplicitTemplateArgs() &&
14816 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14817 Old->getNumTemplateArgs(),
14818 TransArgs)) {
14819 R.clear();
14820 return ExprError();
14821 }
14822
14823 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14824 // a non-static data member is named in an unevaluated operand, or when
14825 // a member is named in a dependent class scope function template explicit
14826 // specialization that is neither declared static nor with an explicit object
14827 // parameter.
14828 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14829 return SemaRef.BuildPossibleImplicitMemberExpr(
14830 SS, TemplateKWLoc, R,
14831 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14832 /*S=*/S: nullptr);
14833
14834 // If we have neither explicit template arguments, nor the template keyword,
14835 // it's a normal declaration name or member reference.
14836 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14837 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14838
14839 // If we have template arguments, then rebuild the template-id expression.
14840 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14841 Old->requiresADL(), &TransArgs);
14842}
14843
14844template<typename Derived>
14845ExprResult
14846TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14847 bool ArgChanged = false;
14848 SmallVector<TypeSourceInfo *, 4> Args;
14849 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14850 TypeSourceInfo *From = E->getArg(I);
14851 TypeLoc FromTL = From->getTypeLoc();
14852 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14853 TypeLocBuilder TLB;
14854 TLB.reserve(Requested: FromTL.getFullDataSize());
14855 QualType To = getDerived().TransformType(TLB, FromTL);
14856 if (To.isNull())
14857 return ExprError();
14858
14859 if (To == From->getType())
14860 Args.push_back(Elt: From);
14861 else {
14862 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14863 ArgChanged = true;
14864 }
14865 continue;
14866 }
14867
14868 ArgChanged = true;
14869
14870 // We have a pack expansion. Instantiate it.
14871 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14872 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14873 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14874 SemaRef.collectUnexpandedParameterPacks(TL: PatternTL, Unexpanded);
14875
14876 // Determine whether the set of unexpanded parameter packs can and should
14877 // be expanded.
14878 bool Expand = true;
14879 bool RetainExpansion = false;
14880 UnsignedOrNone OrigNumExpansions =
14881 ExpansionTL.getTypePtr()->getNumExpansions();
14882 UnsignedOrNone NumExpansions = OrigNumExpansions;
14883 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14884 PatternTL.getSourceRange(),
14885 Unexpanded,
14886 Expand, RetainExpansion,
14887 NumExpansions))
14888 return ExprError();
14889
14890 if (!Expand) {
14891 // The transform has determined that we should perform a simple
14892 // transformation on the pack expansion, producing another pack
14893 // expansion.
14894 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
14895
14896 TypeLocBuilder TLB;
14897 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14898
14899 QualType To = getDerived().TransformType(TLB, PatternTL);
14900 if (To.isNull())
14901 return ExprError();
14902
14903 To = getDerived().RebuildPackExpansionType(To,
14904 PatternTL.getSourceRange(),
14905 ExpansionTL.getEllipsisLoc(),
14906 NumExpansions);
14907 if (To.isNull())
14908 return ExprError();
14909
14910 PackExpansionTypeLoc ToExpansionTL
14911 = TLB.push<PackExpansionTypeLoc>(T: To);
14912 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14913 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14914 continue;
14915 }
14916
14917 // Expand the pack expansion by substituting for each argument in the
14918 // pack(s).
14919 for (unsigned I = 0; I != *NumExpansions; ++I) {
14920 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
14921 TypeLocBuilder TLB;
14922 TLB.reserve(Requested: PatternTL.getFullDataSize());
14923 QualType To = getDerived().TransformType(TLB, PatternTL);
14924 if (To.isNull())
14925 return ExprError();
14926
14927 if (To->containsUnexpandedParameterPack()) {
14928 To = getDerived().RebuildPackExpansionType(To,
14929 PatternTL.getSourceRange(),
14930 ExpansionTL.getEllipsisLoc(),
14931 NumExpansions);
14932 if (To.isNull())
14933 return ExprError();
14934
14935 PackExpansionTypeLoc ToExpansionTL
14936 = TLB.push<PackExpansionTypeLoc>(T: To);
14937 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14938 }
14939
14940 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14941 }
14942
14943 if (!RetainExpansion)
14944 continue;
14945
14946 // If we're supposed to retain a pack expansion, do so by temporarily
14947 // forgetting the partially-substituted parameter pack.
14948 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14949
14950 TypeLocBuilder TLB;
14951 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14952
14953 QualType To = getDerived().TransformType(TLB, PatternTL);
14954 if (To.isNull())
14955 return ExprError();
14956
14957 To = getDerived().RebuildPackExpansionType(To,
14958 PatternTL.getSourceRange(),
14959 ExpansionTL.getEllipsisLoc(),
14960 NumExpansions);
14961 if (To.isNull())
14962 return ExprError();
14963
14964 PackExpansionTypeLoc ToExpansionTL
14965 = TLB.push<PackExpansionTypeLoc>(T: To);
14966 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14967 Args.push_back(Elt: TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14968 }
14969
14970 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14971 return E;
14972
14973 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14974 E->getEndLoc());
14975}
14976
14977template<typename Derived>
14978ExprResult
14979TreeTransform<Derived>::TransformConceptSpecializationExpr(
14980 ConceptSpecializationExpr *E) {
14981 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14982 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14983 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14984 Old->NumTemplateArgs, TransArgs))
14985 return ExprError();
14986
14987 return getDerived().RebuildConceptSpecializationExpr(
14988 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14989 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14990 &TransArgs);
14991}
14992
14993template<typename Derived>
14994ExprResult
14995TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14996 SmallVector<ParmVarDecl*, 4> TransParams;
14997 SmallVector<QualType, 4> TransParamTypes;
14998 Sema::ExtParameterInfoBuilder ExtParamInfos;
14999
15000 // C++2a [expr.prim.req]p2
15001 // Expressions appearing within a requirement-body are unevaluated operands.
15002 EnterExpressionEvaluationContext Ctx(
15003 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15004 Sema::ReuseLambdaContextDecl);
15005
15006 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15007 C&: getSema().Context, DC: getSema().CurContext,
15008 StartLoc: E->getBody()->getBeginLoc());
15009
15010 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15011
15012 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15013 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15014 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15015
15016 for (ParmVarDecl *Param : TransParams)
15017 if (Param)
15018 Param->setDeclContext(Body);
15019
15020 // On failure to transform, TransformRequiresTypeParams returns an expression
15021 // in the event that the transformation of the type params failed in some way.
15022 // It is expected that this will result in a 'not satisfied' Requires clause
15023 // when instantiating.
15024 if (!TypeParamResult.isUnset())
15025 return TypeParamResult;
15026
15027 SmallVector<concepts::Requirement *, 4> TransReqs;
15028 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15029 TransReqs))
15030 return ExprError();
15031
15032 for (concepts::Requirement *Req : TransReqs) {
15033 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Val: Req)) {
15034 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15035 ER->getReturnTypeRequirement()
15036 .getTypeConstraintTemplateParameterList()->getParam(Idx: 0)
15037 ->setDeclContext(Body);
15038 }
15039 }
15040 }
15041
15042 return getDerived().RebuildRequiresExpr(
15043 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15044 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15045}
15046
15047template<typename Derived>
15048bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15049 ArrayRef<concepts::Requirement *> Reqs,
15050 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15051 for (concepts::Requirement *Req : Reqs) {
15052 concepts::Requirement *TransReq = nullptr;
15053 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Val: Req))
15054 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15055 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Val: Req))
15056 TransReq = getDerived().TransformExprRequirement(ExprReq);
15057 else
15058 TransReq = getDerived().TransformNestedRequirement(
15059 cast<concepts::NestedRequirement>(Val: Req));
15060 if (!TransReq)
15061 return true;
15062 Transformed.push_back(Elt: TransReq);
15063 }
15064 return false;
15065}
15066
15067template<typename Derived>
15068concepts::TypeRequirement *
15069TreeTransform<Derived>::TransformTypeRequirement(
15070 concepts::TypeRequirement *Req) {
15071 if (Req->isSubstitutionFailure()) {
15072 if (getDerived().AlwaysRebuild())
15073 return getDerived().RebuildTypeRequirement(
15074 Req->getSubstitutionDiagnostic());
15075 return Req;
15076 }
15077 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15078 if (!TransType)
15079 return nullptr;
15080 return getDerived().RebuildTypeRequirement(TransType);
15081}
15082
15083template<typename Derived>
15084concepts::ExprRequirement *
15085TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15086 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15087 if (Req->isExprSubstitutionFailure())
15088 TransExpr = Req->getExprSubstitutionDiagnostic();
15089 else {
15090 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15091 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15092 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15093 if (TransExprRes.isInvalid())
15094 return nullptr;
15095 TransExpr = TransExprRes.get();
15096 }
15097
15098 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15099 const auto &RetReq = Req->getReturnTypeRequirement();
15100 if (RetReq.isEmpty())
15101 TransRetReq.emplace();
15102 else if (RetReq.isSubstitutionFailure())
15103 TransRetReq.emplace(args: RetReq.getSubstitutionDiagnostic());
15104 else if (RetReq.isTypeConstraint()) {
15105 TemplateParameterList *OrigTPL =
15106 RetReq.getTypeConstraintTemplateParameterList();
15107 TemplateParameterList *TPL =
15108 getDerived().TransformTemplateParameterList(OrigTPL);
15109 if (!TPL)
15110 return nullptr;
15111 TransRetReq.emplace(args&: TPL);
15112 }
15113 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15114 if (Expr *E = dyn_cast<Expr *>(Val&: TransExpr))
15115 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15116 Req->getNoexceptLoc(),
15117 std::move(*TransRetReq));
15118 return getDerived().RebuildExprRequirement(
15119 cast<concepts::Requirement::SubstitutionDiagnostic *>(Val&: TransExpr),
15120 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15121}
15122
15123template<typename Derived>
15124concepts::NestedRequirement *
15125TreeTransform<Derived>::TransformNestedRequirement(
15126 concepts::NestedRequirement *Req) {
15127 if (Req->hasInvalidConstraint()) {
15128 if (getDerived().AlwaysRebuild())
15129 return getDerived().RebuildNestedRequirement(
15130 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15131 return Req;
15132 }
15133 ExprResult TransConstraint =
15134 getDerived().TransformExpr(Req->getConstraintExpr());
15135 if (TransConstraint.isInvalid())
15136 return nullptr;
15137 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15138}
15139
15140template<typename Derived>
15141ExprResult
15142TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15143 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15144 if (!T)
15145 return ExprError();
15146
15147 if (!getDerived().AlwaysRebuild() &&
15148 T == E->getQueriedTypeSourceInfo())
15149 return E;
15150
15151 ExprResult SubExpr;
15152 {
15153 EnterExpressionEvaluationContext Unevaluated(
15154 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15155 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15156 if (SubExpr.isInvalid())
15157 return ExprError();
15158 }
15159
15160 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15161 SubExpr.get(), E->getEndLoc());
15162}
15163
15164template<typename Derived>
15165ExprResult
15166TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15167 ExprResult SubExpr;
15168 {
15169 EnterExpressionEvaluationContext Unevaluated(
15170 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15171 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15172 if (SubExpr.isInvalid())
15173 return ExprError();
15174
15175 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15176 return E;
15177 }
15178
15179 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15180 SubExpr.get(), E->getEndLoc());
15181}
15182
15183template <typename Derived>
15184ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15185 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15186 TypeSourceInfo **RecoveryTSI) {
15187 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15188 DRE, AddrTaken, RecoveryTSI);
15189
15190 // Propagate both errors and recovered types, which return ExprEmpty.
15191 if (!NewDRE.isUsable())
15192 return NewDRE;
15193
15194 // We got an expr, wrap it up in parens.
15195 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15196 return PE;
15197 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15198 PE->getRParen());
15199}
15200
15201template <typename Derived>
15202ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15203 DependentScopeDeclRefExpr *E) {
15204 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/false,
15205 nullptr);
15206}
15207
15208template <typename Derived>
15209ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15210 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15211 TypeSourceInfo **RecoveryTSI) {
15212 assert(E->getQualifierLoc());
15213 NestedNameSpecifierLoc QualifierLoc =
15214 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15215 if (!QualifierLoc)
15216 return ExprError();
15217 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15218
15219 // TODO: If this is a conversion-function-id, verify that the
15220 // destination type name (if present) resolves the same way after
15221 // instantiation as it did in the local scope.
15222
15223 DeclarationNameInfo NameInfo =
15224 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15225 if (!NameInfo.getName())
15226 return ExprError();
15227
15228 if (!E->hasExplicitTemplateArgs()) {
15229 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15230 // Note: it is sufficient to compare the Name component of NameInfo:
15231 // if name has not changed, DNLoc has not changed either.
15232 NameInfo.getName() == E->getDeclName())
15233 return E;
15234
15235 return getDerived().RebuildDependentScopeDeclRefExpr(
15236 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15237 IsAddressOfOperand, RecoveryTSI);
15238 }
15239
15240 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15241 if (getDerived().TransformTemplateArguments(
15242 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15243 return ExprError();
15244
15245 return getDerived().RebuildDependentScopeDeclRefExpr(
15246 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15247 RecoveryTSI);
15248}
15249
15250template<typename Derived>
15251ExprResult
15252TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15253 // CXXConstructExprs other than for list-initialization and
15254 // CXXTemporaryObjectExpr are always implicit, so when we have
15255 // a 1-argument construction we just transform that argument.
15256 if (getDerived().AllowSkippingCXXConstructExpr() &&
15257 ((E->getNumArgs() == 1 ||
15258 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15259 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15260 !E->isListInitialization()))
15261 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15262 /*DirectInit*/ false);
15263
15264 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15265
15266 QualType T = getDerived().TransformType(E->getType());
15267 if (T.isNull())
15268 return ExprError();
15269
15270 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15271 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15272 if (!Constructor)
15273 return ExprError();
15274
15275 bool ArgumentChanged = false;
15276 SmallVector<Expr*, 8> Args;
15277 {
15278 EnterExpressionEvaluationContext Context(
15279 getSema(), EnterExpressionEvaluationContext::InitList,
15280 E->isListInitialization());
15281 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15282 &ArgumentChanged))
15283 return ExprError();
15284 }
15285
15286 if (!getDerived().AlwaysRebuild() &&
15287 T == E->getType() &&
15288 Constructor == E->getConstructor() &&
15289 !ArgumentChanged) {
15290 // Mark the constructor as referenced.
15291 // FIXME: Instantiation-specific
15292 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15293 return E;
15294 }
15295
15296 return getDerived().RebuildCXXConstructExpr(
15297 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15298 E->hadMultipleCandidates(), E->isListInitialization(),
15299 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15300 E->getConstructionKind(), E->getParenOrBraceRange());
15301}
15302
15303template<typename Derived>
15304ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15305 CXXInheritedCtorInitExpr *E) {
15306 QualType T = getDerived().TransformType(E->getType());
15307 if (T.isNull())
15308 return ExprError();
15309
15310 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15311 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15312 if (!Constructor)
15313 return ExprError();
15314
15315 if (!getDerived().AlwaysRebuild() &&
15316 T == E->getType() &&
15317 Constructor == E->getConstructor()) {
15318 // Mark the constructor as referenced.
15319 // FIXME: Instantiation-specific
15320 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15321 return E;
15322 }
15323
15324 return getDerived().RebuildCXXInheritedCtorInitExpr(
15325 T, E->getLocation(), Constructor,
15326 E->constructsVBase(), E->inheritedFromVBase());
15327}
15328
15329/// Transform a C++ temporary-binding expression.
15330///
15331/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15332/// transform the subexpression and return that.
15333template<typename Derived>
15334ExprResult
15335TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15336 if (auto *Dtor = E->getTemporary()->getDestructor())
15337 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(),
15338 Func: const_cast<CXXDestructorDecl *>(Dtor));
15339 return getDerived().TransformExpr(E->getSubExpr());
15340}
15341
15342/// Transform a C++ expression that contains cleanups that should
15343/// be run after the expression is evaluated.
15344///
15345/// Since ExprWithCleanups nodes are implicitly generated, we
15346/// just transform the subexpression and return that.
15347template<typename Derived>
15348ExprResult
15349TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15350 return getDerived().TransformExpr(E->getSubExpr());
15351}
15352
15353template<typename Derived>
15354ExprResult
15355TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15356 CXXTemporaryObjectExpr *E) {
15357 TypeSourceInfo *T =
15358 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15359 if (!T)
15360 return ExprError();
15361
15362 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15363 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15364 if (!Constructor)
15365 return ExprError();
15366
15367 bool ArgumentChanged = false;
15368 SmallVector<Expr*, 8> Args;
15369 Args.reserve(N: E->getNumArgs());
15370 {
15371 EnterExpressionEvaluationContext Context(
15372 getSema(), EnterExpressionEvaluationContext::InitList,
15373 E->isListInitialization());
15374 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15375 ArgChanged: &ArgumentChanged))
15376 return ExprError();
15377
15378 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15379 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15380 if (Res.isInvalid())
15381 return ExprError();
15382 Args = {Res.get()};
15383 }
15384 }
15385
15386 if (!getDerived().AlwaysRebuild() &&
15387 T == E->getTypeSourceInfo() &&
15388 Constructor == E->getConstructor() &&
15389 !ArgumentChanged) {
15390 // FIXME: Instantiation-specific
15391 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: Constructor);
15392 return SemaRef.MaybeBindToTemporary(E);
15393 }
15394
15395 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15396 return getDerived().RebuildCXXTemporaryObjectExpr(
15397 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15398}
15399
15400template<typename Derived>
15401ExprResult
15402TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15403 // Transform any init-capture expressions before entering the scope of the
15404 // lambda body, because they are not semantically within that scope.
15405 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15406 struct TransformedInitCapture {
15407 // The location of the ... if the result is retaining a pack expansion.
15408 SourceLocation EllipsisLoc;
15409 // Zero or more expansions of the init-capture.
15410 SmallVector<InitCaptureInfoTy, 4> Expansions;
15411 };
15412 SmallVector<TransformedInitCapture, 4> InitCaptures;
15413 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15414 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15415 CEnd = E->capture_end();
15416 C != CEnd; ++C) {
15417 if (!E->isInitCapture(Capture: C))
15418 continue;
15419
15420 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15421 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15422
15423 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15424 UnsignedOrNone NumExpansions) {
15425 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15426 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15427
15428 if (NewExprInitResult.isInvalid()) {
15429 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15430 return;
15431 }
15432 Expr *NewExprInit = NewExprInitResult.get();
15433
15434 QualType NewInitCaptureType =
15435 getSema().buildLambdaInitCaptureInitialization(
15436 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15437 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15438 cast<VarDecl>(Val: C->getCapturedVar())->getInitStyle() !=
15439 VarDecl::CInit,
15440 NewExprInit);
15441 Result.Expansions.push_back(
15442 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15443 };
15444
15445 // If this is an init-capture pack, consider expanding the pack now.
15446 if (OldVD->isParameterPack()) {
15447 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15448 ->getTypeLoc()
15449 .castAs<PackExpansionTypeLoc>();
15450 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15451 SemaRef.collectUnexpandedParameterPacks(E: OldVD->getInit(), Unexpanded);
15452
15453 // Determine whether the set of unexpanded parameter packs can and should
15454 // be expanded.
15455 bool Expand = true;
15456 bool RetainExpansion = false;
15457 UnsignedOrNone OrigNumExpansions =
15458 ExpansionTL.getTypePtr()->getNumExpansions();
15459 UnsignedOrNone NumExpansions = OrigNumExpansions;
15460 if (getDerived().TryExpandParameterPacks(
15461 ExpansionTL.getEllipsisLoc(),
15462 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15463 RetainExpansion, NumExpansions))
15464 return ExprError();
15465 assert(!RetainExpansion && "Should not need to retain expansion after a "
15466 "capture since it cannot be extended");
15467 if (Expand) {
15468 for (unsigned I = 0; I != *NumExpansions; ++I) {
15469 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15470 SubstInitCapture(SourceLocation(), std::nullopt);
15471 }
15472 } else {
15473 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15474 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15475 }
15476 } else {
15477 SubstInitCapture(SourceLocation(), std::nullopt);
15478 }
15479 }
15480
15481 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15482 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15483
15484 // Create the local class that will describe the lambda.
15485
15486 // FIXME: DependencyKind below is wrong when substituting inside a templated
15487 // context that isn't a DeclContext (such as a variable template), or when
15488 // substituting an unevaluated lambda inside of a function's parameter's type
15489 // - as parameter types are not instantiated from within a function's DC. We
15490 // use evaluation contexts to distinguish the function parameter case.
15491 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15492 CXXRecordDecl::LDK_Unknown;
15493 DeclContext *DC = getSema().CurContext;
15494 // A RequiresExprBodyDecl is not interesting for dependencies.
15495 // For the following case,
15496 //
15497 // template <typename>
15498 // concept C = requires { [] {}; };
15499 //
15500 // template <class F>
15501 // struct Widget;
15502 //
15503 // template <C F>
15504 // struct Widget<F> {};
15505 //
15506 // While we are substituting Widget<F>, the parent of DC would be
15507 // the template specialization itself. Thus, the lambda expression
15508 // will be deemed as dependent even if there are no dependent template
15509 // arguments.
15510 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15511 while (DC->isRequiresExprBody())
15512 DC = DC->getParent();
15513 if ((getSema().isUnevaluatedContext() ||
15514 getSema().isConstantEvaluatedContext()) &&
15515 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15516 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15517
15518 CXXRecordDecl *OldClass = E->getLambdaClass();
15519 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15520 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15521 E->getCaptureDefault());
15522 getDerived().transformedLocalDecl(OldClass, {Class});
15523
15524 CXXMethodDecl *NewCallOperator =
15525 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15526
15527 // Enter the scope of the lambda.
15528 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15529 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15530 E->hasExplicitParameters(), E->isMutable());
15531
15532 // Introduce the context of the call operator.
15533 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15534 /*NewThisContext*/false);
15535
15536 bool Invalid = false;
15537
15538 // Transform captures.
15539 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15540 CEnd = E->capture_end();
15541 C != CEnd; ++C) {
15542 // When we hit the first implicit capture, tell Sema that we've finished
15543 // the list of explicit captures.
15544 if (C->isImplicit())
15545 break;
15546
15547 // Capturing 'this' is trivial.
15548 if (C->capturesThis()) {
15549 // If this is a lambda that is part of a default member initialiser
15550 // and which we're instantiating outside the class that 'this' is
15551 // supposed to refer to, adjust the type of 'this' accordingly.
15552 //
15553 // Otherwise, leave the type of 'this' as-is.
15554 Sema::CXXThisScopeRAII ThisScope(
15555 getSema(),
15556 dyn_cast_if_present<CXXRecordDecl>(
15557 getSema().getFunctionLevelDeclContext()),
15558 Qualifiers());
15559 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15560 /*BuildAndDiagnose*/ true, nullptr,
15561 C->getCaptureKind() == LCK_StarThis);
15562 continue;
15563 }
15564 // Captured expression will be recaptured during captured variables
15565 // rebuilding.
15566 if (C->capturesVLAType())
15567 continue;
15568
15569 // Rebuild init-captures, including the implied field declaration.
15570 if (E->isInitCapture(Capture: C)) {
15571 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15572
15573 auto *OldVD = cast<VarDecl>(Val: C->getCapturedVar());
15574 llvm::SmallVector<Decl*, 4> NewVDs;
15575
15576 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15577 ExprResult Init = Info.first;
15578 QualType InitQualType = Info.second;
15579 if (Init.isInvalid() || InitQualType.isNull()) {
15580 Invalid = true;
15581 break;
15582 }
15583 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15584 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15585 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15586 getSema().CurContext);
15587 if (!NewVD) {
15588 Invalid = true;
15589 break;
15590 }
15591 NewVDs.push_back(Elt: NewVD);
15592 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15593 // Cases we want to tackle:
15594 // ([C(Pack)] {}, ...)
15595 // But rule out cases e.g.
15596 // [...C = Pack()] {}
15597 if (NewC.EllipsisLoc.isInvalid())
15598 LSI->ContainsUnexpandedParameterPack |=
15599 Init.get()->containsUnexpandedParameterPack();
15600 }
15601
15602 if (Invalid)
15603 break;
15604
15605 getDerived().transformedLocalDecl(OldVD, NewVDs);
15606 continue;
15607 }
15608
15609 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15610
15611 // Determine the capture kind for Sema.
15612 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15613 : C->getCaptureKind() == LCK_ByCopy
15614 ? TryCaptureKind::ExplicitByVal
15615 : TryCaptureKind::ExplicitByRef;
15616 SourceLocation EllipsisLoc;
15617 if (C->isPackExpansion()) {
15618 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15619 bool ShouldExpand = false;
15620 bool RetainExpansion = false;
15621 UnsignedOrNone NumExpansions = std::nullopt;
15622 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15623 C->getLocation(),
15624 Unexpanded,
15625 ShouldExpand, RetainExpansion,
15626 NumExpansions)) {
15627 Invalid = true;
15628 continue;
15629 }
15630
15631 if (ShouldExpand) {
15632 // The transform has determined that we should perform an expansion;
15633 // transform and capture each of the arguments.
15634 // expansion of the pattern. Do so.
15635 auto *Pack = cast<ValueDecl>(Val: C->getCapturedVar());
15636 for (unsigned I = 0; I != *NumExpansions; ++I) {
15637 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15638 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15639 getDerived().TransformDecl(C->getLocation(), Pack));
15640 if (!CapturedVar) {
15641 Invalid = true;
15642 continue;
15643 }
15644
15645 // Capture the transformed variable.
15646 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15647 }
15648
15649 // FIXME: Retain a pack expansion if RetainExpansion is true.
15650
15651 continue;
15652 }
15653
15654 EllipsisLoc = C->getEllipsisLoc();
15655 }
15656
15657 // Transform the captured variable.
15658 auto *CapturedVar = cast_or_null<ValueDecl>(
15659 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15660 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15661 Invalid = true;
15662 continue;
15663 }
15664
15665 // This is not an init-capture; however it contains an unexpanded pack e.g.
15666 // ([Pack] {}(), ...)
15667 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15668 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15669
15670 // Capture the transformed variable.
15671 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15672 EllipsisLoc);
15673 }
15674 getSema().finishLambdaExplicitCaptures(LSI);
15675
15676 // Transform the template parameters, and add them to the current
15677 // instantiation scope. The null case is handled correctly.
15678 auto TPL = getDerived().TransformTemplateParameterList(
15679 E->getTemplateParameterList());
15680 LSI->GLTemplateParameterList = TPL;
15681 if (TPL) {
15682 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15683 TPL);
15684 LSI->ContainsUnexpandedParameterPack |=
15685 TPL->containsUnexpandedParameterPack();
15686 }
15687
15688 TypeLocBuilder NewCallOpTLBuilder;
15689 TypeLoc OldCallOpTypeLoc =
15690 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15691 QualType NewCallOpType =
15692 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15693 if (NewCallOpType.isNull())
15694 return ExprError();
15695 LSI->ContainsUnexpandedParameterPack |=
15696 NewCallOpType->containsUnexpandedParameterPack();
15697 TypeSourceInfo *NewCallOpTSI =
15698 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
15699
15700 // The type may be an AttributedType or some other kind of sugar;
15701 // get the actual underlying FunctionProtoType.
15702 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15703 assert(FPTL && "Not a FunctionProtoType?");
15704
15705 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15706 if (!TRC.ArgPackSubstIndex)
15707 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15708
15709 getSema().CompleteLambdaCallOperator(
15710 NewCallOperator, E->getCallOperator()->getLocation(),
15711 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15712 E->getCallOperator()->getConstexprKind(),
15713 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15714 E->hasExplicitResultType());
15715
15716 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15717 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15718
15719 {
15720 // Number the lambda for linkage purposes if necessary.
15721 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15722
15723 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15724 if (getDerived().ReplacingOriginal()) {
15725 Numbering = OldClass->getLambdaNumbering();
15726 }
15727
15728 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15729 }
15730
15731 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15732 // evaluation context even if we're not transforming the function body.
15733 getSema().PushExpressionEvaluationContextForFunction(
15734 Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
15735 E->getCallOperator());
15736
15737 Sema::CodeSynthesisContext C;
15738 C.Kind = clang::Sema::CodeSynthesisContext::LambdaExpressionSubstitution;
15739 C.PointOfInstantiation = E->getBody()->getBeginLoc();
15740 getSema().pushCodeSynthesisContext(C);
15741
15742 // Instantiate the body of the lambda expression.
15743 StmtResult Body =
15744 Invalid ? StmtError() : getDerived().TransformLambdaBody(E, E->getBody());
15745
15746 getSema().popCodeSynthesisContext();
15747
15748 // ActOnLambda* will pop the function scope for us.
15749 FuncScopeCleanup.disable();
15750
15751 if (Body.isInvalid()) {
15752 SavedContext.pop();
15753 getSema().ActOnLambdaError(E->getBeginLoc(), /*CurScope=*/nullptr,
15754 /*IsInstantiation=*/true);
15755 return ExprError();
15756 }
15757
15758 // Copy the LSI before ActOnFinishFunctionBody removes it.
15759 // FIXME: This is dumb. Store the lambda information somewhere that outlives
15760 // the call operator.
15761 auto LSICopy = *LSI;
15762 getSema().ActOnFinishFunctionBody(NewCallOperator, Body.get(),
15763 /*IsInstantiation*/ true);
15764 SavedContext.pop();
15765
15766 // Recompute the dependency of the lambda so that we can defer the lambda call
15767 // construction until after we have all the necessary template arguments. For
15768 // example, given
15769 //
15770 // template <class> struct S {
15771 // template <class U>
15772 // using Type = decltype([](U){}(42.0));
15773 // };
15774 // void foo() {
15775 // using T = S<int>::Type<float>;
15776 // ^~~~~~
15777 // }
15778 //
15779 // We would end up here from instantiating S<int> when ensuring its
15780 // completeness. That would transform the lambda call expression regardless of
15781 // the absence of the corresponding argument for U.
15782 //
15783 // Going ahead with unsubstituted type U makes things worse: we would soon
15784 // compare the argument type (which is float) against the parameter U
15785 // somewhere in Sema::BuildCallExpr. Then we would quickly run into a bogus
15786 // error suggesting unmatched types 'U' and 'float'!
15787 //
15788 // That said, everything will be fine if we defer that semantic checking.
15789 // Fortunately, we have such a mechanism that bypasses it if the CallExpr is
15790 // dependent. Since the CallExpr's dependency boils down to the lambda's
15791 // dependency in this case, we can harness that by recomputing the dependency
15792 // from the instantiation arguments.
15793 //
15794 // FIXME: Creating the type of a lambda requires us to have a dependency
15795 // value, which happens before its substitution. We update its dependency
15796 // *after* the substitution in case we can't decide the dependency
15797 // so early, e.g. because we want to see if any of the *substituted*
15798 // parameters are dependent.
15799 DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
15800 Class->setLambdaDependencyKind(DependencyKind);
15801 // Clean up the type cache created previously. Then, we re-create a type for
15802 // such Decl with the new DependencyKind.
15803 Class->setTypeForDecl(nullptr);
15804 getSema().Context.getTypeDeclType(Class);
15805
15806 return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
15807 Body.get()->getEndLoc(), &LSICopy);
15808}
15809
15810template<typename Derived>
15811StmtResult
15812TreeTransform<Derived>::TransformLambdaBody(LambdaExpr *E, Stmt *S) {
15813 return TransformStmt(S);
15814}
15815
15816template<typename Derived>
15817StmtResult
15818TreeTransform<Derived>::SkipLambdaBody(LambdaExpr *E, Stmt *S) {
15819 // Transform captures.
15820 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15821 CEnd = E->capture_end();
15822 C != CEnd; ++C) {
15823 // When we hit the first implicit capture, tell Sema that we've finished
15824 // the list of explicit captures.
15825 if (!C->isImplicit())
15826 continue;
15827
15828 // Capturing 'this' is trivial.
15829 if (C->capturesThis()) {
15830 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15831 /*BuildAndDiagnose*/ true, nullptr,
15832 C->getCaptureKind() == LCK_StarThis);
15833 continue;
15834 }
15835 // Captured expression will be recaptured during captured variables
15836 // rebuilding.
15837 if (C->capturesVLAType())
15838 continue;
15839
15840 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15841 assert(!E->isInitCapture(C) && "implicit init-capture?");
15842
15843 // Transform the captured variable.
15844 VarDecl *CapturedVar = cast_or_null<VarDecl>(
15845 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15846 if (!CapturedVar || CapturedVar->isInvalidDecl())
15847 return StmtError();
15848
15849 // Capture the transformed variable.
15850 getSema().tryCaptureVariable(CapturedVar, C->getLocation());
15851 }
15852
15853 return S;
15854}
15855
15856template<typename Derived>
15857ExprResult
15858TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
15859 CXXUnresolvedConstructExpr *E) {
15860 TypeSourceInfo *T =
15861 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15862 if (!T)
15863 return ExprError();
15864
15865 bool ArgumentChanged = false;
15866 SmallVector<Expr*, 8> Args;
15867 Args.reserve(N: E->getNumArgs());
15868 {
15869 EnterExpressionEvaluationContext Context(
15870 getSema(), EnterExpressionEvaluationContext::InitList,
15871 E->isListInitialization());
15872 if (getDerived().TransformExprs(E->arg_begin(), E->getNumArgs(), true, Args,
15873 &ArgumentChanged))
15874 return ExprError();
15875 }
15876
15877 if (!getDerived().AlwaysRebuild() &&
15878 T == E->getTypeSourceInfo() &&
15879 !ArgumentChanged)
15880 return E;
15881
15882 // FIXME: we're faking the locations of the commas
15883 return getDerived().RebuildCXXUnresolvedConstructExpr(
15884 T, E->getLParenLoc(), Args, E->getRParenLoc(), E->isListInitialization());
15885}
15886
15887template<typename Derived>
15888ExprResult
15889TreeTransform<Derived>::TransformCXXDependentScopeMemberExpr(
15890 CXXDependentScopeMemberExpr *E) {
15891 // Transform the base of the expression.
15892 ExprResult Base((Expr*) nullptr);
15893 Expr *OldBase;
15894 QualType BaseType;
15895 QualType ObjectType;
15896 if (!E->isImplicitAccess()) {
15897 OldBase = E->getBase();
15898 Base = getDerived().TransformExpr(OldBase);
15899 if (Base.isInvalid())
15900 return ExprError();
15901
15902 // Start the member reference and compute the object's type.
15903 ParsedType ObjectTy;
15904 bool MayBePseudoDestructor = false;
15905 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
15906 OpLoc: E->getOperatorLoc(),
15907 OpKind: E->isArrow()? tok::arrow : tok::period,
15908 ObjectType&: ObjectTy,
15909 MayBePseudoDestructor);
15910 if (Base.isInvalid())
15911 return ExprError();
15912
15913 ObjectType = ObjectTy.get();
15914 BaseType = ((Expr*) Base.get())->getType();
15915 } else {
15916 OldBase = nullptr;
15917 BaseType = getDerived().TransformType(E->getBaseType());
15918 ObjectType = BaseType->castAs<PointerType>()->getPointeeType();
15919 }
15920
15921 // Transform the first part of the nested-name-specifier that qualifies
15922 // the member name.
15923 NamedDecl *FirstQualifierInScope
15924 = getDerived().TransformFirstQualifierInScope(
15925 E->getFirstQualifierFoundInScope(),
15926 E->getQualifierLoc().getBeginLoc());
15927
15928 NestedNameSpecifierLoc QualifierLoc;
15929 if (E->getQualifier()) {
15930 QualifierLoc
15931 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc(),
15932 ObjectType,
15933 FirstQualifierInScope);
15934 if (!QualifierLoc)
15935 return ExprError();
15936 }
15937
15938 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15939
15940 // TODO: If this is a conversion-function-id, verify that the
15941 // destination type name (if present) resolves the same way after
15942 // instantiation as it did in the local scope.
15943
15944 DeclarationNameInfo NameInfo
15945 = getDerived().TransformDeclarationNameInfo(E->getMemberNameInfo());
15946 if (!NameInfo.getName())
15947 return ExprError();
15948
15949 if (!E->hasExplicitTemplateArgs()) {
15950 // This is a reference to a member without an explicitly-specified
15951 // template argument list. Optimize for this common case.
15952 if (!getDerived().AlwaysRebuild() &&
15953 Base.get() == OldBase &&
15954 BaseType == E->getBaseType() &&
15955 QualifierLoc == E->getQualifierLoc() &&
15956 NameInfo.getName() == E->getMember() &&
15957 FirstQualifierInScope == E->getFirstQualifierFoundInScope())
15958 return E;
15959
15960 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15961 BaseType,
15962 E->isArrow(),
15963 E->getOperatorLoc(),
15964 QualifierLoc,
15965 TemplateKWLoc,
15966 FirstQualifierInScope,
15967 NameInfo,
15968 /*TemplateArgs*/nullptr);
15969 }
15970
15971 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15972 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
15973 E->getNumTemplateArgs(),
15974 TransArgs))
15975 return ExprError();
15976
15977 return getDerived().RebuildCXXDependentScopeMemberExpr(Base.get(),
15978 BaseType,
15979 E->isArrow(),
15980 E->getOperatorLoc(),
15981 QualifierLoc,
15982 TemplateKWLoc,
15983 FirstQualifierInScope,
15984 NameInfo,
15985 &TransArgs);
15986}
15987
15988template <typename Derived>
15989ExprResult TreeTransform<Derived>::TransformUnresolvedMemberExpr(
15990 UnresolvedMemberExpr *Old) {
15991 // Transform the base of the expression.
15992 ExprResult Base((Expr *)nullptr);
15993 QualType BaseType;
15994 if (!Old->isImplicitAccess()) {
15995 Base = getDerived().TransformExpr(Old->getBase());
15996 if (Base.isInvalid())
15997 return ExprError();
15998 Base =
15999 getSema().PerformMemberExprBaseConversion(Base.get(), Old->isArrow());
16000 if (Base.isInvalid())
16001 return ExprError();
16002 BaseType = Base.get()->getType();
16003 } else {
16004 BaseType = getDerived().TransformType(Old->getBaseType());
16005 }
16006
16007 NestedNameSpecifierLoc QualifierLoc;
16008 if (Old->getQualifierLoc()) {
16009 QualifierLoc =
16010 getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
16011 if (!QualifierLoc)
16012 return ExprError();
16013 }
16014
16015 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
16016
16017 LookupResult R(SemaRef, Old->getMemberNameInfo(), Sema::LookupOrdinaryName);
16018
16019 // Transform the declaration set.
16020 if (TransformOverloadExprDecls(Old, /*RequiresADL*/ RequiresADL: false, R))
16021 return ExprError();
16022
16023 // Determine the naming class.
16024 if (Old->getNamingClass()) {
16025 CXXRecordDecl *NamingClass = cast_or_null<CXXRecordDecl>(
16026 getDerived().TransformDecl(Old->getMemberLoc(), Old->getNamingClass()));
16027 if (!NamingClass)
16028 return ExprError();
16029
16030 R.setNamingClass(NamingClass);
16031 }
16032
16033 TemplateArgumentListInfo TransArgs;
16034 if (Old->hasExplicitTemplateArgs()) {
16035 TransArgs.setLAngleLoc(Old->getLAngleLoc());
16036 TransArgs.setRAngleLoc(Old->getRAngleLoc());
16037 if (getDerived().TransformTemplateArguments(
16038 Old->getTemplateArgs(), Old->getNumTemplateArgs(), TransArgs))
16039 return ExprError();
16040 }
16041
16042 // FIXME: to do this check properly, we will need to preserve the
16043 // first-qualifier-in-scope here, just in case we had a dependent
16044 // base (and therefore couldn't do the check) and a
16045 // nested-name-qualifier (and therefore could do the lookup).
16046 NamedDecl *FirstQualifierInScope = nullptr;
16047
16048 return getDerived().RebuildUnresolvedMemberExpr(
16049 Base.get(), BaseType, Old->getOperatorLoc(), Old->isArrow(), QualifierLoc,
16050 TemplateKWLoc, FirstQualifierInScope, R,
16051 (Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr));
16052}
16053
16054template<typename Derived>
16055ExprResult
16056TreeTransform<Derived>::TransformCXXNoexceptExpr(CXXNoexceptExpr *E) {
16057 EnterExpressionEvaluationContext Unevaluated(
16058 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
16059 ExprResult SubExpr = getDerived().TransformExpr(E->getOperand());
16060 if (SubExpr.isInvalid())
16061 return ExprError();
16062
16063 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getOperand())
16064 return E;
16065
16066 return getDerived().RebuildCXXNoexceptExpr(E->getSourceRange(),SubExpr.get());
16067}
16068
16069template<typename Derived>
16070ExprResult
16071TreeTransform<Derived>::TransformPackExpansionExpr(PackExpansionExpr *E) {
16072 ExprResult Pattern = getDerived().TransformExpr(E->getPattern());
16073 if (Pattern.isInvalid())
16074 return ExprError();
16075
16076 if (!getDerived().AlwaysRebuild() && Pattern.get() == E->getPattern())
16077 return E;
16078
16079 return getDerived().RebuildPackExpansion(Pattern.get(), E->getEllipsisLoc(),
16080 E->getNumExpansions());
16081}
16082
16083template <typename Derived>
16084UnsignedOrNone TreeTransform<Derived>::ComputeSizeOfPackExprWithoutSubstitution(
16085 ArrayRef<TemplateArgument> PackArgs) {
16086 UnsignedOrNone Result = 0u;
16087 for (const TemplateArgument &Arg : PackArgs) {
16088 if (!Arg.isPackExpansion()) {
16089 Result = *Result + 1;
16090 continue;
16091 }
16092
16093 TemplateArgumentLoc ArgLoc;
16094 InventTemplateArgumentLoc(Arg, Output&: ArgLoc);
16095
16096 // Find the pattern of the pack expansion.
16097 SourceLocation Ellipsis;
16098 UnsignedOrNone OrigNumExpansions = std::nullopt;
16099 TemplateArgumentLoc Pattern =
16100 getSema().getTemplateArgumentPackExpansionPattern(ArgLoc, Ellipsis,
16101 OrigNumExpansions);
16102
16103 // Substitute under the pack expansion. Do not expand the pack (yet).
16104 TemplateArgumentLoc OutPattern;
16105 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16106 if (getDerived().TransformTemplateArgument(Pattern, OutPattern,
16107 /*Uneval*/ true))
16108 return 1u;
16109
16110 // See if we can determine the number of arguments from the result.
16111 UnsignedOrNone NumExpansions =
16112 getSema().getFullyPackExpandedSize(OutPattern.getArgument());
16113 if (!NumExpansions) {
16114 // No: we must be in an alias template expansion, and we're going to
16115 // need to actually expand the packs.
16116 Result = std::nullopt;
16117 break;
16118 }
16119
16120 Result = *Result + *NumExpansions;
16121 }
16122 return Result;
16123}
16124
16125template<typename Derived>
16126ExprResult
16127TreeTransform<Derived>::TransformSizeOfPackExpr(SizeOfPackExpr *E) {
16128 // If E is not value-dependent, then nothing will change when we transform it.
16129 // Note: This is an instantiation-centric view.
16130 if (!E->isValueDependent())
16131 return E;
16132
16133 EnterExpressionEvaluationContext Unevaluated(
16134 getSema(), Sema::ExpressionEvaluationContext::Unevaluated);
16135
16136 ArrayRef<TemplateArgument> PackArgs;
16137 TemplateArgument ArgStorage;
16138
16139 // Find the argument list to transform.
16140 if (E->isPartiallySubstituted()) {
16141 PackArgs = E->getPartialArguments();
16142 } else if (E->isValueDependent()) {
16143 UnexpandedParameterPack Unexpanded(E->getPack(), E->getPackLoc());
16144 bool ShouldExpand = false;
16145 bool RetainExpansion = false;
16146 UnsignedOrNone NumExpansions = std::nullopt;
16147 if (getDerived().TryExpandParameterPacks(E->getOperatorLoc(), E->getPackLoc(),
16148 Unexpanded,
16149 ShouldExpand, RetainExpansion,
16150 NumExpansions))
16151 return ExprError();
16152
16153 // If we need to expand the pack, build a template argument from it and
16154 // expand that.
16155 if (ShouldExpand) {
16156 auto *Pack = E->getPack();
16157 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: Pack)) {
16158 ArgStorage = getSema().Context.getPackExpansionType(
16159 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16160 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Val: Pack)) {
16161 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16162 } else {
16163 auto *VD = cast<ValueDecl>(Val: Pack);
16164 ExprResult DRE = getSema().BuildDeclRefExpr(
16165 VD, VD->getType().getNonLValueExprType(Context: getSema().Context),
16166 VD->getType()->isReferenceType() ? VK_LValue : VK_PRValue,
16167 E->getPackLoc());
16168 if (DRE.isInvalid())
16169 return ExprError();
16170 ArgStorage = TemplateArgument(
16171 new (getSema().Context)
16172 PackExpansionExpr(DRE.get(), E->getPackLoc(), std::nullopt),
16173 /*IsCanonical=*/false);
16174 }
16175 PackArgs = ArgStorage;
16176 }
16177 }
16178
16179 // If we're not expanding the pack, just transform the decl.
16180 if (!PackArgs.size()) {
16181 auto *Pack = cast_or_null<NamedDecl>(
16182 getDerived().TransformDecl(E->getPackLoc(), E->getPack()));
16183 if (!Pack)
16184 return ExprError();
16185 return getDerived().RebuildSizeOfPackExpr(
16186 E->getOperatorLoc(), Pack, E->getPackLoc(), E->getRParenLoc(),
16187 std::nullopt, {});
16188 }
16189
16190 // Try to compute the result without performing a partial substitution.
16191 UnsignedOrNone Result =
16192 getDerived().ComputeSizeOfPackExprWithoutSubstitution(PackArgs);
16193
16194 // Common case: we could determine the number of expansions without
16195 // substituting.
16196 if (Result)
16197 return getDerived().RebuildSizeOfPackExpr(E->getOperatorLoc(), E->getPack(),
16198 E->getPackLoc(),
16199 E->getRParenLoc(), *Result, {});
16200
16201 TemplateArgumentListInfo TransformedPackArgs(E->getPackLoc(),
16202 E->getPackLoc());
16203 {
16204 TemporaryBase Rebase(*this, E->getPackLoc(), getBaseEntity());
16205 typedef TemplateArgumentLocInventIterator<
16206 Derived, const TemplateArgument*> PackLocIterator;
16207 if (TransformTemplateArguments(PackLocIterator(*this, PackArgs.begin()),
16208 PackLocIterator(*this, PackArgs.end()),
16209 TransformedPackArgs, /*Uneval*/true))
16210 return ExprError();
16211 }
16212
16213 // Check whether we managed to fully-expand the pack.
16214 // FIXME: Is it possible for us to do so and not hit the early exit path?
16215 SmallVector<TemplateArgument, 8> Args;
16216 bool PartialSubstitution = false;
16217 for (auto &Loc : TransformedPackArgs.arguments()) {
16218 Args.push_back(Elt: Loc.getArgument());
16219 if (Loc.getArgument().isPackExpansion())
16220 PartialSubstitution = true;
16221 }
16222
16223 if (PartialSubstitution)
16224 return getDerived().RebuildSizeOfPackExpr(
16225 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16226 std::nullopt, Args);
16227
16228 return getDerived().RebuildSizeOfPackExpr(
16229 E->getOperatorLoc(), E->getPack(), E->getPackLoc(), E->getRParenLoc(),
16230 /*Length=*/static_cast<unsigned>(Args.size()),
16231 /*PartialArgs=*/{});
16232}
16233
16234template <typename Derived>
16235ExprResult
16236TreeTransform<Derived>::TransformPackIndexingExpr(PackIndexingExpr *E) {
16237 if (!E->isValueDependent())
16238 return E;
16239
16240 // Transform the index
16241 ExprResult IndexExpr;
16242 {
16243 EnterExpressionEvaluationContext ConstantContext(
16244 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
16245 IndexExpr = getDerived().TransformExpr(E->getIndexExpr());
16246 if (IndexExpr.isInvalid())
16247 return ExprError();
16248 }
16249
16250 SmallVector<Expr *, 5> ExpandedExprs;
16251 bool FullySubstituted = true;
16252 if (!E->expandsToEmptyPack() && E->getExpressions().empty()) {
16253 Expr *Pattern = E->getPackIdExpression();
16254 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16255 getSema().collectUnexpandedParameterPacks(E->getPackIdExpression(),
16256 Unexpanded);
16257 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16258
16259 // Determine whether the set of unexpanded parameter packs can and should
16260 // be expanded.
16261 bool ShouldExpand = true;
16262 bool RetainExpansion = false;
16263 UnsignedOrNone OrigNumExpansions = std::nullopt,
16264 NumExpansions = std::nullopt;
16265 if (getDerived().TryExpandParameterPacks(
16266 E->getEllipsisLoc(), Pattern->getSourceRange(), Unexpanded,
16267 ShouldExpand, RetainExpansion, NumExpansions))
16268 return true;
16269 if (!ShouldExpand) {
16270 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16271 ExprResult Pack = getDerived().TransformExpr(Pattern);
16272 if (Pack.isInvalid())
16273 return ExprError();
16274 return getDerived().RebuildPackIndexingExpr(
16275 E->getEllipsisLoc(), E->getRSquareLoc(), Pack.get(), IndexExpr.get(),
16276 {}, /*FullySubstituted=*/false);
16277 }
16278 for (unsigned I = 0; I != *NumExpansions; ++I) {
16279 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16280 ExprResult Out = getDerived().TransformExpr(Pattern);
16281 if (Out.isInvalid())
16282 return true;
16283 if (Out.get()->containsUnexpandedParameterPack()) {
16284 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16285 OrigNumExpansions);
16286 if (Out.isInvalid())
16287 return true;
16288 FullySubstituted = false;
16289 }
16290 ExpandedExprs.push_back(Elt: Out.get());
16291 }
16292 // If we're supposed to retain a pack expansion, do so by temporarily
16293 // forgetting the partially-substituted parameter pack.
16294 if (RetainExpansion) {
16295 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16296
16297 ExprResult Out = getDerived().TransformExpr(Pattern);
16298 if (Out.isInvalid())
16299 return true;
16300
16301 Out = getDerived().RebuildPackExpansion(Out.get(), E->getEllipsisLoc(),
16302 OrigNumExpansions);
16303 if (Out.isInvalid())
16304 return true;
16305 FullySubstituted = false;
16306 ExpandedExprs.push_back(Elt: Out.get());
16307 }
16308 } else if (!E->expandsToEmptyPack()) {
16309 if (getDerived().TransformExprs(E->getExpressions().data(),
16310 E->getExpressions().size(), false,
16311 ExpandedExprs))
16312 return ExprError();
16313 }
16314
16315 return getDerived().RebuildPackIndexingExpr(
16316 E->getEllipsisLoc(), E->getRSquareLoc(), E->getPackIdExpression(),
16317 IndexExpr.get(), ExpandedExprs, FullySubstituted);
16318}
16319
16320template<typename Derived>
16321ExprResult
16322TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
16323 SubstNonTypeTemplateParmPackExpr *E) {
16324 // Default behavior is to do nothing with this transformation.
16325 return E;
16326}
16327
16328template<typename Derived>
16329ExprResult
16330TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
16331 SubstNonTypeTemplateParmExpr *E) {
16332 // Default behavior is to do nothing with this transformation.
16333 return E;
16334}
16335
16336template<typename Derived>
16337ExprResult
16338TreeTransform<Derived>::TransformFunctionParmPackExpr(FunctionParmPackExpr *E) {
16339 // Default behavior is to do nothing with this transformation.
16340 return E;
16341}
16342
16343template<typename Derived>
16344ExprResult
16345TreeTransform<Derived>::TransformMaterializeTemporaryExpr(
16346 MaterializeTemporaryExpr *E) {
16347 return getDerived().TransformExpr(E->getSubExpr());
16348}
16349
16350template<typename Derived>
16351ExprResult
16352TreeTransform<Derived>::TransformCXXFoldExpr(CXXFoldExpr *E) {
16353 UnresolvedLookupExpr *Callee = nullptr;
16354 if (Expr *OldCallee = E->getCallee()) {
16355 ExprResult CalleeResult = getDerived().TransformExpr(OldCallee);
16356 if (CalleeResult.isInvalid())
16357 return ExprError();
16358 Callee = cast<UnresolvedLookupExpr>(Val: CalleeResult.get());
16359 }
16360
16361 Expr *Pattern = E->getPattern();
16362
16363 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16364 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
16365 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16366
16367 // Determine whether the set of unexpanded parameter packs can and should
16368 // be expanded.
16369 bool Expand = true;
16370 bool RetainExpansion = false;
16371 UnsignedOrNone OrigNumExpansions = E->getNumExpansions(),
16372 NumExpansions = OrigNumExpansions;
16373 if (getDerived().TryExpandParameterPacks(E->getEllipsisLoc(),
16374 Pattern->getSourceRange(),
16375 Unexpanded,
16376 Expand, RetainExpansion,
16377 NumExpansions))
16378 return true;
16379
16380 if (!Expand) {
16381 // Do not expand any packs here, just transform and rebuild a fold
16382 // expression.
16383 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16384
16385 ExprResult LHS =
16386 E->getLHS() ? getDerived().TransformExpr(E->getLHS()) : ExprResult();
16387 if (LHS.isInvalid())
16388 return true;
16389
16390 ExprResult RHS =
16391 E->getRHS() ? getDerived().TransformExpr(E->getRHS()) : ExprResult();
16392 if (RHS.isInvalid())
16393 return true;
16394
16395 if (!getDerived().AlwaysRebuild() &&
16396 LHS.get() == E->getLHS() && RHS.get() == E->getRHS())
16397 return E;
16398
16399 return getDerived().RebuildCXXFoldExpr(
16400 Callee, E->getBeginLoc(), LHS.get(), E->getOperator(),
16401 E->getEllipsisLoc(), RHS.get(), E->getEndLoc(), NumExpansions);
16402 }
16403
16404 // Formally a fold expression expands to nested parenthesized expressions.
16405 // Enforce this limit to avoid creating trees so deep we can't safely traverse
16406 // them.
16407 if (NumExpansions && SemaRef.getLangOpts().BracketDepth < *NumExpansions) {
16408 SemaRef.Diag(Loc: E->getEllipsisLoc(),
16409 DiagID: clang::diag::err_fold_expression_limit_exceeded)
16410 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16411 << E->getSourceRange();
16412 SemaRef.Diag(Loc: E->getEllipsisLoc(), DiagID: diag::note_bracket_depth);
16413 return ExprError();
16414 }
16415
16416 // The transform has determined that we should perform an elementwise
16417 // expansion of the pattern. Do so.
16418 ExprResult Result = getDerived().TransformExpr(E->getInit());
16419 if (Result.isInvalid())
16420 return true;
16421 bool LeftFold = E->isLeftFold();
16422
16423 // If we're retaining an expansion for a right fold, it is the innermost
16424 // component and takes the init (if any).
16425 if (!LeftFold && RetainExpansion) {
16426 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16427
16428 ExprResult Out = getDerived().TransformExpr(Pattern);
16429 if (Out.isInvalid())
16430 return true;
16431
16432 Result = getDerived().RebuildCXXFoldExpr(
16433 Callee, E->getBeginLoc(), Out.get(), E->getOperator(),
16434 E->getEllipsisLoc(), Result.get(), E->getEndLoc(), OrigNumExpansions);
16435 if (Result.isInvalid())
16436 return true;
16437 }
16438
16439 bool WarnedOnComparison = false;
16440 for (unsigned I = 0; I != *NumExpansions; ++I) {
16441 Sema::ArgPackSubstIndexRAII SubstIndex(
16442 getSema(), LeftFold ? I : *NumExpansions - I - 1);
16443 ExprResult Out = getDerived().TransformExpr(Pattern);
16444 if (Out.isInvalid())
16445 return true;
16446
16447 if (Out.get()->containsUnexpandedParameterPack()) {
16448 // We still have a pack; retain a pack expansion for this slice.
16449 Result = getDerived().RebuildCXXFoldExpr(
16450 Callee, E->getBeginLoc(), LeftFold ? Result.get() : Out.get(),
16451 E->getOperator(), E->getEllipsisLoc(),
16452 LeftFold ? Out.get() : Result.get(), E->getEndLoc(),
16453 OrigNumExpansions);
16454 } else if (Result.isUsable()) {
16455 // We've got down to a single element; build a binary operator.
16456 Expr *LHS = LeftFold ? Result.get() : Out.get();
16457 Expr *RHS = LeftFold ? Out.get() : Result.get();
16458 if (Callee) {
16459 UnresolvedSet<16> Functions;
16460 Functions.append(I: Callee->decls_begin(), E: Callee->decls_end());
16461 Result = getDerived().RebuildCXXOperatorCallExpr(
16462 BinaryOperator::getOverloadedOperator(Opc: E->getOperator()),
16463 E->getEllipsisLoc(), Callee->getBeginLoc(), Callee->requiresADL(),
16464 Functions, LHS, RHS);
16465 } else {
16466 Result = getDerived().RebuildBinaryOperator(E->getEllipsisLoc(),
16467 E->getOperator(), LHS, RHS,
16468 /*ForFoldExpresion=*/true);
16469 if (!WarnedOnComparison && Result.isUsable()) {
16470 if (auto *BO = dyn_cast<BinaryOperator>(Val: Result.get());
16471 BO && BO->isComparisonOp()) {
16472 WarnedOnComparison = true;
16473 SemaRef.Diag(Loc: BO->getBeginLoc(),
16474 DiagID: diag::warn_comparison_in_fold_expression)
16475 << BO->getOpcodeStr();
16476 }
16477 }
16478 }
16479 } else
16480 Result = Out;
16481
16482 if (Result.isInvalid())
16483 return true;
16484 }
16485
16486 // If we're retaining an expansion for a left fold, it is the outermost
16487 // component and takes the complete expansion so far as its init (if any).
16488 if (LeftFold && RetainExpansion) {
16489 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
16490
16491 ExprResult Out = getDerived().TransformExpr(Pattern);
16492 if (Out.isInvalid())
16493 return true;
16494
16495 Result = getDerived().RebuildCXXFoldExpr(
16496 Callee, E->getBeginLoc(), Result.get(), E->getOperator(),
16497 E->getEllipsisLoc(), Out.get(), E->getEndLoc(), OrigNumExpansions);
16498 if (Result.isInvalid())
16499 return true;
16500 }
16501
16502 if (ParenExpr *PE = dyn_cast_or_null<ParenExpr>(Val: Result.get()))
16503 PE->setIsProducedByFoldExpansion();
16504
16505 // If we had no init and an empty pack, and we're not retaining an expansion,
16506 // then produce a fallback value or error.
16507 if (Result.isUnset())
16508 return getDerived().RebuildEmptyCXXFoldExpr(E->getEllipsisLoc(),
16509 E->getOperator());
16510 return Result;
16511}
16512
16513template <typename Derived>
16514ExprResult
16515TreeTransform<Derived>::TransformCXXParenListInitExpr(CXXParenListInitExpr *E) {
16516 SmallVector<Expr *, 4> TransformedInits;
16517 ArrayRef<Expr *> InitExprs = E->getInitExprs();
16518
16519 QualType T = getDerived().TransformType(E->getType());
16520
16521 bool ArgChanged = false;
16522
16523 if (getDerived().TransformExprs(InitExprs.data(), InitExprs.size(), true,
16524 TransformedInits, &ArgChanged))
16525 return ExprError();
16526
16527 if (!getDerived().AlwaysRebuild() && !ArgChanged && T == E->getType())
16528 return E;
16529
16530 return getDerived().RebuildCXXParenListInitExpr(
16531 TransformedInits, T, E->getUserSpecifiedInitExprs().size(),
16532 E->getInitLoc(), E->getBeginLoc(), E->getEndLoc());
16533}
16534
16535template<typename Derived>
16536ExprResult
16537TreeTransform<Derived>::TransformCXXStdInitializerListExpr(
16538 CXXStdInitializerListExpr *E) {
16539 return getDerived().TransformExpr(E->getSubExpr());
16540}
16541
16542template<typename Derived>
16543ExprResult
16544TreeTransform<Derived>::TransformObjCStringLiteral(ObjCStringLiteral *E) {
16545 return SemaRef.MaybeBindToTemporary(E);
16546}
16547
16548template<typename Derived>
16549ExprResult
16550TreeTransform<Derived>::TransformObjCBoolLiteralExpr(ObjCBoolLiteralExpr *E) {
16551 return E;
16552}
16553
16554template<typename Derived>
16555ExprResult
16556TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
16557 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
16558 if (SubExpr.isInvalid())
16559 return ExprError();
16560
16561 if (!getDerived().AlwaysRebuild() &&
16562 SubExpr.get() == E->getSubExpr())
16563 return E;
16564
16565 return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
16566}
16567
16568template<typename Derived>
16569ExprResult
16570TreeTransform<Derived>::TransformObjCArrayLiteral(ObjCArrayLiteral *E) {
16571 // Transform each of the elements.
16572 SmallVector<Expr *, 8> Elements;
16573 bool ArgChanged = false;
16574 if (getDerived().TransformExprs(E->getElements(), E->getNumElements(),
16575 /*IsCall=*/false, Elements, &ArgChanged))
16576 return ExprError();
16577
16578 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16579 return SemaRef.MaybeBindToTemporary(E);
16580
16581 return getDerived().RebuildObjCArrayLiteral(E->getSourceRange(),
16582 Elements.data(),
16583 Elements.size());
16584}
16585
16586template<typename Derived>
16587ExprResult
16588TreeTransform<Derived>::TransformObjCDictionaryLiteral(
16589 ObjCDictionaryLiteral *E) {
16590 // Transform each of the elements.
16591 SmallVector<ObjCDictionaryElement, 8> Elements;
16592 bool ArgChanged = false;
16593 for (unsigned I = 0, N = E->getNumElements(); I != N; ++I) {
16594 ObjCDictionaryElement OrigElement = E->getKeyValueElement(Index: I);
16595
16596 if (OrigElement.isPackExpansion()) {
16597 // This key/value element is a pack expansion.
16598 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
16599 getSema().collectUnexpandedParameterPacks(OrigElement.Key, Unexpanded);
16600 getSema().collectUnexpandedParameterPacks(OrigElement.Value, Unexpanded);
16601 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
16602
16603 // Determine whether the set of unexpanded parameter packs can
16604 // and should be expanded.
16605 bool Expand = true;
16606 bool RetainExpansion = false;
16607 UnsignedOrNone OrigNumExpansions = OrigElement.NumExpansions;
16608 UnsignedOrNone NumExpansions = OrigNumExpansions;
16609 SourceRange PatternRange(OrigElement.Key->getBeginLoc(),
16610 OrigElement.Value->getEndLoc());
16611 if (getDerived().TryExpandParameterPacks(OrigElement.EllipsisLoc,
16612 PatternRange, Unexpanded, Expand,
16613 RetainExpansion, NumExpansions))
16614 return ExprError();
16615
16616 if (!Expand) {
16617 // The transform has determined that we should perform a simple
16618 // transformation on the pack expansion, producing another pack
16619 // expansion.
16620 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
16621 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16622 if (Key.isInvalid())
16623 return ExprError();
16624
16625 if (Key.get() != OrigElement.Key)
16626 ArgChanged = true;
16627
16628 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16629 if (Value.isInvalid())
16630 return ExprError();
16631
16632 if (Value.get() != OrigElement.Value)
16633 ArgChanged = true;
16634
16635 ObjCDictionaryElement Expansion = {
16636 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: OrigElement.EllipsisLoc, .NumExpansions: NumExpansions
16637 };
16638 Elements.push_back(Elt: Expansion);
16639 continue;
16640 }
16641
16642 // Record right away that the argument was changed. This needs
16643 // to happen even if the array expands to nothing.
16644 ArgChanged = true;
16645
16646 // The transform has determined that we should perform an elementwise
16647 // expansion of the pattern. Do so.
16648 for (unsigned I = 0; I != *NumExpansions; ++I) {
16649 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
16650 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16651 if (Key.isInvalid())
16652 return ExprError();
16653
16654 ExprResult Value = getDerived().TransformExpr(OrigElement.Value);
16655 if (Value.isInvalid())
16656 return ExprError();
16657
16658 ObjCDictionaryElement Element = {
16659 .Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(), .NumExpansions: NumExpansions
16660 };
16661
16662 // If any unexpanded parameter packs remain, we still have a
16663 // pack expansion.
16664 // FIXME: Can this really happen?
16665 if (Key.get()->containsUnexpandedParameterPack() ||
16666 Value.get()->containsUnexpandedParameterPack())
16667 Element.EllipsisLoc = OrigElement.EllipsisLoc;
16668
16669 Elements.push_back(Elt: Element);
16670 }
16671
16672 // FIXME: Retain a pack expansion if RetainExpansion is true.
16673
16674 // We've finished with this pack expansion.
16675 continue;
16676 }
16677
16678 // Transform and check key.
16679 ExprResult Key = getDerived().TransformExpr(OrigElement.Key);
16680 if (Key.isInvalid())
16681 return ExprError();
16682
16683 if (Key.get() != OrigElement.Key)
16684 ArgChanged = true;
16685
16686 // Transform and check value.
16687 ExprResult Value
16688 = getDerived().TransformExpr(OrigElement.Value);
16689 if (Value.isInvalid())
16690 return ExprError();
16691
16692 if (Value.get() != OrigElement.Value)
16693 ArgChanged = true;
16694
16695 ObjCDictionaryElement Element = {.Key: Key.get(), .Value: Value.get(), .EllipsisLoc: SourceLocation(),
16696 .NumExpansions: std::nullopt};
16697 Elements.push_back(Elt: Element);
16698 }
16699
16700 if (!getDerived().AlwaysRebuild() && !ArgChanged)
16701 return SemaRef.MaybeBindToTemporary(E);
16702
16703 return getDerived().RebuildObjCDictionaryLiteral(E->getSourceRange(),
16704 Elements);
16705}
16706
16707template<typename Derived>
16708ExprResult
16709TreeTransform<Derived>::TransformObjCEncodeExpr(ObjCEncodeExpr *E) {
16710 TypeSourceInfo *EncodedTypeInfo
16711 = getDerived().TransformType(E->getEncodedTypeSourceInfo());
16712 if (!EncodedTypeInfo)
16713 return ExprError();
16714
16715 if (!getDerived().AlwaysRebuild() &&
16716 EncodedTypeInfo == E->getEncodedTypeSourceInfo())
16717 return E;
16718
16719 return getDerived().RebuildObjCEncodeExpr(E->getAtLoc(),
16720 EncodedTypeInfo,
16721 E->getRParenLoc());
16722}
16723
16724template<typename Derived>
16725ExprResult TreeTransform<Derived>::
16726TransformObjCIndirectCopyRestoreExpr(ObjCIndirectCopyRestoreExpr *E) {
16727 // This is a kind of implicit conversion, and it needs to get dropped
16728 // and recomputed for the same general reasons that ImplicitCastExprs
16729 // do, as well a more specific one: this expression is only valid when
16730 // it appears *immediately* as an argument expression.
16731 return getDerived().TransformExpr(E->getSubExpr());
16732}
16733
16734template<typename Derived>
16735ExprResult TreeTransform<Derived>::
16736TransformObjCBridgedCastExpr(ObjCBridgedCastExpr *E) {
16737 TypeSourceInfo *TSInfo
16738 = getDerived().TransformType(E->getTypeInfoAsWritten());
16739 if (!TSInfo)
16740 return ExprError();
16741
16742 ExprResult Result = getDerived().TransformExpr(E->getSubExpr());
16743 if (Result.isInvalid())
16744 return ExprError();
16745
16746 if (!getDerived().AlwaysRebuild() &&
16747 TSInfo == E->getTypeInfoAsWritten() &&
16748 Result.get() == E->getSubExpr())
16749 return E;
16750
16751 return SemaRef.ObjC().BuildObjCBridgedCast(
16752 LParenLoc: E->getLParenLoc(), Kind: E->getBridgeKind(), BridgeKeywordLoc: E->getBridgeKeywordLoc(), TSInfo,
16753 SubExpr: Result.get());
16754}
16755
16756template <typename Derived>
16757ExprResult TreeTransform<Derived>::TransformObjCAvailabilityCheckExpr(
16758 ObjCAvailabilityCheckExpr *E) {
16759 return E;
16760}
16761
16762template<typename Derived>
16763ExprResult
16764TreeTransform<Derived>::TransformObjCMessageExpr(ObjCMessageExpr *E) {
16765 // Transform arguments.
16766 bool ArgChanged = false;
16767 SmallVector<Expr*, 8> Args;
16768 Args.reserve(N: E->getNumArgs());
16769 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), false, Args,
16770 &ArgChanged))
16771 return ExprError();
16772
16773 if (E->getReceiverKind() == ObjCMessageExpr::Class) {
16774 // Class message: transform the receiver type.
16775 TypeSourceInfo *ReceiverTypeInfo
16776 = getDerived().TransformType(E->getClassReceiverTypeInfo());
16777 if (!ReceiverTypeInfo)
16778 return ExprError();
16779
16780 // If nothing changed, just retain the existing message send.
16781 if (!getDerived().AlwaysRebuild() &&
16782 ReceiverTypeInfo == E->getClassReceiverTypeInfo() && !ArgChanged)
16783 return SemaRef.MaybeBindToTemporary(E);
16784
16785 // Build a new class message send.
16786 SmallVector<SourceLocation, 16> SelLocs;
16787 E->getSelectorLocs(SelLocs);
16788 return getDerived().RebuildObjCMessageExpr(ReceiverTypeInfo,
16789 E->getSelector(),
16790 SelLocs,
16791 E->getMethodDecl(),
16792 E->getLeftLoc(),
16793 Args,
16794 E->getRightLoc());
16795 }
16796 else if (E->getReceiverKind() == ObjCMessageExpr::SuperClass ||
16797 E->getReceiverKind() == ObjCMessageExpr::SuperInstance) {
16798 if (!E->getMethodDecl())
16799 return ExprError();
16800
16801 // Build a new class message send to 'super'.
16802 SmallVector<SourceLocation, 16> SelLocs;
16803 E->getSelectorLocs(SelLocs);
16804 return getDerived().RebuildObjCMessageExpr(E->getSuperLoc(),
16805 E->getSelector(),
16806 SelLocs,
16807 E->getReceiverType(),
16808 E->getMethodDecl(),
16809 E->getLeftLoc(),
16810 Args,
16811 E->getRightLoc());
16812 }
16813
16814 // Instance message: transform the receiver
16815 assert(E->getReceiverKind() == ObjCMessageExpr::Instance &&
16816 "Only class and instance messages may be instantiated");
16817 ExprResult Receiver
16818 = getDerived().TransformExpr(E->getInstanceReceiver());
16819 if (Receiver.isInvalid())
16820 return ExprError();
16821
16822 // If nothing changed, just retain the existing message send.
16823 if (!getDerived().AlwaysRebuild() &&
16824 Receiver.get() == E->getInstanceReceiver() && !ArgChanged)
16825 return SemaRef.MaybeBindToTemporary(E);
16826
16827 // Build a new instance message send.
16828 SmallVector<SourceLocation, 16> SelLocs;
16829 E->getSelectorLocs(SelLocs);
16830 return getDerived().RebuildObjCMessageExpr(Receiver.get(),
16831 E->getSelector(),
16832 SelLocs,
16833 E->getMethodDecl(),
16834 E->getLeftLoc(),
16835 Args,
16836 E->getRightLoc());
16837}
16838
16839template<typename Derived>
16840ExprResult
16841TreeTransform<Derived>::TransformObjCSelectorExpr(ObjCSelectorExpr *E) {
16842 return E;
16843}
16844
16845template<typename Derived>
16846ExprResult
16847TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
16848 return E;
16849}
16850
16851template<typename Derived>
16852ExprResult
16853TreeTransform<Derived>::TransformObjCIvarRefExpr(ObjCIvarRefExpr *E) {
16854 // Transform the base expression.
16855 ExprResult Base = getDerived().TransformExpr(E->getBase());
16856 if (Base.isInvalid())
16857 return ExprError();
16858
16859 // We don't need to transform the ivar; it will never change.
16860
16861 // If nothing changed, just retain the existing expression.
16862 if (!getDerived().AlwaysRebuild() &&
16863 Base.get() == E->getBase())
16864 return E;
16865
16866 return getDerived().RebuildObjCIvarRefExpr(Base.get(), E->getDecl(),
16867 E->getLocation(),
16868 E->isArrow(), E->isFreeIvar());
16869}
16870
16871template<typename Derived>
16872ExprResult
16873TreeTransform<Derived>::TransformObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
16874 // 'super' and types never change. Property never changes. Just
16875 // retain the existing expression.
16876 if (!E->isObjectReceiver())
16877 return E;
16878
16879 // Transform the base expression.
16880 ExprResult Base = getDerived().TransformExpr(E->getBase());
16881 if (Base.isInvalid())
16882 return ExprError();
16883
16884 // We don't need to transform the property; it will never change.
16885
16886 // If nothing changed, just retain the existing expression.
16887 if (!getDerived().AlwaysRebuild() &&
16888 Base.get() == E->getBase())
16889 return E;
16890
16891 if (E->isExplicitProperty())
16892 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16893 E->getExplicitProperty(),
16894 E->getLocation());
16895
16896 return getDerived().RebuildObjCPropertyRefExpr(Base.get(),
16897 SemaRef.Context.PseudoObjectTy,
16898 E->getImplicitPropertyGetter(),
16899 E->getImplicitPropertySetter(),
16900 E->getLocation());
16901}
16902
16903template<typename Derived>
16904ExprResult
16905TreeTransform<Derived>::TransformObjCSubscriptRefExpr(ObjCSubscriptRefExpr *E) {
16906 // Transform the base expression.
16907 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
16908 if (Base.isInvalid())
16909 return ExprError();
16910
16911 // Transform the key expression.
16912 ExprResult Key = getDerived().TransformExpr(E->getKeyExpr());
16913 if (Key.isInvalid())
16914 return ExprError();
16915
16916 // If nothing changed, just retain the existing expression.
16917 if (!getDerived().AlwaysRebuild() &&
16918 Key.get() == E->getKeyExpr() && Base.get() == E->getBaseExpr())
16919 return E;
16920
16921 return getDerived().RebuildObjCSubscriptRefExpr(E->getRBracket(),
16922 Base.get(), Key.get(),
16923 E->getAtIndexMethodDecl(),
16924 E->setAtIndexMethodDecl());
16925}
16926
16927template<typename Derived>
16928ExprResult
16929TreeTransform<Derived>::TransformObjCIsaExpr(ObjCIsaExpr *E) {
16930 // Transform the base expression.
16931 ExprResult Base = getDerived().TransformExpr(E->getBase());
16932 if (Base.isInvalid())
16933 return ExprError();
16934
16935 // If nothing changed, just retain the existing expression.
16936 if (!getDerived().AlwaysRebuild() &&
16937 Base.get() == E->getBase())
16938 return E;
16939
16940 return getDerived().RebuildObjCIsaExpr(Base.get(), E->getIsaMemberLoc(),
16941 E->getOpLoc(),
16942 E->isArrow());
16943}
16944
16945template<typename Derived>
16946ExprResult
16947TreeTransform<Derived>::TransformShuffleVectorExpr(ShuffleVectorExpr *E) {
16948 bool ArgumentChanged = false;
16949 SmallVector<Expr*, 8> SubExprs;
16950 SubExprs.reserve(N: E->getNumSubExprs());
16951 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
16952 SubExprs, &ArgumentChanged))
16953 return ExprError();
16954
16955 if (!getDerived().AlwaysRebuild() &&
16956 !ArgumentChanged)
16957 return E;
16958
16959 return getDerived().RebuildShuffleVectorExpr(E->getBuiltinLoc(),
16960 SubExprs,
16961 E->getRParenLoc());
16962}
16963
16964template<typename Derived>
16965ExprResult
16966TreeTransform<Derived>::TransformConvertVectorExpr(ConvertVectorExpr *E) {
16967 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
16968 if (SrcExpr.isInvalid())
16969 return ExprError();
16970
16971 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
16972 if (!Type)
16973 return ExprError();
16974
16975 if (!getDerived().AlwaysRebuild() &&
16976 Type == E->getTypeSourceInfo() &&
16977 SrcExpr.get() == E->getSrcExpr())
16978 return E;
16979
16980 return getDerived().RebuildConvertVectorExpr(E->getBuiltinLoc(),
16981 SrcExpr.get(), Type,
16982 E->getRParenLoc());
16983}
16984
16985template<typename Derived>
16986ExprResult
16987TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
16988 BlockDecl *oldBlock = E->getBlockDecl();
16989
16990 SemaRef.ActOnBlockStart(CaretLoc: E->getCaretLocation(), /*Scope=*/CurScope: nullptr);
16991 BlockScopeInfo *blockScope = SemaRef.getCurBlock();
16992
16993 blockScope->TheDecl->setIsVariadic(oldBlock->isVariadic());
16994 blockScope->TheDecl->setBlockMissingReturnType(
16995 oldBlock->blockMissingReturnType());
16996
16997 SmallVector<ParmVarDecl*, 4> params;
16998 SmallVector<QualType, 4> paramTypes;
16999
17000 const FunctionProtoType *exprFunctionType = E->getFunctionType();
17001
17002 // Parameter substitution.
17003 Sema::ExtParameterInfoBuilder extParamInfos;
17004 if (getDerived().TransformFunctionTypeParams(
17005 E->getCaretLocation(), oldBlock->parameters(), nullptr,
17006 exprFunctionType->getExtParameterInfosOrNull(), paramTypes, &params,
17007 extParamInfos)) {
17008 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17009 return ExprError();
17010 }
17011
17012 QualType exprResultType =
17013 getDerived().TransformType(exprFunctionType->getReturnType());
17014
17015 auto epi = exprFunctionType->getExtProtoInfo();
17016 epi.ExtParameterInfos = extParamInfos.getPointerOrNull(numParams: paramTypes.size());
17017
17018 QualType functionType =
17019 getDerived().RebuildFunctionProtoType(exprResultType, paramTypes, epi);
17020 blockScope->FunctionType = functionType;
17021
17022 // Set the parameters on the block decl.
17023 if (!params.empty())
17024 blockScope->TheDecl->setParams(params);
17025
17026 if (!oldBlock->blockMissingReturnType()) {
17027 blockScope->HasImplicitReturnType = false;
17028 blockScope->ReturnType = exprResultType;
17029 }
17030
17031 // Transform the body
17032 StmtResult body = getDerived().TransformStmt(E->getBody());
17033 if (body.isInvalid()) {
17034 getSema().ActOnBlockError(E->getCaretLocation(), /*Scope=*/nullptr);
17035 return ExprError();
17036 }
17037
17038#ifndef NDEBUG
17039 // In builds with assertions, make sure that we captured everything we
17040 // captured before.
17041 if (!SemaRef.getDiagnostics().hasErrorOccurred()) {
17042 for (const auto &I : oldBlock->captures()) {
17043 VarDecl *oldCapture = I.getVariable();
17044
17045 // Ignore parameter packs.
17046 if (oldCapture->isParameterPack())
17047 continue;
17048
17049 VarDecl *newCapture =
17050 cast<VarDecl>(getDerived().TransformDecl(E->getCaretLocation(),
17051 oldCapture));
17052 assert(blockScope->CaptureMap.count(newCapture));
17053 }
17054
17055 // The this pointer may not be captured by the instantiated block, even when
17056 // it's captured by the original block, if the expression causing the
17057 // capture is in the discarded branch of a constexpr if statement.
17058 assert((!blockScope->isCXXThisCaptured() || oldBlock->capturesCXXThis()) &&
17059 "this pointer isn't captured in the old block");
17060 }
17061#endif
17062
17063 return SemaRef.ActOnBlockStmtExpr(CaretLoc: E->getCaretLocation(), Body: body.get(),
17064 /*Scope=*/CurScope: nullptr);
17065}
17066
17067template<typename Derived>
17068ExprResult
17069TreeTransform<Derived>::TransformAsTypeExpr(AsTypeExpr *E) {
17070 ExprResult SrcExpr = getDerived().TransformExpr(E->getSrcExpr());
17071 if (SrcExpr.isInvalid())
17072 return ExprError();
17073
17074 QualType Type = getDerived().TransformType(E->getType());
17075
17076 return SemaRef.BuildAsTypeExpr(E: SrcExpr.get(), DestTy: Type, BuiltinLoc: E->getBuiltinLoc(),
17077 RParenLoc: E->getRParenLoc());
17078}
17079
17080template<typename Derived>
17081ExprResult
17082TreeTransform<Derived>::TransformAtomicExpr(AtomicExpr *E) {
17083 bool ArgumentChanged = false;
17084 SmallVector<Expr*, 8> SubExprs;
17085 SubExprs.reserve(N: E->getNumSubExprs());
17086 if (getDerived().TransformExprs(E->getSubExprs(), E->getNumSubExprs(), false,
17087 SubExprs, &ArgumentChanged))
17088 return ExprError();
17089
17090 if (!getDerived().AlwaysRebuild() &&
17091 !ArgumentChanged)
17092 return E;
17093
17094 return getDerived().RebuildAtomicExpr(E->getBuiltinLoc(), SubExprs,
17095 E->getOp(), E->getRParenLoc());
17096}
17097
17098//===----------------------------------------------------------------------===//
17099// Type reconstruction
17100//===----------------------------------------------------------------------===//
17101
17102template<typename Derived>
17103QualType TreeTransform<Derived>::RebuildPointerType(QualType PointeeType,
17104 SourceLocation Star) {
17105 return SemaRef.BuildPointerType(T: PointeeType, Loc: Star,
17106 Entity: getDerived().getBaseEntity());
17107}
17108
17109template<typename Derived>
17110QualType TreeTransform<Derived>::RebuildBlockPointerType(QualType PointeeType,
17111 SourceLocation Star) {
17112 return SemaRef.BuildBlockPointerType(T: PointeeType, Loc: Star,
17113 Entity: getDerived().getBaseEntity());
17114}
17115
17116template<typename Derived>
17117QualType
17118TreeTransform<Derived>::RebuildReferenceType(QualType ReferentType,
17119 bool WrittenAsLValue,
17120 SourceLocation Sigil) {
17121 return SemaRef.BuildReferenceType(T: ReferentType, LValueRef: WrittenAsLValue,
17122 Loc: Sigil, Entity: getDerived().getBaseEntity());
17123}
17124
17125template <typename Derived>
17126QualType TreeTransform<Derived>::RebuildMemberPointerType(
17127 QualType PointeeType, const CXXScopeSpec &SS, CXXRecordDecl *Cls,
17128 SourceLocation Sigil) {
17129 return SemaRef.BuildMemberPointerType(T: PointeeType, SS, Cls, Loc: Sigil,
17130 Entity: getDerived().getBaseEntity());
17131}
17132
17133template<typename Derived>
17134QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
17135 const ObjCTypeParamDecl *Decl,
17136 SourceLocation ProtocolLAngleLoc,
17137 ArrayRef<ObjCProtocolDecl *> Protocols,
17138 ArrayRef<SourceLocation> ProtocolLocs,
17139 SourceLocation ProtocolRAngleLoc) {
17140 return SemaRef.ObjC().BuildObjCTypeParamType(
17141 Decl, ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17142 /*FailOnError=*/FailOnError: true);
17143}
17144
17145template<typename Derived>
17146QualType TreeTransform<Derived>::RebuildObjCObjectType(
17147 QualType BaseType,
17148 SourceLocation Loc,
17149 SourceLocation TypeArgsLAngleLoc,
17150 ArrayRef<TypeSourceInfo *> TypeArgs,
17151 SourceLocation TypeArgsRAngleLoc,
17152 SourceLocation ProtocolLAngleLoc,
17153 ArrayRef<ObjCProtocolDecl *> Protocols,
17154 ArrayRef<SourceLocation> ProtocolLocs,
17155 SourceLocation ProtocolRAngleLoc) {
17156 return SemaRef.ObjC().BuildObjCObjectType(
17157 BaseType, Loc, TypeArgsLAngleLoc, TypeArgs, TypeArgsRAngleLoc,
17158 ProtocolLAngleLoc, Protocols, ProtocolLocs, ProtocolRAngleLoc,
17159 /*FailOnError=*/FailOnError: true,
17160 /*Rebuilding=*/Rebuilding: true);
17161}
17162
17163template<typename Derived>
17164QualType TreeTransform<Derived>::RebuildObjCObjectPointerType(
17165 QualType PointeeType,
17166 SourceLocation Star) {
17167 return SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
17168}
17169
17170template <typename Derived>
17171QualType TreeTransform<Derived>::RebuildArrayType(
17172 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt *Size,
17173 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17174 if (SizeExpr || !Size)
17175 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize: SizeExpr,
17176 Quals: IndexTypeQuals, Brackets: BracketsRange,
17177 Entity: getDerived().getBaseEntity());
17178
17179 QualType Types[] = {
17180 SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy,
17181 SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy,
17182 SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty
17183 };
17184 QualType SizeType;
17185 for (const auto &T : Types)
17186 if (Size->getBitWidth() == SemaRef.Context.getIntWidth(T)) {
17187 SizeType = T;
17188 break;
17189 }
17190
17191 // Note that we can return a VariableArrayType here in the case where
17192 // the element type was a dependent VariableArrayType.
17193 IntegerLiteral *ArraySize
17194 = IntegerLiteral::Create(C: SemaRef.Context, V: *Size, type: SizeType,
17195 /*FIXME*/l: BracketsRange.getBegin());
17196 return SemaRef.BuildArrayType(T: ElementType, ASM: SizeMod, ArraySize,
17197 Quals: IndexTypeQuals, Brackets: BracketsRange,
17198 Entity: getDerived().getBaseEntity());
17199}
17200
17201template <typename Derived>
17202QualType TreeTransform<Derived>::RebuildConstantArrayType(
17203 QualType ElementType, ArraySizeModifier SizeMod, const llvm::APInt &Size,
17204 Expr *SizeExpr, unsigned IndexTypeQuals, SourceRange BracketsRange) {
17205 return getDerived().RebuildArrayType(ElementType, SizeMod, &Size, SizeExpr,
17206 IndexTypeQuals, BracketsRange);
17207}
17208
17209template <typename Derived>
17210QualType TreeTransform<Derived>::RebuildIncompleteArrayType(
17211 QualType ElementType, ArraySizeModifier SizeMod, unsigned IndexTypeQuals,
17212 SourceRange BracketsRange) {
17213 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr, nullptr,
17214 IndexTypeQuals, BracketsRange);
17215}
17216
17217template <typename Derived>
17218QualType TreeTransform<Derived>::RebuildVariableArrayType(
17219 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17220 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17221 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17222 SizeExpr,
17223 IndexTypeQuals, BracketsRange);
17224}
17225
17226template <typename Derived>
17227QualType TreeTransform<Derived>::RebuildDependentSizedArrayType(
17228 QualType ElementType, ArraySizeModifier SizeMod, Expr *SizeExpr,
17229 unsigned IndexTypeQuals, SourceRange BracketsRange) {
17230 return getDerived().RebuildArrayType(ElementType, SizeMod, nullptr,
17231 SizeExpr,
17232 IndexTypeQuals, BracketsRange);
17233}
17234
17235template <typename Derived>
17236QualType TreeTransform<Derived>::RebuildDependentAddressSpaceType(
17237 QualType PointeeType, Expr *AddrSpaceExpr, SourceLocation AttributeLoc) {
17238 return SemaRef.BuildAddressSpaceAttr(T&: PointeeType, AddrSpace: AddrSpaceExpr,
17239 AttrLoc: AttributeLoc);
17240}
17241
17242template <typename Derived>
17243QualType TreeTransform<Derived>::RebuildVectorType(QualType ElementType,
17244 unsigned NumElements,
17245 VectorKind VecKind) {
17246 // FIXME: semantic checking!
17247 return SemaRef.Context.getVectorType(VectorType: ElementType, NumElts: NumElements, VecKind);
17248}
17249
17250template <typename Derived>
17251QualType TreeTransform<Derived>::RebuildDependentVectorType(
17252 QualType ElementType, Expr *SizeExpr, SourceLocation AttributeLoc,
17253 VectorKind VecKind) {
17254 return SemaRef.BuildVectorType(T: ElementType, VecSize: SizeExpr, AttrLoc: AttributeLoc);
17255}
17256
17257template<typename Derived>
17258QualType TreeTransform<Derived>::RebuildExtVectorType(QualType ElementType,
17259 unsigned NumElements,
17260 SourceLocation AttributeLoc) {
17261 llvm::APInt numElements(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17262 NumElements, true);
17263 IntegerLiteral *VectorSize
17264 = IntegerLiteral::Create(C: SemaRef.Context, V: numElements, type: SemaRef.Context.IntTy,
17265 l: AttributeLoc);
17266 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: VectorSize, AttrLoc: AttributeLoc);
17267}
17268
17269template<typename Derived>
17270QualType
17271TreeTransform<Derived>::RebuildDependentSizedExtVectorType(QualType ElementType,
17272 Expr *SizeExpr,
17273 SourceLocation AttributeLoc) {
17274 return SemaRef.BuildExtVectorType(T: ElementType, ArraySize: SizeExpr, AttrLoc: AttributeLoc);
17275}
17276
17277template <typename Derived>
17278QualType TreeTransform<Derived>::RebuildConstantMatrixType(
17279 QualType ElementType, unsigned NumRows, unsigned NumColumns) {
17280 return SemaRef.Context.getConstantMatrixType(ElementType, NumRows,
17281 NumColumns);
17282}
17283
17284template <typename Derived>
17285QualType TreeTransform<Derived>::RebuildDependentSizedMatrixType(
17286 QualType ElementType, Expr *RowExpr, Expr *ColumnExpr,
17287 SourceLocation AttributeLoc) {
17288 return SemaRef.BuildMatrixType(T: ElementType, NumRows: RowExpr, NumColumns: ColumnExpr,
17289 AttrLoc: AttributeLoc);
17290}
17291
17292template <typename Derived>
17293QualType TreeTransform<Derived>::RebuildFunctionProtoType(
17294 QualType T, MutableArrayRef<QualType> ParamTypes,
17295 const FunctionProtoType::ExtProtoInfo &EPI) {
17296 return SemaRef.BuildFunctionType(T, ParamTypes,
17297 Loc: getDerived().getBaseLocation(),
17298 Entity: getDerived().getBaseEntity(),
17299 EPI);
17300}
17301
17302template<typename Derived>
17303QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
17304 return SemaRef.Context.getFunctionNoProtoType(ResultTy: T);
17305}
17306
17307template<typename Derived>
17308QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
17309 Decl *D) {
17310 assert(D && "no decl found");
17311 if (D->isInvalidDecl()) return QualType();
17312
17313 // FIXME: Doesn't account for ObjCInterfaceDecl!
17314 if (auto *UPD = dyn_cast<UsingPackDecl>(Val: D)) {
17315 // A valid resolved using typename pack expansion decl can have multiple
17316 // UsingDecls, but they must each have exactly one type, and it must be
17317 // the same type in every case. But we must have at least one expansion!
17318 if (UPD->expansions().empty()) {
17319 getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
17320 << UPD->isCXXClassMember() << UPD;
17321 return QualType();
17322 }
17323
17324 // We might still have some unresolved types. Try to pick a resolved type
17325 // if we can. The final instantiation will check that the remaining
17326 // unresolved types instantiate to the type we pick.
17327 QualType FallbackT;
17328 QualType T;
17329 for (auto *E : UPD->expansions()) {
17330 QualType ThisT = RebuildUnresolvedUsingType(Loc, D: E);
17331 if (ThisT.isNull())
17332 continue;
17333 else if (ThisT->getAs<UnresolvedUsingType>())
17334 FallbackT = ThisT;
17335 else if (T.isNull())
17336 T = ThisT;
17337 else
17338 assert(getSema().Context.hasSameType(ThisT, T) &&
17339 "mismatched resolved types in using pack expansion");
17340 }
17341 return T.isNull() ? FallbackT : T;
17342 } else if (auto *Using = dyn_cast<UsingDecl>(Val: D)) {
17343 assert(Using->hasTypename() &&
17344 "UnresolvedUsingTypenameDecl transformed to non-typename using");
17345
17346 // A valid resolved using typename decl points to exactly one type decl.
17347 assert(++Using->shadow_begin() == Using->shadow_end());
17348
17349 UsingShadowDecl *Shadow = *Using->shadow_begin();
17350 if (SemaRef.DiagnoseUseOfDecl(D: Shadow->getTargetDecl(), Locs: Loc))
17351 return QualType();
17352 return SemaRef.Context.getUsingType(
17353 Found: Shadow, Underlying: SemaRef.Context.getTypeDeclType(
17354 Decl: cast<TypeDecl>(Val: Shadow->getTargetDecl())));
17355 } else {
17356 assert(isa<UnresolvedUsingTypenameDecl>(D) &&
17357 "UnresolvedUsingTypenameDecl transformed to non-using decl");
17358 return SemaRef.Context.getTypeDeclType(
17359 Decl: cast<UnresolvedUsingTypenameDecl>(Val: D));
17360 }
17361}
17362
17363template <typename Derived>
17364QualType TreeTransform<Derived>::RebuildTypeOfExprType(Expr *E, SourceLocation,
17365 TypeOfKind Kind) {
17366 return SemaRef.BuildTypeofExprType(E, Kind);
17367}
17368
17369template<typename Derived>
17370QualType TreeTransform<Derived>::RebuildTypeOfType(QualType Underlying,
17371 TypeOfKind Kind) {
17372 return SemaRef.Context.getTypeOfType(QT: Underlying, Kind);
17373}
17374
17375template <typename Derived>
17376QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, SourceLocation) {
17377 return SemaRef.BuildDecltypeType(E);
17378}
17379
17380template <typename Derived>
17381QualType TreeTransform<Derived>::RebuildPackIndexingType(
17382 QualType Pattern, Expr *IndexExpr, SourceLocation Loc,
17383 SourceLocation EllipsisLoc, bool FullySubstituted,
17384 ArrayRef<QualType> Expansions) {
17385 return SemaRef.BuildPackIndexingType(Pattern, IndexExpr, Loc, EllipsisLoc,
17386 FullySubstituted, Expansions);
17387}
17388
17389template<typename Derived>
17390QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
17391 UnaryTransformType::UTTKind UKind,
17392 SourceLocation Loc) {
17393 return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
17394}
17395
17396template<typename Derived>
17397QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
17398 TemplateName Template,
17399 SourceLocation TemplateNameLoc,
17400 TemplateArgumentListInfo &TemplateArgs) {
17401 return SemaRef.CheckTemplateIdType(Template, TemplateLoc: TemplateNameLoc, TemplateArgs);
17402}
17403
17404template<typename Derived>
17405QualType TreeTransform<Derived>::RebuildAtomicType(QualType ValueType,
17406 SourceLocation KWLoc) {
17407 return SemaRef.BuildAtomicType(T: ValueType, Loc: KWLoc);
17408}
17409
17410template<typename Derived>
17411QualType TreeTransform<Derived>::RebuildPipeType(QualType ValueType,
17412 SourceLocation KWLoc,
17413 bool isReadPipe) {
17414 return isReadPipe ? SemaRef.BuildReadPipeType(T: ValueType, Loc: KWLoc)
17415 : SemaRef.BuildWritePipeType(T: ValueType, Loc: KWLoc);
17416}
17417
17418template <typename Derived>
17419QualType TreeTransform<Derived>::RebuildBitIntType(bool IsUnsigned,
17420 unsigned NumBits,
17421 SourceLocation Loc) {
17422 llvm::APInt NumBitsAP(SemaRef.Context.getIntWidth(T: SemaRef.Context.IntTy),
17423 NumBits, true);
17424 IntegerLiteral *Bits = IntegerLiteral::Create(C: SemaRef.Context, V: NumBitsAP,
17425 type: SemaRef.Context.IntTy, l: Loc);
17426 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: Bits, Loc);
17427}
17428
17429template <typename Derived>
17430QualType TreeTransform<Derived>::RebuildDependentBitIntType(
17431 bool IsUnsigned, Expr *NumBitsExpr, SourceLocation Loc) {
17432 return SemaRef.BuildBitIntType(IsUnsigned, BitWidth: NumBitsExpr, Loc);
17433}
17434
17435template<typename Derived>
17436TemplateName
17437TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17438 bool TemplateKW,
17439 TemplateDecl *Template) {
17440 return SemaRef.Context.getQualifiedTemplateName(NNS: SS.getScopeRep(), TemplateKeyword: TemplateKW,
17441 Template: TemplateName(Template));
17442}
17443
17444template<typename Derived>
17445TemplateName
17446TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17447 SourceLocation TemplateKWLoc,
17448 const IdentifierInfo &Name,
17449 SourceLocation NameLoc,
17450 QualType ObjectType,
17451 NamedDecl *FirstQualifierInScope,
17452 bool AllowInjectedClassName) {
17453 UnqualifiedId TemplateName;
17454 TemplateName.setIdentifier(Id: &Name, IdLoc: NameLoc);
17455 Sema::TemplateTy Template;
17456 getSema().ActOnTemplateName(/*Scope=*/nullptr, SS, TemplateKWLoc,
17457 TemplateName, ParsedType::make(P: ObjectType),
17458 /*EnteringContext=*/false, Template,
17459 AllowInjectedClassName);
17460 return Template.get();
17461}
17462
17463template<typename Derived>
17464TemplateName
17465TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
17466 SourceLocation TemplateKWLoc,
17467 OverloadedOperatorKind Operator,
17468 SourceLocation NameLoc,
17469 QualType ObjectType,
17470 bool AllowInjectedClassName) {
17471 UnqualifiedId Name;
17472 // FIXME: Bogus location information.
17473 SourceLocation SymbolLocations[3] = { NameLoc, NameLoc, NameLoc };
17474 Name.setOperatorFunctionId(OperatorLoc: NameLoc, Op: Operator, SymbolLocations);
17475 Sema::TemplateTy Template;
17476 getSema().ActOnTemplateName(
17477 /*Scope=*/nullptr, SS, TemplateKWLoc, Name, ParsedType::make(P: ObjectType),
17478 /*EnteringContext=*/false, Template, AllowInjectedClassName);
17479 return Template.get();
17480}
17481
17482template <typename Derived>
17483ExprResult TreeTransform<Derived>::RebuildCXXOperatorCallExpr(
17484 OverloadedOperatorKind Op, SourceLocation OpLoc, SourceLocation CalleeLoc,
17485 bool RequiresADL, const UnresolvedSetImpl &Functions, Expr *First,
17486 Expr *Second) {
17487 bool isPostIncDec = Second && (Op == OO_PlusPlus || Op == OO_MinusMinus);
17488
17489 if (First->getObjectKind() == OK_ObjCProperty) {
17490 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17491 if (BinaryOperator::isAssignmentOp(Opc))
17492 return SemaRef.PseudoObject().checkAssignment(/*Scope=*/S: nullptr, OpLoc,
17493 Opcode: Opc, LHS: First, RHS: Second);
17494 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: First);
17495 if (Result.isInvalid())
17496 return ExprError();
17497 First = Result.get();
17498 }
17499
17500 if (Second && Second->getObjectKind() == OK_ObjCProperty) {
17501 ExprResult Result = SemaRef.CheckPlaceholderExpr(E: Second);
17502 if (Result.isInvalid())
17503 return ExprError();
17504 Second = Result.get();
17505 }
17506
17507 // Determine whether this should be a builtin operation.
17508 if (Op == OO_Subscript) {
17509 if (!First->getType()->isOverloadableType() &&
17510 !Second->getType()->isOverloadableType())
17511 return getSema().CreateBuiltinArraySubscriptExpr(First, CalleeLoc, Second,
17512 OpLoc);
17513 } else if (Op == OO_Arrow) {
17514 // It is possible that the type refers to a RecoveryExpr created earlier
17515 // in the tree transformation.
17516 if (First->getType()->isDependentType())
17517 return ExprError();
17518 // -> is never a builtin operation.
17519 return SemaRef.BuildOverloadedArrowExpr(S: nullptr, Base: First, OpLoc);
17520 } else if (Second == nullptr || isPostIncDec) {
17521 if (!First->getType()->isOverloadableType() ||
17522 (Op == OO_Amp && getSema().isQualifiedMemberAccess(First))) {
17523 // The argument is not of overloadable type, or this is an expression
17524 // of the form &Class::member, so try to create a built-in unary
17525 // operation.
17526 UnaryOperatorKind Opc
17527 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17528
17529 return getSema().CreateBuiltinUnaryOp(OpLoc, Opc, First);
17530 }
17531 } else {
17532 if (!First->isTypeDependent() && !Second->isTypeDependent() &&
17533 !First->getType()->isOverloadableType() &&
17534 !Second->getType()->isOverloadableType()) {
17535 // Neither of the arguments is type-dependent or has an overloadable
17536 // type, so try to create a built-in binary operation.
17537 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17538 ExprResult Result
17539 = SemaRef.CreateBuiltinBinOp(OpLoc, Opc, LHSExpr: First, RHSExpr: Second);
17540 if (Result.isInvalid())
17541 return ExprError();
17542
17543 return Result;
17544 }
17545 }
17546
17547 // Create the overloaded operator invocation for unary operators.
17548 if (!Second || isPostIncDec) {
17549 UnaryOperatorKind Opc
17550 = UnaryOperator::getOverloadedOpcode(OO: Op, Postfix: isPostIncDec);
17551 return SemaRef.CreateOverloadedUnaryOp(OpLoc, Opc, Fns: Functions, input: First,
17552 RequiresADL);
17553 }
17554
17555 // Create the overloaded operator invocation for binary operators.
17556 BinaryOperatorKind Opc = BinaryOperator::getOverloadedOpcode(OO: Op);
17557 ExprResult Result = SemaRef.CreateOverloadedBinOp(OpLoc, Opc, Fns: Functions,
17558 LHS: First, RHS: Second, RequiresADL);
17559 if (Result.isInvalid())
17560 return ExprError();
17561
17562 return Result;
17563}
17564
17565template<typename Derived>
17566ExprResult
17567TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
17568 SourceLocation OperatorLoc,
17569 bool isArrow,
17570 CXXScopeSpec &SS,
17571 TypeSourceInfo *ScopeType,
17572 SourceLocation CCLoc,
17573 SourceLocation TildeLoc,
17574 PseudoDestructorTypeStorage Destroyed) {
17575 QualType BaseType = Base->getType();
17576 if (Base->isTypeDependent() || Destroyed.getIdentifier() ||
17577 (!isArrow && !BaseType->getAs<RecordType>()) ||
17578 (isArrow && BaseType->getAs<PointerType>() &&
17579 !BaseType->castAs<PointerType>()->getPointeeType()
17580 ->template getAs<RecordType>())){
17581 // This pseudo-destructor expression is still a pseudo-destructor.
17582 return SemaRef.BuildPseudoDestructorExpr(
17583 Base, OpLoc: OperatorLoc, OpKind: isArrow ? tok::arrow : tok::period, SS, ScopeType,
17584 CCLoc, TildeLoc, DestroyedType: Destroyed);
17585 }
17586
17587 TypeSourceInfo *DestroyedType = Destroyed.getTypeSourceInfo();
17588 DeclarationName Name(SemaRef.Context.DeclarationNames.getCXXDestructorName(
17589 Ty: SemaRef.Context.getCanonicalType(T: DestroyedType->getType())));
17590 DeclarationNameInfo NameInfo(Name, Destroyed.getLocation());
17591 NameInfo.setNamedTypeInfo(DestroyedType);
17592
17593 // The scope type is now known to be a valid nested name specifier
17594 // component. Tack it on to the end of the nested name specifier.
17595 if (ScopeType) {
17596 if (!ScopeType->getType()->getAs<TagType>()) {
17597 getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
17598 diag::err_expected_class_or_namespace)
17599 << ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
17600 return ExprError();
17601 }
17602 SS.Extend(Context&: SemaRef.Context, TL: ScopeType->getTypeLoc(), ColonColonLoc: CCLoc);
17603 }
17604
17605 SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
17606 return getSema().BuildMemberReferenceExpr(Base, BaseType,
17607 OperatorLoc, isArrow,
17608 SS, TemplateKWLoc,
17609 /*FIXME: FirstQualifier*/ nullptr,
17610 NameInfo,
17611 /*TemplateArgs*/ nullptr,
17612 /*S*/nullptr);
17613}
17614
17615template<typename Derived>
17616StmtResult
17617TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
17618 SourceLocation Loc = S->getBeginLoc();
17619 CapturedDecl *CD = S->getCapturedDecl();
17620 unsigned NumParams = CD->getNumParams();
17621 unsigned ContextParamPos = CD->getContextParamPosition();
17622 SmallVector<Sema::CapturedParamNameType, 4> Params;
17623 for (unsigned I = 0; I < NumParams; ++I) {
17624 if (I != ContextParamPos) {
17625 Params.push_back(
17626 Elt: std::make_pair(
17627 CD->getParam(i: I)->getName(),
17628 getDerived().TransformType(CD->getParam(i: I)->getType())));
17629 } else {
17630 Params.push_back(Elt: std::make_pair(x: StringRef(), y: QualType()));
17631 }
17632 }
17633 getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/nullptr,
17634 S->getCapturedRegionKind(), Params);
17635 StmtResult Body;
17636 {
17637 Sema::CompoundScopeRAII CompoundScope(getSema());
17638 Body = getDerived().TransformStmt(S->getCapturedStmt());
17639 }
17640
17641 if (Body.isInvalid()) {
17642 getSema().ActOnCapturedRegionError();
17643 return StmtError();
17644 }
17645
17646 return getSema().ActOnCapturedRegionEnd(Body.get());
17647}
17648
17649template <typename Derived>
17650StmtResult
17651TreeTransform<Derived>::TransformSYCLKernelCallStmt(SYCLKernelCallStmt *S) {
17652 // SYCLKernelCallStmt nodes are inserted upon completion of a (non-template)
17653 // function definition or instantiation of a function template specialization
17654 // and will therefore never appear in a dependent context.
17655 llvm_unreachable("SYCL kernel call statement cannot appear in dependent "
17656 "context");
17657}
17658
17659template <typename Derived>
17660ExprResult TreeTransform<Derived>::TransformHLSLOutArgExpr(HLSLOutArgExpr *E) {
17661 // We can transform the base expression and allow argument resolution to fill
17662 // in the rest.
17663 return getDerived().TransformExpr(E->getArgLValue());
17664}
17665
17666} // end namespace clang
17667
17668#endif // LLVM_CLANG_LIB_SEMA_TREETRANSFORM_H
17669

source code of clang/lib/Sema/TreeTransform.h