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(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(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(Record);
1040 }
1041
1042 /// Build a new Enum type.
1043 QualType RebuildEnumType(EnumDecl *Enum) {
1044 return SemaRef.Context.getTypeDeclType(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, *S, 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(SomeDecl, Kind);
1225 SemaRef.Diag(IdLoc, diag::err_tag_reference_non_tag)
1226 << SomeDecl << NTK << Kind;
1227 SemaRef.Diag(SomeDecl->getLocation(), diag::note_declared_at);
1228 break;
1229 }
1230 default:
1231 SemaRef.Diag(IdLoc, 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(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
1241 SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
1242 return QualType();
1243 }
1244
1245 // Build the elaborated-type-specifier type.
1246 QualType T = SemaRef.Context.getTypeDeclType(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: Attrs))
1401 return StmtError();
1402 return SemaRef.BuildAttributedStmt(AttrsLoc: AttrLoc, Attrs: 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(Expr *NumThreads,
1718 SourceLocation StartLoc,
1719 SourceLocation LParenLoc,
1720 SourceLocation EndLoc) {
1721 return getSema().OpenMP().ActOnOpenMPNumThreadsClause(NumThreads, StartLoc,
1722 LParenLoc, EndLoc);
1723 }
1724
1725 /// Build a new OpenMP 'safelen' clause.
1726 ///
1727 /// By default, performs semantic analysis to build the new OpenMP clause.
1728 /// Subclasses may override this routine to provide different behavior.
1729 OMPClause *RebuildOMPSafelenClause(Expr *Len, SourceLocation StartLoc,
1730 SourceLocation LParenLoc,
1731 SourceLocation EndLoc) {
1732 return getSema().OpenMP().ActOnOpenMPSafelenClause(Len, StartLoc, LParenLoc,
1733 EndLoc);
1734 }
1735
1736 /// Build a new OpenMP 'simdlen' clause.
1737 ///
1738 /// By default, performs semantic analysis to build the new OpenMP clause.
1739 /// Subclasses may override this routine to provide different behavior.
1740 OMPClause *RebuildOMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
1741 SourceLocation LParenLoc,
1742 SourceLocation EndLoc) {
1743 return getSema().OpenMP().ActOnOpenMPSimdlenClause(Len, StartLoc, LParenLoc,
1744 EndLoc);
1745 }
1746
1747 OMPClause *RebuildOMPSizesClause(ArrayRef<Expr *> Sizes,
1748 SourceLocation StartLoc,
1749 SourceLocation LParenLoc,
1750 SourceLocation EndLoc) {
1751 return getSema().OpenMP().ActOnOpenMPSizesClause(Sizes, StartLoc, LParenLoc,
1752 EndLoc);
1753 }
1754
1755 /// Build a new OpenMP 'permutation' clause.
1756 OMPClause *RebuildOMPPermutationClause(ArrayRef<Expr *> PermExprs,
1757 SourceLocation StartLoc,
1758 SourceLocation LParenLoc,
1759 SourceLocation EndLoc) {
1760 return getSema().OpenMP().ActOnOpenMPPermutationClause(PermExprs, StartLoc,
1761 LParenLoc, EndLoc);
1762 }
1763
1764 /// Build a new OpenMP 'full' clause.
1765 OMPClause *RebuildOMPFullClause(SourceLocation StartLoc,
1766 SourceLocation EndLoc) {
1767 return getSema().OpenMP().ActOnOpenMPFullClause(StartLoc, EndLoc);
1768 }
1769
1770 /// Build a new OpenMP 'partial' clause.
1771 OMPClause *RebuildOMPPartialClause(Expr *Factor, SourceLocation StartLoc,
1772 SourceLocation LParenLoc,
1773 SourceLocation EndLoc) {
1774 return getSema().OpenMP().ActOnOpenMPPartialClause(Factor, StartLoc,
1775 LParenLoc, EndLoc);
1776 }
1777
1778 /// Build a new OpenMP 'allocator' clause.
1779 ///
1780 /// By default, performs semantic analysis to build the new OpenMP clause.
1781 /// Subclasses may override this routine to provide different behavior.
1782 OMPClause *RebuildOMPAllocatorClause(Expr *A, SourceLocation StartLoc,
1783 SourceLocation LParenLoc,
1784 SourceLocation EndLoc) {
1785 return getSema().OpenMP().ActOnOpenMPAllocatorClause(A, StartLoc, LParenLoc,
1786 EndLoc);
1787 }
1788
1789 /// Build a new OpenMP 'collapse' clause.
1790 ///
1791 /// By default, performs semantic analysis to build the new OpenMP clause.
1792 /// Subclasses may override this routine to provide different behavior.
1793 OMPClause *RebuildOMPCollapseClause(Expr *Num, SourceLocation StartLoc,
1794 SourceLocation LParenLoc,
1795 SourceLocation EndLoc) {
1796 return getSema().OpenMP().ActOnOpenMPCollapseClause(Num, StartLoc,
1797 LParenLoc, EndLoc);
1798 }
1799
1800 /// Build a new OpenMP 'default' clause.
1801 ///
1802 /// By default, performs semantic analysis to build the new OpenMP clause.
1803 /// Subclasses may override this routine to provide different behavior.
1804 OMPClause *RebuildOMPDefaultClause(DefaultKind Kind, SourceLocation KindKwLoc,
1805 SourceLocation StartLoc,
1806 SourceLocation LParenLoc,
1807 SourceLocation EndLoc) {
1808 return getSema().OpenMP().ActOnOpenMPDefaultClause(
1809 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1810 }
1811
1812 /// Build a new OpenMP 'proc_bind' clause.
1813 ///
1814 /// By default, performs semantic analysis to build the new OpenMP clause.
1815 /// Subclasses may override this routine to provide different behavior.
1816 OMPClause *RebuildOMPProcBindClause(ProcBindKind Kind,
1817 SourceLocation KindKwLoc,
1818 SourceLocation StartLoc,
1819 SourceLocation LParenLoc,
1820 SourceLocation EndLoc) {
1821 return getSema().OpenMP().ActOnOpenMPProcBindClause(
1822 Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
1823 }
1824
1825 /// Build a new OpenMP 'schedule' clause.
1826 ///
1827 /// By default, performs semantic analysis to build the new OpenMP clause.
1828 /// Subclasses may override this routine to provide different behavior.
1829 OMPClause *RebuildOMPScheduleClause(
1830 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
1831 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
1832 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
1833 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
1834 return getSema().OpenMP().ActOnOpenMPScheduleClause(
1835 M1, M2, Kind, ChunkSize, StartLoc, LParenLoc, M1Loc, M2Loc, KindLoc,
1836 CommaLoc, EndLoc);
1837 }
1838
1839 /// Build a new OpenMP 'ordered' clause.
1840 ///
1841 /// By default, performs semantic analysis to build the new OpenMP clause.
1842 /// Subclasses may override this routine to provide different behavior.
1843 OMPClause *RebuildOMPOrderedClause(SourceLocation StartLoc,
1844 SourceLocation EndLoc,
1845 SourceLocation LParenLoc, Expr *Num) {
1846 return getSema().OpenMP().ActOnOpenMPOrderedClause(StartLoc, EndLoc,
1847 LParenLoc, Num);
1848 }
1849
1850 /// Build a new OpenMP 'private' clause.
1851 ///
1852 /// By default, performs semantic analysis to build the new OpenMP clause.
1853 /// Subclasses may override this routine to provide different behavior.
1854 OMPClause *RebuildOMPPrivateClause(ArrayRef<Expr *> VarList,
1855 SourceLocation StartLoc,
1856 SourceLocation LParenLoc,
1857 SourceLocation EndLoc) {
1858 return getSema().OpenMP().ActOnOpenMPPrivateClause(VarList, StartLoc,
1859 LParenLoc, EndLoc);
1860 }
1861
1862 /// Build a new OpenMP 'firstprivate' clause.
1863 ///
1864 /// By default, performs semantic analysis to build the new OpenMP clause.
1865 /// Subclasses may override this routine to provide different behavior.
1866 OMPClause *RebuildOMPFirstprivateClause(ArrayRef<Expr *> VarList,
1867 SourceLocation StartLoc,
1868 SourceLocation LParenLoc,
1869 SourceLocation EndLoc) {
1870 return getSema().OpenMP().ActOnOpenMPFirstprivateClause(VarList, StartLoc,
1871 LParenLoc, EndLoc);
1872 }
1873
1874 /// Build a new OpenMP 'lastprivate' clause.
1875 ///
1876 /// By default, performs semantic analysis to build the new OpenMP clause.
1877 /// Subclasses may override this routine to provide different behavior.
1878 OMPClause *RebuildOMPLastprivateClause(ArrayRef<Expr *> VarList,
1879 OpenMPLastprivateModifier LPKind,
1880 SourceLocation LPKindLoc,
1881 SourceLocation ColonLoc,
1882 SourceLocation StartLoc,
1883 SourceLocation LParenLoc,
1884 SourceLocation EndLoc) {
1885 return getSema().OpenMP().ActOnOpenMPLastprivateClause(
1886 VarList, LPKind, LPKindLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
1887 }
1888
1889 /// Build a new OpenMP 'shared' clause.
1890 ///
1891 /// By default, performs semantic analysis to build the new OpenMP clause.
1892 /// Subclasses may override this routine to provide different behavior.
1893 OMPClause *RebuildOMPSharedClause(ArrayRef<Expr *> VarList,
1894 SourceLocation StartLoc,
1895 SourceLocation LParenLoc,
1896 SourceLocation EndLoc) {
1897 return getSema().OpenMP().ActOnOpenMPSharedClause(VarList, StartLoc,
1898 LParenLoc, EndLoc);
1899 }
1900
1901 /// Build a new OpenMP 'reduction' clause.
1902 ///
1903 /// By default, performs semantic analysis to build the new statement.
1904 /// Subclasses may override this routine to provide different behavior.
1905 OMPClause *RebuildOMPReductionClause(
1906 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
1907 OpenMPOriginalSharingModifier OriginalSharingModifier,
1908 SourceLocation StartLoc, SourceLocation LParenLoc,
1909 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1910 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
1911 const DeclarationNameInfo &ReductionId,
1912 ArrayRef<Expr *> UnresolvedReductions) {
1913 return getSema().OpenMP().ActOnOpenMPReductionClause(
1914 VarList, {Modifier, OriginalSharingModifier}, StartLoc, LParenLoc,
1915 ModifierLoc, ColonLoc, EndLoc, ReductionIdScopeSpec, ReductionId,
1916 UnresolvedReductions);
1917 }
1918
1919 /// Build a new OpenMP 'task_reduction' clause.
1920 ///
1921 /// By default, performs semantic analysis to build the new statement.
1922 /// Subclasses may override this routine to provide different behavior.
1923 OMPClause *RebuildOMPTaskReductionClause(
1924 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1925 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
1926 CXXScopeSpec &ReductionIdScopeSpec,
1927 const DeclarationNameInfo &ReductionId,
1928 ArrayRef<Expr *> UnresolvedReductions) {
1929 return getSema().OpenMP().ActOnOpenMPTaskReductionClause(
1930 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1931 ReductionId, UnresolvedReductions);
1932 }
1933
1934 /// Build a new OpenMP 'in_reduction' clause.
1935 ///
1936 /// By default, performs semantic analysis to build the new statement.
1937 /// Subclasses may override this routine to provide different behavior.
1938 OMPClause *
1939 RebuildOMPInReductionClause(ArrayRef<Expr *> VarList, SourceLocation StartLoc,
1940 SourceLocation LParenLoc, SourceLocation ColonLoc,
1941 SourceLocation EndLoc,
1942 CXXScopeSpec &ReductionIdScopeSpec,
1943 const DeclarationNameInfo &ReductionId,
1944 ArrayRef<Expr *> UnresolvedReductions) {
1945 return getSema().OpenMP().ActOnOpenMPInReductionClause(
1946 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
1947 ReductionId, UnresolvedReductions);
1948 }
1949
1950 /// Build a new OpenMP 'linear' clause.
1951 ///
1952 /// By default, performs semantic analysis to build the new OpenMP clause.
1953 /// Subclasses may override this routine to provide different behavior.
1954 OMPClause *RebuildOMPLinearClause(
1955 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
1956 SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier,
1957 SourceLocation ModifierLoc, SourceLocation ColonLoc,
1958 SourceLocation StepModifierLoc, SourceLocation EndLoc) {
1959 return getSema().OpenMP().ActOnOpenMPLinearClause(
1960 VarList, Step, StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc,
1961 StepModifierLoc, EndLoc);
1962 }
1963
1964 /// Build a new OpenMP 'aligned' clause.
1965 ///
1966 /// By default, performs semantic analysis to build the new OpenMP clause.
1967 /// Subclasses may override this routine to provide different behavior.
1968 OMPClause *RebuildOMPAlignedClause(ArrayRef<Expr *> VarList, Expr *Alignment,
1969 SourceLocation StartLoc,
1970 SourceLocation LParenLoc,
1971 SourceLocation ColonLoc,
1972 SourceLocation EndLoc) {
1973 return getSema().OpenMP().ActOnOpenMPAlignedClause(
1974 VarList, Alignment, StartLoc, LParenLoc, ColonLoc, EndLoc);
1975 }
1976
1977 /// Build a new OpenMP 'copyin' clause.
1978 ///
1979 /// By default, performs semantic analysis to build the new OpenMP clause.
1980 /// Subclasses may override this routine to provide different behavior.
1981 OMPClause *RebuildOMPCopyinClause(ArrayRef<Expr *> VarList,
1982 SourceLocation StartLoc,
1983 SourceLocation LParenLoc,
1984 SourceLocation EndLoc) {
1985 return getSema().OpenMP().ActOnOpenMPCopyinClause(VarList, StartLoc,
1986 LParenLoc, EndLoc);
1987 }
1988
1989 /// Build a new OpenMP 'copyprivate' clause.
1990 ///
1991 /// By default, performs semantic analysis to build the new OpenMP clause.
1992 /// Subclasses may override this routine to provide different behavior.
1993 OMPClause *RebuildOMPCopyprivateClause(ArrayRef<Expr *> VarList,
1994 SourceLocation StartLoc,
1995 SourceLocation LParenLoc,
1996 SourceLocation EndLoc) {
1997 return getSema().OpenMP().ActOnOpenMPCopyprivateClause(VarList, StartLoc,
1998 LParenLoc, EndLoc);
1999 }
2000
2001 /// Build a new OpenMP 'flush' pseudo clause.
2002 ///
2003 /// By default, performs semantic analysis to build the new OpenMP clause.
2004 /// Subclasses may override this routine to provide different behavior.
2005 OMPClause *RebuildOMPFlushClause(ArrayRef<Expr *> VarList,
2006 SourceLocation StartLoc,
2007 SourceLocation LParenLoc,
2008 SourceLocation EndLoc) {
2009 return getSema().OpenMP().ActOnOpenMPFlushClause(VarList, StartLoc,
2010 LParenLoc, EndLoc);
2011 }
2012
2013 /// Build a new OpenMP 'depobj' pseudo clause.
2014 ///
2015 /// By default, performs semantic analysis to build the new OpenMP clause.
2016 /// Subclasses may override this routine to provide different behavior.
2017 OMPClause *RebuildOMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
2018 SourceLocation LParenLoc,
2019 SourceLocation EndLoc) {
2020 return getSema().OpenMP().ActOnOpenMPDepobjClause(Depobj, StartLoc,
2021 LParenLoc, EndLoc);
2022 }
2023
2024 /// Build a new OpenMP 'depend' pseudo clause.
2025 ///
2026 /// By default, performs semantic analysis to build the new OpenMP clause.
2027 /// Subclasses may override this routine to provide different behavior.
2028 OMPClause *RebuildOMPDependClause(OMPDependClause::DependDataTy Data,
2029 Expr *DepModifier, ArrayRef<Expr *> VarList,
2030 SourceLocation StartLoc,
2031 SourceLocation LParenLoc,
2032 SourceLocation EndLoc) {
2033 return getSema().OpenMP().ActOnOpenMPDependClause(
2034 Data, DepModifier, VarList, StartLoc, LParenLoc, EndLoc);
2035 }
2036
2037 /// Build a new OpenMP 'device' clause.
2038 ///
2039 /// By default, performs semantic analysis to build the new statement.
2040 /// Subclasses may override this routine to provide different behavior.
2041 OMPClause *RebuildOMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
2042 Expr *Device, SourceLocation StartLoc,
2043 SourceLocation LParenLoc,
2044 SourceLocation ModifierLoc,
2045 SourceLocation EndLoc) {
2046 return getSema().OpenMP().ActOnOpenMPDeviceClause(
2047 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2048 }
2049
2050 /// Build a new OpenMP 'map' clause.
2051 ///
2052 /// By default, performs semantic analysis to build the new OpenMP clause.
2053 /// Subclasses may override this routine to provide different behavior.
2054 OMPClause *RebuildOMPMapClause(
2055 Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
2056 ArrayRef<SourceLocation> MapTypeModifiersLoc,
2057 CXXScopeSpec MapperIdScopeSpec, DeclarationNameInfo MapperId,
2058 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
2059 SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
2060 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
2061 return getSema().OpenMP().ActOnOpenMPMapClause(
2062 IteratorModifier, MapTypeModifiers, MapTypeModifiersLoc,
2063 MapperIdScopeSpec, MapperId, MapType, IsMapTypeImplicit, MapLoc,
2064 ColonLoc, VarList, Locs,
2065 /*NoDiagnose=*/false, UnresolvedMappers);
2066 }
2067
2068 /// Build a new OpenMP 'allocate' clause.
2069 ///
2070 /// By default, performs semantic analysis to build the new OpenMP clause.
2071 /// Subclasses may override this routine to provide different behavior.
2072 OMPClause *
2073 RebuildOMPAllocateClause(Expr *Allocate, Expr *Alignment,
2074 OpenMPAllocateClauseModifier FirstModifier,
2075 SourceLocation FirstModifierLoc,
2076 OpenMPAllocateClauseModifier SecondModifier,
2077 SourceLocation SecondModifierLoc,
2078 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2079 SourceLocation LParenLoc, SourceLocation ColonLoc,
2080 SourceLocation EndLoc) {
2081 return getSema().OpenMP().ActOnOpenMPAllocateClause(
2082 Allocate, Alignment, FirstModifier, FirstModifierLoc, SecondModifier,
2083 SecondModifierLoc, VarList, StartLoc, LParenLoc, ColonLoc, EndLoc);
2084 }
2085
2086 /// Build a new OpenMP 'num_teams' clause.
2087 ///
2088 /// By default, performs semantic analysis to build the new statement.
2089 /// Subclasses may override this routine to provide different behavior.
2090 OMPClause *RebuildOMPNumTeamsClause(ArrayRef<Expr *> VarList,
2091 SourceLocation StartLoc,
2092 SourceLocation LParenLoc,
2093 SourceLocation EndLoc) {
2094 return getSema().OpenMP().ActOnOpenMPNumTeamsClause(VarList, StartLoc,
2095 LParenLoc, EndLoc);
2096 }
2097
2098 /// Build a new OpenMP 'thread_limit' clause.
2099 ///
2100 /// By default, performs semantic analysis to build the new statement.
2101 /// Subclasses may override this routine to provide different behavior.
2102 OMPClause *RebuildOMPThreadLimitClause(ArrayRef<Expr *> VarList,
2103 SourceLocation StartLoc,
2104 SourceLocation LParenLoc,
2105 SourceLocation EndLoc) {
2106 return getSema().OpenMP().ActOnOpenMPThreadLimitClause(VarList, StartLoc,
2107 LParenLoc, EndLoc);
2108 }
2109
2110 /// Build a new OpenMP 'priority' clause.
2111 ///
2112 /// By default, performs semantic analysis to build the new statement.
2113 /// Subclasses may override this routine to provide different behavior.
2114 OMPClause *RebuildOMPPriorityClause(Expr *Priority, SourceLocation StartLoc,
2115 SourceLocation LParenLoc,
2116 SourceLocation EndLoc) {
2117 return getSema().OpenMP().ActOnOpenMPPriorityClause(Priority, StartLoc,
2118 LParenLoc, EndLoc);
2119 }
2120
2121 /// Build a new OpenMP 'grainsize' clause.
2122 ///
2123 /// By default, performs semantic analysis to build the new statement.
2124 /// Subclasses may override this routine to provide different behavior.
2125 OMPClause *RebuildOMPGrainsizeClause(OpenMPGrainsizeClauseModifier Modifier,
2126 Expr *Device, SourceLocation StartLoc,
2127 SourceLocation LParenLoc,
2128 SourceLocation ModifierLoc,
2129 SourceLocation EndLoc) {
2130 return getSema().OpenMP().ActOnOpenMPGrainsizeClause(
2131 Modifier, Device, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2132 }
2133
2134 /// Build a new OpenMP 'num_tasks' clause.
2135 ///
2136 /// By default, performs semantic analysis to build the new statement.
2137 /// Subclasses may override this routine to provide different behavior.
2138 OMPClause *RebuildOMPNumTasksClause(OpenMPNumTasksClauseModifier Modifier,
2139 Expr *NumTasks, SourceLocation StartLoc,
2140 SourceLocation LParenLoc,
2141 SourceLocation ModifierLoc,
2142 SourceLocation EndLoc) {
2143 return getSema().OpenMP().ActOnOpenMPNumTasksClause(
2144 Modifier, NumTasks, StartLoc, LParenLoc, ModifierLoc, EndLoc);
2145 }
2146
2147 /// Build a new OpenMP 'hint' clause.
2148 ///
2149 /// By default, performs semantic analysis to build the new statement.
2150 /// Subclasses may override this routine to provide different behavior.
2151 OMPClause *RebuildOMPHintClause(Expr *Hint, SourceLocation StartLoc,
2152 SourceLocation LParenLoc,
2153 SourceLocation EndLoc) {
2154 return getSema().OpenMP().ActOnOpenMPHintClause(Hint, StartLoc, LParenLoc,
2155 EndLoc);
2156 }
2157
2158 /// Build a new OpenMP 'detach' clause.
2159 ///
2160 /// By default, performs semantic analysis to build the new statement.
2161 /// Subclasses may override this routine to provide different behavior.
2162 OMPClause *RebuildOMPDetachClause(Expr *Evt, SourceLocation StartLoc,
2163 SourceLocation LParenLoc,
2164 SourceLocation EndLoc) {
2165 return getSema().OpenMP().ActOnOpenMPDetachClause(Evt, StartLoc, LParenLoc,
2166 EndLoc);
2167 }
2168
2169 /// Build a new OpenMP 'dist_schedule' clause.
2170 ///
2171 /// By default, performs semantic analysis to build the new OpenMP clause.
2172 /// Subclasses may override this routine to provide different behavior.
2173 OMPClause *
2174 RebuildOMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,
2175 Expr *ChunkSize, SourceLocation StartLoc,
2176 SourceLocation LParenLoc, SourceLocation KindLoc,
2177 SourceLocation CommaLoc, SourceLocation EndLoc) {
2178 return getSema().OpenMP().ActOnOpenMPDistScheduleClause(
2179 Kind, ChunkSize, StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc);
2180 }
2181
2182 /// Build a new OpenMP 'to' clause.
2183 ///
2184 /// By default, performs semantic analysis to build the new statement.
2185 /// Subclasses may override this routine to provide different behavior.
2186 OMPClause *
2187 RebuildOMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2188 ArrayRef<SourceLocation> MotionModifiersLoc,
2189 CXXScopeSpec &MapperIdScopeSpec,
2190 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2191 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2192 ArrayRef<Expr *> UnresolvedMappers) {
2193 return getSema().OpenMP().ActOnOpenMPToClause(
2194 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2195 ColonLoc, VarList, Locs, UnresolvedMappers);
2196 }
2197
2198 /// Build a new OpenMP 'from' clause.
2199 ///
2200 /// By default, performs semantic analysis to build the new statement.
2201 /// Subclasses may override this routine to provide different behavior.
2202 OMPClause *
2203 RebuildOMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
2204 ArrayRef<SourceLocation> MotionModifiersLoc,
2205 CXXScopeSpec &MapperIdScopeSpec,
2206 DeclarationNameInfo &MapperId, SourceLocation ColonLoc,
2207 ArrayRef<Expr *> VarList, const OMPVarListLocTy &Locs,
2208 ArrayRef<Expr *> UnresolvedMappers) {
2209 return getSema().OpenMP().ActOnOpenMPFromClause(
2210 MotionModifiers, MotionModifiersLoc, MapperIdScopeSpec, MapperId,
2211 ColonLoc, VarList, Locs, UnresolvedMappers);
2212 }
2213
2214 /// Build a new OpenMP 'use_device_ptr' clause.
2215 ///
2216 /// By default, performs semantic analysis to build the new OpenMP clause.
2217 /// Subclasses may override this routine to provide different behavior.
2218 OMPClause *RebuildOMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
2219 const OMPVarListLocTy &Locs) {
2220 return getSema().OpenMP().ActOnOpenMPUseDevicePtrClause(VarList, Locs);
2221 }
2222
2223 /// Build a new OpenMP 'use_device_addr' clause.
2224 ///
2225 /// By default, performs semantic analysis to build the new OpenMP clause.
2226 /// Subclasses may override this routine to provide different behavior.
2227 OMPClause *RebuildOMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
2228 const OMPVarListLocTy &Locs) {
2229 return getSema().OpenMP().ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
2230 }
2231
2232 /// Build a new OpenMP 'is_device_ptr' clause.
2233 ///
2234 /// By default, performs semantic analysis to build the new OpenMP clause.
2235 /// Subclasses may override this routine to provide different behavior.
2236 OMPClause *RebuildOMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
2237 const OMPVarListLocTy &Locs) {
2238 return getSema().OpenMP().ActOnOpenMPIsDevicePtrClause(VarList, Locs);
2239 }
2240
2241 /// Build a new OpenMP 'has_device_addr' clause.
2242 ///
2243 /// By default, performs semantic analysis to build the new OpenMP clause.
2244 /// Subclasses may override this routine to provide different behavior.
2245 OMPClause *RebuildOMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
2246 const OMPVarListLocTy &Locs) {
2247 return getSema().OpenMP().ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
2248 }
2249
2250 /// Build a new OpenMP 'defaultmap' clause.
2251 ///
2252 /// By default, performs semantic analysis to build the new OpenMP clause.
2253 /// Subclasses may override this routine to provide different behavior.
2254 OMPClause *RebuildOMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,
2255 OpenMPDefaultmapClauseKind Kind,
2256 SourceLocation StartLoc,
2257 SourceLocation LParenLoc,
2258 SourceLocation MLoc,
2259 SourceLocation KindLoc,
2260 SourceLocation EndLoc) {
2261 return getSema().OpenMP().ActOnOpenMPDefaultmapClause(
2262 M, Kind, StartLoc, LParenLoc, MLoc, KindLoc, EndLoc);
2263 }
2264
2265 /// Build a new OpenMP 'nontemporal' clause.
2266 ///
2267 /// By default, performs semantic analysis to build the new OpenMP clause.
2268 /// Subclasses may override this routine to provide different behavior.
2269 OMPClause *RebuildOMPNontemporalClause(ArrayRef<Expr *> VarList,
2270 SourceLocation StartLoc,
2271 SourceLocation LParenLoc,
2272 SourceLocation EndLoc) {
2273 return getSema().OpenMP().ActOnOpenMPNontemporalClause(VarList, StartLoc,
2274 LParenLoc, EndLoc);
2275 }
2276
2277 /// Build a new OpenMP 'inclusive' clause.
2278 ///
2279 /// By default, performs semantic analysis to build the new OpenMP clause.
2280 /// Subclasses may override this routine to provide different behavior.
2281 OMPClause *RebuildOMPInclusiveClause(ArrayRef<Expr *> VarList,
2282 SourceLocation StartLoc,
2283 SourceLocation LParenLoc,
2284 SourceLocation EndLoc) {
2285 return getSema().OpenMP().ActOnOpenMPInclusiveClause(VarList, StartLoc,
2286 LParenLoc, EndLoc);
2287 }
2288
2289 /// Build a new OpenMP 'exclusive' clause.
2290 ///
2291 /// By default, performs semantic analysis to build the new OpenMP clause.
2292 /// Subclasses may override this routine to provide different behavior.
2293 OMPClause *RebuildOMPExclusiveClause(ArrayRef<Expr *> VarList,
2294 SourceLocation StartLoc,
2295 SourceLocation LParenLoc,
2296 SourceLocation EndLoc) {
2297 return getSema().OpenMP().ActOnOpenMPExclusiveClause(VarList, StartLoc,
2298 LParenLoc, EndLoc);
2299 }
2300
2301 /// Build a new OpenMP 'uses_allocators' clause.
2302 ///
2303 /// By default, performs semantic analysis to build the new OpenMP clause.
2304 /// Subclasses may override this routine to provide different behavior.
2305 OMPClause *RebuildOMPUsesAllocatorsClause(
2306 ArrayRef<SemaOpenMP::UsesAllocatorsData> Data, SourceLocation StartLoc,
2307 SourceLocation LParenLoc, SourceLocation EndLoc) {
2308 return getSema().OpenMP().ActOnOpenMPUsesAllocatorClause(
2309 StartLoc, LParenLoc, EndLoc, Data);
2310 }
2311
2312 /// Build a new OpenMP 'affinity' clause.
2313 ///
2314 /// By default, performs semantic analysis to build the new OpenMP clause.
2315 /// Subclasses may override this routine to provide different behavior.
2316 OMPClause *RebuildOMPAffinityClause(SourceLocation StartLoc,
2317 SourceLocation LParenLoc,
2318 SourceLocation ColonLoc,
2319 SourceLocation EndLoc, Expr *Modifier,
2320 ArrayRef<Expr *> Locators) {
2321 return getSema().OpenMP().ActOnOpenMPAffinityClause(
2322 StartLoc, LParenLoc, ColonLoc, EndLoc, Modifier, Locators);
2323 }
2324
2325 /// Build a new OpenMP 'order' clause.
2326 ///
2327 /// By default, performs semantic analysis to build the new OpenMP clause.
2328 /// Subclasses may override this routine to provide different behavior.
2329 OMPClause *RebuildOMPOrderClause(
2330 OpenMPOrderClauseKind Kind, SourceLocation KindKwLoc,
2331 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
2332 OpenMPOrderClauseModifier Modifier, SourceLocation ModifierKwLoc) {
2333 return getSema().OpenMP().ActOnOpenMPOrderClause(
2334 Modifier, Kind, StartLoc, LParenLoc, ModifierKwLoc, KindKwLoc, EndLoc);
2335 }
2336
2337 /// Build a new OpenMP 'init' clause.
2338 ///
2339 /// By default, performs semantic analysis to build the new OpenMP clause.
2340 /// Subclasses may override this routine to provide different behavior.
2341 OMPClause *RebuildOMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
2342 SourceLocation StartLoc,
2343 SourceLocation LParenLoc,
2344 SourceLocation VarLoc,
2345 SourceLocation EndLoc) {
2346 return getSema().OpenMP().ActOnOpenMPInitClause(
2347 InteropVar, InteropInfo, StartLoc, LParenLoc, VarLoc, EndLoc);
2348 }
2349
2350 /// Build a new OpenMP 'use' clause.
2351 ///
2352 /// By default, performs semantic analysis to build the new OpenMP clause.
2353 /// Subclasses may override this routine to provide different behavior.
2354 OMPClause *RebuildOMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
2355 SourceLocation LParenLoc,
2356 SourceLocation VarLoc, SourceLocation EndLoc) {
2357 return getSema().OpenMP().ActOnOpenMPUseClause(InteropVar, StartLoc,
2358 LParenLoc, VarLoc, EndLoc);
2359 }
2360
2361 /// Build a new OpenMP 'destroy' clause.
2362 ///
2363 /// By default, performs semantic analysis to build the new OpenMP clause.
2364 /// Subclasses may override this routine to provide different behavior.
2365 OMPClause *RebuildOMPDestroyClause(Expr *InteropVar, SourceLocation StartLoc,
2366 SourceLocation LParenLoc,
2367 SourceLocation VarLoc,
2368 SourceLocation EndLoc) {
2369 return getSema().OpenMP().ActOnOpenMPDestroyClause(
2370 InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
2371 }
2372
2373 /// Build a new OpenMP 'novariants' clause.
2374 ///
2375 /// By default, performs semantic analysis to build the new OpenMP clause.
2376 /// Subclasses may override this routine to provide different behavior.
2377 OMPClause *RebuildOMPNovariantsClause(Expr *Condition,
2378 SourceLocation StartLoc,
2379 SourceLocation LParenLoc,
2380 SourceLocation EndLoc) {
2381 return getSema().OpenMP().ActOnOpenMPNovariantsClause(Condition, StartLoc,
2382 LParenLoc, EndLoc);
2383 }
2384
2385 /// Build a new OpenMP 'nocontext' clause.
2386 ///
2387 /// By default, performs semantic analysis to build the new OpenMP clause.
2388 /// Subclasses may override this routine to provide different behavior.
2389 OMPClause *RebuildOMPNocontextClause(Expr *Condition, SourceLocation StartLoc,
2390 SourceLocation LParenLoc,
2391 SourceLocation EndLoc) {
2392 return getSema().OpenMP().ActOnOpenMPNocontextClause(Condition, StartLoc,
2393 LParenLoc, EndLoc);
2394 }
2395
2396 /// Build a new OpenMP 'filter' clause.
2397 ///
2398 /// By default, performs semantic analysis to build the new OpenMP clause.
2399 /// Subclasses may override this routine to provide different behavior.
2400 OMPClause *RebuildOMPFilterClause(Expr *ThreadID, SourceLocation StartLoc,
2401 SourceLocation LParenLoc,
2402 SourceLocation EndLoc) {
2403 return getSema().OpenMP().ActOnOpenMPFilterClause(ThreadID, StartLoc,
2404 LParenLoc, EndLoc);
2405 }
2406
2407 /// Build a new OpenMP 'bind' clause.
2408 ///
2409 /// By default, performs semantic analysis to build the new OpenMP clause.
2410 /// Subclasses may override this routine to provide different behavior.
2411 OMPClause *RebuildOMPBindClause(OpenMPBindClauseKind Kind,
2412 SourceLocation KindLoc,
2413 SourceLocation StartLoc,
2414 SourceLocation LParenLoc,
2415 SourceLocation EndLoc) {
2416 return getSema().OpenMP().ActOnOpenMPBindClause(Kind, KindLoc, StartLoc,
2417 LParenLoc, EndLoc);
2418 }
2419
2420 /// Build a new OpenMP 'ompx_dyn_cgroup_mem' clause.
2421 ///
2422 /// By default, performs semantic analysis to build the new OpenMP clause.
2423 /// Subclasses may override this routine to provide different behavior.
2424 OMPClause *RebuildOMPXDynCGroupMemClause(Expr *Size, SourceLocation StartLoc,
2425 SourceLocation LParenLoc,
2426 SourceLocation EndLoc) {
2427 return getSema().OpenMP().ActOnOpenMPXDynCGroupMemClause(Size, StartLoc,
2428 LParenLoc, EndLoc);
2429 }
2430
2431 /// Build a new OpenMP 'ompx_attribute' clause.
2432 ///
2433 /// By default, performs semantic analysis to build the new OpenMP clause.
2434 /// Subclasses may override this routine to provide different behavior.
2435 OMPClause *RebuildOMPXAttributeClause(ArrayRef<const Attr *> Attrs,
2436 SourceLocation StartLoc,
2437 SourceLocation LParenLoc,
2438 SourceLocation EndLoc) {
2439 return getSema().OpenMP().ActOnOpenMPXAttributeClause(Attrs, StartLoc,
2440 LParenLoc, EndLoc);
2441 }
2442
2443 /// Build a new OpenMP 'ompx_bare' clause.
2444 ///
2445 /// By default, performs semantic analysis to build the new OpenMP clause.
2446 /// Subclasses may override this routine to provide different behavior.
2447 OMPClause *RebuildOMPXBareClause(SourceLocation StartLoc,
2448 SourceLocation EndLoc) {
2449 return getSema().OpenMP().ActOnOpenMPXBareClause(StartLoc, EndLoc);
2450 }
2451
2452 /// Build a new OpenMP 'align' clause.
2453 ///
2454 /// By default, performs semantic analysis to build the new OpenMP clause.
2455 /// Subclasses may override this routine to provide different behavior.
2456 OMPClause *RebuildOMPAlignClause(Expr *A, SourceLocation StartLoc,
2457 SourceLocation LParenLoc,
2458 SourceLocation EndLoc) {
2459 return getSema().OpenMP().ActOnOpenMPAlignClause(A, StartLoc, LParenLoc,
2460 EndLoc);
2461 }
2462
2463 /// Build a new OpenMP 'at' clause.
2464 ///
2465 /// By default, performs semantic analysis to build the new OpenMP clause.
2466 /// Subclasses may override this routine to provide different behavior.
2467 OMPClause *RebuildOMPAtClause(OpenMPAtClauseKind Kind, SourceLocation KwLoc,
2468 SourceLocation StartLoc,
2469 SourceLocation LParenLoc,
2470 SourceLocation EndLoc) {
2471 return getSema().OpenMP().ActOnOpenMPAtClause(Kind, KwLoc, StartLoc,
2472 LParenLoc, EndLoc);
2473 }
2474
2475 /// Build a new OpenMP 'severity' clause.
2476 ///
2477 /// By default, performs semantic analysis to build the new OpenMP clause.
2478 /// Subclasses may override this routine to provide different behavior.
2479 OMPClause *RebuildOMPSeverityClause(OpenMPSeverityClauseKind Kind,
2480 SourceLocation KwLoc,
2481 SourceLocation StartLoc,
2482 SourceLocation LParenLoc,
2483 SourceLocation EndLoc) {
2484 return getSema().OpenMP().ActOnOpenMPSeverityClause(Kind, KwLoc, StartLoc,
2485 LParenLoc, EndLoc);
2486 }
2487
2488 /// Build a new OpenMP 'message' clause.
2489 ///
2490 /// By default, performs semantic analysis to build the new OpenMP clause.
2491 /// Subclasses may override this routine to provide different behavior.
2492 OMPClause *RebuildOMPMessageClause(Expr *MS, SourceLocation StartLoc,
2493 SourceLocation LParenLoc,
2494 SourceLocation EndLoc) {
2495 return getSema().OpenMP().ActOnOpenMPMessageClause(MS, StartLoc, LParenLoc,
2496 EndLoc);
2497 }
2498
2499 /// Build a new OpenMP 'doacross' clause.
2500 ///
2501 /// By default, performs semantic analysis to build the new OpenMP clause.
2502 /// Subclasses may override this routine to provide different behavior.
2503 OMPClause *
2504 RebuildOMPDoacrossClause(OpenMPDoacrossClauseModifier DepType,
2505 SourceLocation DepLoc, SourceLocation ColonLoc,
2506 ArrayRef<Expr *> VarList, SourceLocation StartLoc,
2507 SourceLocation LParenLoc, SourceLocation EndLoc) {
2508 return getSema().OpenMP().ActOnOpenMPDoacrossClause(
2509 DepType, DepLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
2510 }
2511
2512 /// Build a new OpenMP 'holds' clause.
2513 OMPClause *RebuildOMPHoldsClause(Expr *A, SourceLocation StartLoc,
2514 SourceLocation LParenLoc,
2515 SourceLocation EndLoc) {
2516 return getSema().OpenMP().ActOnOpenMPHoldsClause(A, StartLoc, LParenLoc,
2517 EndLoc);
2518 }
2519
2520 /// Rebuild the operand to an Objective-C \@synchronized statement.
2521 ///
2522 /// By default, performs semantic analysis to build the new statement.
2523 /// Subclasses may override this routine to provide different behavior.
2524 ExprResult RebuildObjCAtSynchronizedOperand(SourceLocation atLoc,
2525 Expr *object) {
2526 return getSema().ObjC().ActOnObjCAtSynchronizedOperand(atLoc, object);
2527 }
2528
2529 /// Build a new Objective-C \@synchronized statement.
2530 ///
2531 /// By default, performs semantic analysis to build the new statement.
2532 /// Subclasses may override this routine to provide different behavior.
2533 StmtResult RebuildObjCAtSynchronizedStmt(SourceLocation AtLoc,
2534 Expr *Object, Stmt *Body) {
2535 return getSema().ObjC().ActOnObjCAtSynchronizedStmt(AtLoc, Object, Body);
2536 }
2537
2538 /// Build a new Objective-C \@autoreleasepool statement.
2539 ///
2540 /// By default, performs semantic analysis to build the new statement.
2541 /// Subclasses may override this routine to provide different behavior.
2542 StmtResult RebuildObjCAutoreleasePoolStmt(SourceLocation AtLoc,
2543 Stmt *Body) {
2544 return getSema().ObjC().ActOnObjCAutoreleasePoolStmt(AtLoc, Body);
2545 }
2546
2547 /// Build a new Objective-C fast enumeration statement.
2548 ///
2549 /// By default, performs semantic analysis to build the new statement.
2550 /// Subclasses may override this routine to provide different behavior.
2551 StmtResult RebuildObjCForCollectionStmt(SourceLocation ForLoc,
2552 Stmt *Element,
2553 Expr *Collection,
2554 SourceLocation RParenLoc,
2555 Stmt *Body) {
2556 StmtResult ForEachStmt = getSema().ObjC().ActOnObjCForCollectionStmt(
2557 ForLoc, Element, Collection, RParenLoc);
2558 if (ForEachStmt.isInvalid())
2559 return StmtError();
2560
2561 return getSema().ObjC().FinishObjCForCollectionStmt(ForEachStmt.get(),
2562 Body);
2563 }
2564
2565 /// Build a new C++ exception declaration.
2566 ///
2567 /// By default, performs semantic analysis to build the new decaration.
2568 /// Subclasses may override this routine to provide different behavior.
2569 VarDecl *RebuildExceptionDecl(VarDecl *ExceptionDecl,
2570 TypeSourceInfo *Declarator,
2571 SourceLocation StartLoc,
2572 SourceLocation IdLoc,
2573 IdentifierInfo *Id) {
2574 VarDecl *Var = getSema().BuildExceptionDeclaration(nullptr, Declarator,
2575 StartLoc, IdLoc, Id);
2576 if (Var)
2577 getSema().CurContext->addDecl(Var);
2578 return Var;
2579 }
2580
2581 /// Build a new C++ catch statement.
2582 ///
2583 /// By default, performs semantic analysis to build the new statement.
2584 /// Subclasses may override this routine to provide different behavior.
2585 StmtResult RebuildCXXCatchStmt(SourceLocation CatchLoc,
2586 VarDecl *ExceptionDecl,
2587 Stmt *Handler) {
2588 return Owned(new (getSema().Context) CXXCatchStmt(CatchLoc, ExceptionDecl,
2589 Handler));
2590 }
2591
2592 /// Build a new C++ try statement.
2593 ///
2594 /// By default, performs semantic analysis to build the new statement.
2595 /// Subclasses may override this routine to provide different behavior.
2596 StmtResult RebuildCXXTryStmt(SourceLocation TryLoc, Stmt *TryBlock,
2597 ArrayRef<Stmt *> Handlers) {
2598 return getSema().ActOnCXXTryBlock(TryLoc, TryBlock, Handlers);
2599 }
2600
2601 /// Build a new C++0x range-based for statement.
2602 ///
2603 /// By default, performs semantic analysis to build the new statement.
2604 /// Subclasses may override this routine to provide different behavior.
2605 StmtResult RebuildCXXForRangeStmt(
2606 SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *Init,
2607 SourceLocation ColonLoc, Stmt *Range, Stmt *Begin, Stmt *End, Expr *Cond,
2608 Expr *Inc, Stmt *LoopVar, SourceLocation RParenLoc,
2609 ArrayRef<MaterializeTemporaryExpr *> LifetimeExtendTemps) {
2610 // If we've just learned that the range is actually an Objective-C
2611 // collection, treat this as an Objective-C fast enumeration loop.
2612 if (DeclStmt *RangeStmt = dyn_cast<DeclStmt>(Range)) {
2613 if (RangeStmt->isSingleDecl()) {
2614 if (VarDecl *RangeVar = dyn_cast<VarDecl>(RangeStmt->getSingleDecl())) {
2615 if (RangeVar->isInvalidDecl())
2616 return StmtError();
2617
2618 Expr *RangeExpr = RangeVar->getInit();
2619 if (!RangeExpr->isTypeDependent() &&
2620 RangeExpr->getType()->isObjCObjectPointerType()) {
2621 // FIXME: Support init-statements in Objective-C++20 ranged for
2622 // statement.
2623 if (Init) {
2624 return SemaRef.Diag(Init->getBeginLoc(),
2625 diag::err_objc_for_range_init_stmt)
2626 << Init->getSourceRange();
2627 }
2628 return getSema().ObjC().ActOnObjCForCollectionStmt(
2629 ForLoc, LoopVar, RangeExpr, RParenLoc);
2630 }
2631 }
2632 }
2633 }
2634
2635 return getSema().BuildCXXForRangeStmt(
2636 ForLoc, CoawaitLoc, Init, ColonLoc, Range, Begin, End, Cond, Inc,
2637 LoopVar, RParenLoc, Sema::BFRK_Rebuild, LifetimeExtendTemps);
2638 }
2639
2640 /// Build a new C++0x range-based for statement.
2641 ///
2642 /// By default, performs semantic analysis to build the new statement.
2643 /// Subclasses may override this routine to provide different behavior.
2644 StmtResult RebuildMSDependentExistsStmt(SourceLocation KeywordLoc,
2645 bool IsIfExists,
2646 NestedNameSpecifierLoc QualifierLoc,
2647 DeclarationNameInfo NameInfo,
2648 Stmt *Nested) {
2649 return getSema().BuildMSDependentExistsStmt(KeywordLoc, IsIfExists,
2650 QualifierLoc, NameInfo, Nested);
2651 }
2652
2653 /// Attach body to a C++0x range-based for statement.
2654 ///
2655 /// By default, performs semantic analysis to finish the new statement.
2656 /// Subclasses may override this routine to provide different behavior.
2657 StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body) {
2658 return getSema().FinishCXXForRangeStmt(ForRange, Body);
2659 }
2660
2661 StmtResult RebuildSEHTryStmt(bool IsCXXTry, SourceLocation TryLoc,
2662 Stmt *TryBlock, Stmt *Handler) {
2663 return getSema().ActOnSEHTryBlock(IsCXXTry, TryLoc, TryBlock, Handler);
2664 }
2665
2666 StmtResult RebuildSEHExceptStmt(SourceLocation Loc, Expr *FilterExpr,
2667 Stmt *Block) {
2668 return getSema().ActOnSEHExceptBlock(Loc, FilterExpr, Block);
2669 }
2670
2671 StmtResult RebuildSEHFinallyStmt(SourceLocation Loc, Stmt *Block) {
2672 return SEHFinallyStmt::Create(C: getSema().getASTContext(), FinallyLoc: Loc, Block);
2673 }
2674
2675 ExprResult RebuildSYCLUniqueStableNameExpr(SourceLocation OpLoc,
2676 SourceLocation LParen,
2677 SourceLocation RParen,
2678 TypeSourceInfo *TSI) {
2679 return getSema().SYCL().BuildUniqueStableNameExpr(OpLoc, LParen, RParen,
2680 TSI);
2681 }
2682
2683 /// Build a new predefined expression.
2684 ///
2685 /// By default, performs semantic analysis to build the new expression.
2686 /// Subclasses may override this routine to provide different behavior.
2687 ExprResult RebuildPredefinedExpr(SourceLocation Loc, PredefinedIdentKind IK) {
2688 return getSema().BuildPredefinedExpr(Loc, IK);
2689 }
2690
2691 /// Build a new expression that references a declaration.
2692 ///
2693 /// By default, performs semantic analysis to build the new expression.
2694 /// Subclasses may override this routine to provide different behavior.
2695 ExprResult RebuildDeclarationNameExpr(const CXXScopeSpec &SS,
2696 LookupResult &R,
2697 bool RequiresADL) {
2698 return getSema().BuildDeclarationNameExpr(SS, R, RequiresADL);
2699 }
2700
2701
2702 /// Build a new expression that references a declaration.
2703 ///
2704 /// By default, performs semantic analysis to build the new expression.
2705 /// Subclasses may override this routine to provide different behavior.
2706 ExprResult RebuildDeclRefExpr(NestedNameSpecifierLoc QualifierLoc,
2707 ValueDecl *VD,
2708 const DeclarationNameInfo &NameInfo,
2709 NamedDecl *Found,
2710 TemplateArgumentListInfo *TemplateArgs) {
2711 CXXScopeSpec SS;
2712 SS.Adopt(Other: QualifierLoc);
2713 return getSema().BuildDeclarationNameExpr(SS, NameInfo, VD, Found,
2714 TemplateArgs);
2715 }
2716
2717 /// Build a new expression in parentheses.
2718 ///
2719 /// By default, performs semantic analysis to build the new expression.
2720 /// Subclasses may override this routine to provide different behavior.
2721 ExprResult RebuildParenExpr(Expr *SubExpr, SourceLocation LParen,
2722 SourceLocation RParen) {
2723 return getSema().ActOnParenExpr(LParen, RParen, SubExpr);
2724 }
2725
2726 /// Build a new pseudo-destructor expression.
2727 ///
2728 /// By default, performs semantic analysis to build the new expression.
2729 /// Subclasses may override this routine to provide different behavior.
2730 ExprResult RebuildCXXPseudoDestructorExpr(Expr *Base,
2731 SourceLocation OperatorLoc,
2732 bool isArrow,
2733 CXXScopeSpec &SS,
2734 TypeSourceInfo *ScopeType,
2735 SourceLocation CCLoc,
2736 SourceLocation TildeLoc,
2737 PseudoDestructorTypeStorage Destroyed);
2738
2739 /// Build a new unary operator expression.
2740 ///
2741 /// By default, performs semantic analysis to build the new expression.
2742 /// Subclasses may override this routine to provide different behavior.
2743 ExprResult RebuildUnaryOperator(SourceLocation OpLoc,
2744 UnaryOperatorKind Opc,
2745 Expr *SubExpr) {
2746 return getSema().BuildUnaryOp(/*Scope=*/nullptr, OpLoc, Opc, SubExpr);
2747 }
2748
2749 /// Build a new builtin offsetof expression.
2750 ///
2751 /// By default, performs semantic analysis to build the new expression.
2752 /// Subclasses may override this routine to provide different behavior.
2753 ExprResult RebuildOffsetOfExpr(SourceLocation OperatorLoc,
2754 TypeSourceInfo *Type,
2755 ArrayRef<Sema::OffsetOfComponent> Components,
2756 SourceLocation RParenLoc) {
2757 return getSema().BuildBuiltinOffsetOf(OperatorLoc, Type, Components,
2758 RParenLoc);
2759 }
2760
2761 /// Build a new sizeof, alignof or vec_step expression with a
2762 /// type argument.
2763 ///
2764 /// By default, performs semantic analysis to build the new expression.
2765 /// Subclasses may override this routine to provide different behavior.
2766 ExprResult RebuildUnaryExprOrTypeTrait(TypeSourceInfo *TInfo,
2767 SourceLocation OpLoc,
2768 UnaryExprOrTypeTrait ExprKind,
2769 SourceRange R) {
2770 return getSema().CreateUnaryExprOrTypeTraitExpr(TInfo, OpLoc, ExprKind, R);
2771 }
2772
2773 /// Build a new sizeof, alignof or vec step expression with an
2774 /// expression argument.
2775 ///
2776 /// By default, performs semantic analysis to build the new expression.
2777 /// Subclasses may override this routine to provide different behavior.
2778 ExprResult RebuildUnaryExprOrTypeTrait(Expr *SubExpr, SourceLocation OpLoc,
2779 UnaryExprOrTypeTrait ExprKind,
2780 SourceRange R) {
2781 ExprResult Result
2782 = getSema().CreateUnaryExprOrTypeTraitExpr(SubExpr, OpLoc, ExprKind);
2783 if (Result.isInvalid())
2784 return ExprError();
2785
2786 return Result;
2787 }
2788
2789 /// Build a new array subscript expression.
2790 ///
2791 /// By default, performs semantic analysis to build the new expression.
2792 /// Subclasses may override this routine to provide different behavior.
2793 ExprResult RebuildArraySubscriptExpr(Expr *LHS,
2794 SourceLocation LBracketLoc,
2795 Expr *RHS,
2796 SourceLocation RBracketLoc) {
2797 return getSema().ActOnArraySubscriptExpr(/*Scope=*/nullptr, LHS,
2798 LBracketLoc, RHS,
2799 RBracketLoc);
2800 }
2801
2802 /// Build a new matrix subscript expression.
2803 ///
2804 /// By default, performs semantic analysis to build the new expression.
2805 /// Subclasses may override this routine to provide different behavior.
2806 ExprResult RebuildMatrixSubscriptExpr(Expr *Base, Expr *RowIdx,
2807 Expr *ColumnIdx,
2808 SourceLocation RBracketLoc) {
2809 return getSema().CreateBuiltinMatrixSubscriptExpr(Base, RowIdx, ColumnIdx,
2810 RBracketLoc);
2811 }
2812
2813 /// Build a new array section expression.
2814 ///
2815 /// By default, performs semantic analysis to build the new expression.
2816 /// Subclasses may override this routine to provide different behavior.
2817 ExprResult RebuildArraySectionExpr(bool IsOMPArraySection, Expr *Base,
2818 SourceLocation LBracketLoc,
2819 Expr *LowerBound,
2820 SourceLocation ColonLocFirst,
2821 SourceLocation ColonLocSecond,
2822 Expr *Length, Expr *Stride,
2823 SourceLocation RBracketLoc) {
2824 if (IsOMPArraySection)
2825 return getSema().OpenMP().ActOnOMPArraySectionExpr(
2826 Base, LBracketLoc, LowerBound, ColonLocFirst, ColonLocSecond, Length,
2827 Stride, RBracketLoc);
2828
2829 assert(Stride == nullptr && !ColonLocSecond.isValid() &&
2830 "Stride/second colon not allowed for OpenACC");
2831
2832 return getSema().OpenACC().ActOnArraySectionExpr(
2833 Base, LBracketLoc, LowerBound, ColonLocFirst, Length, RBracketLoc);
2834 }
2835
2836 /// Build a new array shaping expression.
2837 ///
2838 /// By default, performs semantic analysis to build the new expression.
2839 /// Subclasses may override this routine to provide different behavior.
2840 ExprResult RebuildOMPArrayShapingExpr(Expr *Base, SourceLocation LParenLoc,
2841 SourceLocation RParenLoc,
2842 ArrayRef<Expr *> Dims,
2843 ArrayRef<SourceRange> BracketsRanges) {
2844 return getSema().OpenMP().ActOnOMPArrayShapingExpr(
2845 Base, LParenLoc, RParenLoc, Dims, BracketsRanges);
2846 }
2847
2848 /// Build a new iterator expression.
2849 ///
2850 /// By default, performs semantic analysis to build the new expression.
2851 /// Subclasses may override this routine to provide different behavior.
2852 ExprResult
2853 RebuildOMPIteratorExpr(SourceLocation IteratorKwLoc, SourceLocation LLoc,
2854 SourceLocation RLoc,
2855 ArrayRef<SemaOpenMP::OMPIteratorData> Data) {
2856 return getSema().OpenMP().ActOnOMPIteratorExpr(
2857 /*Scope=*/nullptr, IteratorKwLoc, LLoc, RLoc, Data);
2858 }
2859
2860 /// Build a new call expression.
2861 ///
2862 /// By default, performs semantic analysis to build the new expression.
2863 /// Subclasses may override this routine to provide different behavior.
2864 ExprResult RebuildCallExpr(Expr *Callee, SourceLocation LParenLoc,
2865 MultiExprArg Args,
2866 SourceLocation RParenLoc,
2867 Expr *ExecConfig = nullptr) {
2868 return getSema().ActOnCallExpr(
2869 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc, ExecConfig);
2870 }
2871
2872 ExprResult RebuildCxxSubscriptExpr(Expr *Callee, SourceLocation LParenLoc,
2873 MultiExprArg Args,
2874 SourceLocation RParenLoc) {
2875 return getSema().ActOnArraySubscriptExpr(
2876 /*Scope=*/nullptr, Callee, LParenLoc, Args, RParenLoc);
2877 }
2878
2879 /// Build a new member access expression.
2880 ///
2881 /// By default, performs semantic analysis to build the new expression.
2882 /// Subclasses may override this routine to provide different behavior.
2883 ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc,
2884 bool isArrow,
2885 NestedNameSpecifierLoc QualifierLoc,
2886 SourceLocation TemplateKWLoc,
2887 const DeclarationNameInfo &MemberNameInfo,
2888 ValueDecl *Member,
2889 NamedDecl *FoundDecl,
2890 const TemplateArgumentListInfo *ExplicitTemplateArgs,
2891 NamedDecl *FirstQualifierInScope) {
2892 ExprResult BaseResult = getSema().PerformMemberExprBaseConversion(Base,
2893 isArrow);
2894 if (!Member->getDeclName()) {
2895 // We have a reference to an unnamed field. This is always the
2896 // base of an anonymous struct/union member access, i.e. the
2897 // field is always of record type.
2898 assert(Member->getType()->isRecordType() &&
2899 "unnamed member not of record type?");
2900
2901 BaseResult =
2902 getSema().PerformObjectMemberConversion(BaseResult.get(),
2903 QualifierLoc.getNestedNameSpecifier(),
2904 FoundDecl, Member);
2905 if (BaseResult.isInvalid())
2906 return ExprError();
2907 Base = BaseResult.get();
2908
2909 // `TranformMaterializeTemporaryExpr()` removes materialized temporaries
2910 // from the AST, so we need to re-insert them if needed (since
2911 // `BuildFieldRefereneExpr()` doesn't do this).
2912 if (!isArrow && Base->isPRValue()) {
2913 BaseResult = getSema().TemporaryMaterializationConversion(Base);
2914 if (BaseResult.isInvalid())
2915 return ExprError();
2916 Base = BaseResult.get();
2917 }
2918
2919 CXXScopeSpec EmptySS;
2920 return getSema().BuildFieldReferenceExpr(
2921 Base, isArrow, OpLoc, EmptySS, cast<FieldDecl>(Member),
2922 DeclAccessPair::make(D: FoundDecl, AS: FoundDecl->getAccess()),
2923 MemberNameInfo);
2924 }
2925
2926 CXXScopeSpec SS;
2927 SS.Adopt(Other: QualifierLoc);
2928
2929 Base = BaseResult.get();
2930 if (Base->containsErrors())
2931 return ExprError();
2932
2933 QualType BaseType = Base->getType();
2934
2935 if (isArrow && !BaseType->isPointerType())
2936 return ExprError();
2937
2938 // FIXME: this involves duplicating earlier analysis in a lot of
2939 // cases; we should avoid this when possible.
2940 LookupResult R(getSema(), MemberNameInfo, Sema::LookupMemberName);
2941 R.addDecl(D: FoundDecl);
2942 R.resolveKind();
2943
2944 if (getSema().isUnevaluatedContext() && Base->isImplicitCXXThis() &&
2945 isa<FieldDecl, IndirectFieldDecl, MSPropertyDecl>(Member)) {
2946 if (auto *ThisClass = cast<CXXThisExpr>(Base)
2947 ->getType()
2948 ->getPointeeType()
2949 ->getAsCXXRecordDecl()) {
2950 auto *Class = cast<CXXRecordDecl>(Member->getDeclContext());
2951 // In unevaluated contexts, an expression supposed to be a member access
2952 // might reference a member in an unrelated class.
2953 if (!ThisClass->Equals(Class) && !ThisClass->isDerivedFrom(Class))
2954 return getSema().BuildDeclRefExpr(Member, Member->getType(),
2955 VK_LValue, Member->getLocation());
2956 }
2957 }
2958
2959 return getSema().BuildMemberReferenceExpr(Base, BaseType, OpLoc, isArrow,
2960 SS, TemplateKWLoc,
2961 FirstQualifierInScope,
2962 R, ExplicitTemplateArgs,
2963 /*S*/nullptr);
2964 }
2965
2966 /// Build a new binary operator expression.
2967 ///
2968 /// By default, performs semantic analysis to build the new expression.
2969 /// Subclasses may override this routine to provide different behavior.
2970 ExprResult RebuildBinaryOperator(SourceLocation OpLoc, BinaryOperatorKind Opc,
2971 Expr *LHS, Expr *RHS,
2972 bool ForFoldExpression = false) {
2973 return getSema().BuildBinOp(/*Scope=*/nullptr, OpLoc, Opc, LHS, RHS,
2974 ForFoldExpression);
2975 }
2976
2977 /// Build a new rewritten operator expression.
2978 ///
2979 /// By default, performs semantic analysis to build the new expression.
2980 /// Subclasses may override this routine to provide different behavior.
2981 ExprResult RebuildCXXRewrittenBinaryOperator(
2982 SourceLocation OpLoc, BinaryOperatorKind Opcode,
2983 const UnresolvedSetImpl &UnqualLookups, Expr *LHS, Expr *RHS) {
2984 return getSema().CreateOverloadedBinOp(OpLoc, Opcode, UnqualLookups, LHS,
2985 RHS, /*RequiresADL*/false);
2986 }
2987
2988 /// Build a new conditional operator expression.
2989 ///
2990 /// By default, performs semantic analysis to build the new expression.
2991 /// Subclasses may override this routine to provide different behavior.
2992 ExprResult RebuildConditionalOperator(Expr *Cond,
2993 SourceLocation QuestionLoc,
2994 Expr *LHS,
2995 SourceLocation ColonLoc,
2996 Expr *RHS) {
2997 return getSema().ActOnConditionalOp(QuestionLoc, ColonLoc, Cond,
2998 LHS, RHS);
2999 }
3000
3001 /// Build a new C-style cast expression.
3002 ///
3003 /// By default, performs semantic analysis to build the new expression.
3004 /// Subclasses may override this routine to provide different behavior.
3005 ExprResult RebuildCStyleCastExpr(SourceLocation LParenLoc,
3006 TypeSourceInfo *TInfo,
3007 SourceLocation RParenLoc,
3008 Expr *SubExpr) {
3009 return getSema().BuildCStyleCastExpr(LParenLoc, TInfo, RParenLoc,
3010 SubExpr);
3011 }
3012
3013 /// Build a new compound literal expression.
3014 ///
3015 /// By default, performs semantic analysis to build the new expression.
3016 /// Subclasses may override this routine to provide different behavior.
3017 ExprResult RebuildCompoundLiteralExpr(SourceLocation LParenLoc,
3018 TypeSourceInfo *TInfo,
3019 SourceLocation RParenLoc,
3020 Expr *Init) {
3021 return getSema().BuildCompoundLiteralExpr(LParenLoc, TInfo, RParenLoc,
3022 Init);
3023 }
3024
3025 /// Build a new extended vector element access expression.
3026 ///
3027 /// By default, performs semantic analysis to build the new expression.
3028 /// Subclasses may override this routine to provide different behavior.
3029 ExprResult RebuildExtVectorElementExpr(Expr *Base, SourceLocation OpLoc,
3030 bool IsArrow,
3031 SourceLocation AccessorLoc,
3032 IdentifierInfo &Accessor) {
3033
3034 CXXScopeSpec SS;
3035 DeclarationNameInfo NameInfo(&Accessor, AccessorLoc);
3036 return getSema().BuildMemberReferenceExpr(
3037 Base, Base->getType(), OpLoc, IsArrow, SS, SourceLocation(),
3038 /*FirstQualifierInScope*/ nullptr, NameInfo,
3039 /* TemplateArgs */ nullptr,
3040 /*S*/ nullptr);
3041 }
3042
3043 /// Build a new initializer list expression.
3044 ///
3045 /// By default, performs semantic analysis to build the new expression.
3046 /// Subclasses may override this routine to provide different behavior.
3047 ExprResult RebuildInitList(SourceLocation LBraceLoc,
3048 MultiExprArg Inits,
3049 SourceLocation RBraceLoc) {
3050 return SemaRef.BuildInitList(LBraceLoc, InitArgList: Inits, RBraceLoc);
3051 }
3052
3053 /// Build a new designated initializer expression.
3054 ///
3055 /// By default, performs semantic analysis to build the new expression.
3056 /// Subclasses may override this routine to provide different behavior.
3057 ExprResult RebuildDesignatedInitExpr(Designation &Desig,
3058 MultiExprArg ArrayExprs,
3059 SourceLocation EqualOrColonLoc,
3060 bool GNUSyntax,
3061 Expr *Init) {
3062 ExprResult Result
3063 = SemaRef.ActOnDesignatedInitializer(Desig, EqualOrColonLoc, GNUSyntax,
3064 Init);
3065 if (Result.isInvalid())
3066 return ExprError();
3067
3068 return Result;
3069 }
3070
3071 /// Build a new value-initialized expression.
3072 ///
3073 /// By default, builds the implicit value initialization without performing
3074 /// any semantic analysis. Subclasses may override this routine to provide
3075 /// different behavior.
3076 ExprResult RebuildImplicitValueInitExpr(QualType T) {
3077 return new (SemaRef.Context) ImplicitValueInitExpr(T);
3078 }
3079
3080 /// Build a new \c va_arg expression.
3081 ///
3082 /// By default, performs semantic analysis to build the new expression.
3083 /// Subclasses may override this routine to provide different behavior.
3084 ExprResult RebuildVAArgExpr(SourceLocation BuiltinLoc,
3085 Expr *SubExpr, TypeSourceInfo *TInfo,
3086 SourceLocation RParenLoc) {
3087 return getSema().BuildVAArgExpr(BuiltinLoc,
3088 SubExpr, TInfo,
3089 RParenLoc);
3090 }
3091
3092 /// Build a new expression list in parentheses.
3093 ///
3094 /// By default, performs semantic analysis to build the new expression.
3095 /// Subclasses may override this routine to provide different behavior.
3096 ExprResult RebuildParenListExpr(SourceLocation LParenLoc,
3097 MultiExprArg SubExprs,
3098 SourceLocation RParenLoc) {
3099 return getSema().ActOnParenListExpr(LParenLoc, RParenLoc, SubExprs);
3100 }
3101
3102 ExprResult RebuildCXXParenListInitExpr(ArrayRef<Expr *> Args, QualType T,
3103 unsigned NumUserSpecifiedExprs,
3104 SourceLocation InitLoc,
3105 SourceLocation LParenLoc,
3106 SourceLocation RParenLoc) {
3107 return getSema().ActOnCXXParenListInitExpr(Args, T, NumUserSpecifiedExprs,
3108 InitLoc, LParenLoc, RParenLoc);
3109 }
3110
3111 /// Build a new address-of-label expression.
3112 ///
3113 /// By default, performs semantic analysis, using the name of the label
3114 /// rather than attempting to map the label statement itself.
3115 /// Subclasses may override this routine to provide different behavior.
3116 ExprResult RebuildAddrLabelExpr(SourceLocation AmpAmpLoc,
3117 SourceLocation LabelLoc, LabelDecl *Label) {
3118 return getSema().ActOnAddrLabel(AmpAmpLoc, LabelLoc, Label);
3119 }
3120
3121 /// Build a new GNU statement expression.
3122 ///
3123 /// By default, performs semantic analysis to build the new expression.
3124 /// Subclasses may override this routine to provide different behavior.
3125 ExprResult RebuildStmtExpr(SourceLocation LParenLoc, Stmt *SubStmt,
3126 SourceLocation RParenLoc, unsigned TemplateDepth) {
3127 return getSema().BuildStmtExpr(LParenLoc, SubStmt, RParenLoc,
3128 TemplateDepth);
3129 }
3130
3131 /// Build a new __builtin_choose_expr expression.
3132 ///
3133 /// By default, performs semantic analysis to build the new expression.
3134 /// Subclasses may override this routine to provide different behavior.
3135 ExprResult RebuildChooseExpr(SourceLocation BuiltinLoc,
3136 Expr *Cond, Expr *LHS, Expr *RHS,
3137 SourceLocation RParenLoc) {
3138 return SemaRef.ActOnChooseExpr(BuiltinLoc,
3139 CondExpr: Cond, LHSExpr: LHS, RHSExpr: RHS,
3140 RPLoc: RParenLoc);
3141 }
3142
3143 /// Build a new generic selection expression with an expression predicate.
3144 ///
3145 /// By default, performs semantic analysis to build the new expression.
3146 /// Subclasses may override this routine to provide different behavior.
3147 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3148 SourceLocation DefaultLoc,
3149 SourceLocation RParenLoc,
3150 Expr *ControllingExpr,
3151 ArrayRef<TypeSourceInfo *> Types,
3152 ArrayRef<Expr *> Exprs) {
3153 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3154 /*PredicateIsExpr=*/true,
3155 ControllingExpr, Types, Exprs);
3156 }
3157
3158 /// Build a new generic selection expression with a type predicate.
3159 ///
3160 /// By default, performs semantic analysis to build the new expression.
3161 /// Subclasses may override this routine to provide different behavior.
3162 ExprResult RebuildGenericSelectionExpr(SourceLocation KeyLoc,
3163 SourceLocation DefaultLoc,
3164 SourceLocation RParenLoc,
3165 TypeSourceInfo *ControllingType,
3166 ArrayRef<TypeSourceInfo *> Types,
3167 ArrayRef<Expr *> Exprs) {
3168 return getSema().CreateGenericSelectionExpr(KeyLoc, DefaultLoc, RParenLoc,
3169 /*PredicateIsExpr=*/false,
3170 ControllingType, Types, Exprs);
3171 }
3172
3173 /// Build a new overloaded operator call expression.
3174 ///
3175 /// By default, performs semantic analysis to build the new expression.
3176 /// The semantic analysis provides the behavior of template instantiation,
3177 /// copying with transformations that turn what looks like an overloaded
3178 /// operator call into a use of a builtin operator, performing
3179 /// argument-dependent lookup, etc. Subclasses may override this routine to
3180 /// provide different behavior.
3181 ExprResult RebuildCXXOperatorCallExpr(OverloadedOperatorKind Op,
3182 SourceLocation OpLoc,
3183 SourceLocation CalleeLoc,
3184 bool RequiresADL,
3185 const UnresolvedSetImpl &Functions,
3186 Expr *First, Expr *Second);
3187
3188 /// Build a new C++ "named" cast expression, such as static_cast or
3189 /// reinterpret_cast.
3190 ///
3191 /// By default, this routine dispatches to one of the more-specific routines
3192 /// for a particular named case, e.g., RebuildCXXStaticCastExpr().
3193 /// Subclasses may override this routine to provide different behavior.
3194 ExprResult RebuildCXXNamedCastExpr(SourceLocation OpLoc,
3195 Stmt::StmtClass Class,
3196 SourceLocation LAngleLoc,
3197 TypeSourceInfo *TInfo,
3198 SourceLocation RAngleLoc,
3199 SourceLocation LParenLoc,
3200 Expr *SubExpr,
3201 SourceLocation RParenLoc) {
3202 switch (Class) {
3203 case Stmt::CXXStaticCastExprClass:
3204 return getDerived().RebuildCXXStaticCastExpr(OpLoc, LAngleLoc, TInfo,
3205 RAngleLoc, LParenLoc,
3206 SubExpr, RParenLoc);
3207
3208 case Stmt::CXXDynamicCastExprClass:
3209 return getDerived().RebuildCXXDynamicCastExpr(OpLoc, LAngleLoc, TInfo,
3210 RAngleLoc, LParenLoc,
3211 SubExpr, RParenLoc);
3212
3213 case Stmt::CXXReinterpretCastExprClass:
3214 return getDerived().RebuildCXXReinterpretCastExpr(OpLoc, LAngleLoc, TInfo,
3215 RAngleLoc, LParenLoc,
3216 SubExpr,
3217 RParenLoc);
3218
3219 case Stmt::CXXConstCastExprClass:
3220 return getDerived().RebuildCXXConstCastExpr(OpLoc, LAngleLoc, TInfo,
3221 RAngleLoc, LParenLoc,
3222 SubExpr, RParenLoc);
3223
3224 case Stmt::CXXAddrspaceCastExprClass:
3225 return getDerived().RebuildCXXAddrspaceCastExpr(
3226 OpLoc, LAngleLoc, TInfo, RAngleLoc, LParenLoc, SubExpr, RParenLoc);
3227
3228 default:
3229 llvm_unreachable("Invalid C++ named cast");
3230 }
3231 }
3232
3233 /// Build a new C++ static_cast expression.
3234 ///
3235 /// By default, performs semantic analysis to build the new expression.
3236 /// Subclasses may override this routine to provide different behavior.
3237 ExprResult RebuildCXXStaticCastExpr(SourceLocation OpLoc,
3238 SourceLocation LAngleLoc,
3239 TypeSourceInfo *TInfo,
3240 SourceLocation RAngleLoc,
3241 SourceLocation LParenLoc,
3242 Expr *SubExpr,
3243 SourceLocation RParenLoc) {
3244 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_static_cast,
3245 TInfo, SubExpr,
3246 SourceRange(LAngleLoc, RAngleLoc),
3247 SourceRange(LParenLoc, RParenLoc));
3248 }
3249
3250 /// Build a new C++ dynamic_cast expression.
3251 ///
3252 /// By default, performs semantic analysis to build the new expression.
3253 /// Subclasses may override this routine to provide different behavior.
3254 ExprResult RebuildCXXDynamicCastExpr(SourceLocation OpLoc,
3255 SourceLocation LAngleLoc,
3256 TypeSourceInfo *TInfo,
3257 SourceLocation RAngleLoc,
3258 SourceLocation LParenLoc,
3259 Expr *SubExpr,
3260 SourceLocation RParenLoc) {
3261 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_dynamic_cast,
3262 TInfo, SubExpr,
3263 SourceRange(LAngleLoc, RAngleLoc),
3264 SourceRange(LParenLoc, RParenLoc));
3265 }
3266
3267 /// Build a new C++ reinterpret_cast expression.
3268 ///
3269 /// By default, performs semantic analysis to build the new expression.
3270 /// Subclasses may override this routine to provide different behavior.
3271 ExprResult RebuildCXXReinterpretCastExpr(SourceLocation OpLoc,
3272 SourceLocation LAngleLoc,
3273 TypeSourceInfo *TInfo,
3274 SourceLocation RAngleLoc,
3275 SourceLocation LParenLoc,
3276 Expr *SubExpr,
3277 SourceLocation RParenLoc) {
3278 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_reinterpret_cast,
3279 TInfo, SubExpr,
3280 SourceRange(LAngleLoc, RAngleLoc),
3281 SourceRange(LParenLoc, RParenLoc));
3282 }
3283
3284 /// Build a new C++ const_cast expression.
3285 ///
3286 /// By default, performs semantic analysis to build the new expression.
3287 /// Subclasses may override this routine to provide different behavior.
3288 ExprResult RebuildCXXConstCastExpr(SourceLocation OpLoc,
3289 SourceLocation LAngleLoc,
3290 TypeSourceInfo *TInfo,
3291 SourceLocation RAngleLoc,
3292 SourceLocation LParenLoc,
3293 Expr *SubExpr,
3294 SourceLocation RParenLoc) {
3295 return getSema().BuildCXXNamedCast(OpLoc, tok::kw_const_cast,
3296 TInfo, SubExpr,
3297 SourceRange(LAngleLoc, RAngleLoc),
3298 SourceRange(LParenLoc, RParenLoc));
3299 }
3300
3301 ExprResult
3302 RebuildCXXAddrspaceCastExpr(SourceLocation OpLoc, SourceLocation LAngleLoc,
3303 TypeSourceInfo *TInfo, SourceLocation RAngleLoc,
3304 SourceLocation LParenLoc, Expr *SubExpr,
3305 SourceLocation RParenLoc) {
3306 return getSema().BuildCXXNamedCast(
3307 OpLoc, tok::kw_addrspace_cast, TInfo, SubExpr,
3308 SourceRange(LAngleLoc, RAngleLoc), SourceRange(LParenLoc, RParenLoc));
3309 }
3310
3311 /// Build a new C++ functional-style cast expression.
3312 ///
3313 /// By default, performs semantic analysis to build the new expression.
3314 /// Subclasses may override this routine to provide different behavior.
3315 ExprResult RebuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo,
3316 SourceLocation LParenLoc,
3317 Expr *Sub,
3318 SourceLocation RParenLoc,
3319 bool ListInitialization) {
3320 // If Sub is a ParenListExpr, then Sub is the syntatic form of a
3321 // CXXParenListInitExpr. Pass its expanded arguments so that the
3322 // CXXParenListInitExpr can be rebuilt.
3323 if (auto *PLE = dyn_cast<ParenListExpr>(Sub))
3324 return getSema().BuildCXXTypeConstructExpr(
3325 TInfo, LParenLoc, MultiExprArg(PLE->getExprs(), PLE->getNumExprs()),
3326 RParenLoc, ListInitialization);
3327
3328 if (auto *PLE = dyn_cast<CXXParenListInitExpr>(Sub))
3329 return getSema().BuildCXXTypeConstructExpr(
3330 TInfo, LParenLoc, PLE->getInitExprs(), RParenLoc, ListInitialization);
3331
3332 return getSema().BuildCXXTypeConstructExpr(TInfo, LParenLoc,
3333 MultiExprArg(&Sub, 1), RParenLoc,
3334 ListInitialization);
3335 }
3336
3337 /// Build a new C++ __builtin_bit_cast expression.
3338 ///
3339 /// By default, performs semantic analysis to build the new expression.
3340 /// Subclasses may override this routine to provide different behavior.
3341 ExprResult RebuildBuiltinBitCastExpr(SourceLocation KWLoc,
3342 TypeSourceInfo *TSI, Expr *Sub,
3343 SourceLocation RParenLoc) {
3344 return getSema().BuildBuiltinBitCastExpr(KWLoc, TSI, Sub, RParenLoc);
3345 }
3346
3347 /// Build a new C++ typeid(type) expression.
3348 ///
3349 /// By default, performs semantic analysis to build the new expression.
3350 /// Subclasses may override this routine to provide different behavior.
3351 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3352 SourceLocation TypeidLoc,
3353 TypeSourceInfo *Operand,
3354 SourceLocation RParenLoc) {
3355 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3356 RParenLoc);
3357 }
3358
3359
3360 /// Build a new C++ typeid(expr) expression.
3361 ///
3362 /// By default, performs semantic analysis to build the new expression.
3363 /// Subclasses may override this routine to provide different behavior.
3364 ExprResult RebuildCXXTypeidExpr(QualType TypeInfoType,
3365 SourceLocation TypeidLoc,
3366 Expr *Operand,
3367 SourceLocation RParenLoc) {
3368 return getSema().BuildCXXTypeId(TypeInfoType, TypeidLoc, Operand,
3369 RParenLoc);
3370 }
3371
3372 /// Build a new C++ __uuidof(type) expression.
3373 ///
3374 /// By default, performs semantic analysis to build the new expression.
3375 /// Subclasses may override this routine to provide different behavior.
3376 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3377 TypeSourceInfo *Operand,
3378 SourceLocation RParenLoc) {
3379 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3380 }
3381
3382 /// Build a new C++ __uuidof(expr) expression.
3383 ///
3384 /// By default, performs semantic analysis to build the new expression.
3385 /// Subclasses may override this routine to provide different behavior.
3386 ExprResult RebuildCXXUuidofExpr(QualType Type, SourceLocation TypeidLoc,
3387 Expr *Operand, SourceLocation RParenLoc) {
3388 return getSema().BuildCXXUuidof(Type, TypeidLoc, Operand, RParenLoc);
3389 }
3390
3391 /// Build a new C++ "this" expression.
3392 ///
3393 /// By default, performs semantic analysis to build a new "this" expression.
3394 /// Subclasses may override this routine to provide different behavior.
3395 ExprResult RebuildCXXThisExpr(SourceLocation ThisLoc,
3396 QualType ThisType,
3397 bool isImplicit) {
3398 if (getSema().CheckCXXThisType(ThisLoc, ThisType))
3399 return ExprError();
3400 return getSema().BuildCXXThisExpr(ThisLoc, ThisType, isImplicit);
3401 }
3402
3403 /// Build a new C++ throw expression.
3404 ///
3405 /// By default, performs semantic analysis to build the new expression.
3406 /// Subclasses may override this routine to provide different behavior.
3407 ExprResult RebuildCXXThrowExpr(SourceLocation ThrowLoc, Expr *Sub,
3408 bool IsThrownVariableInScope) {
3409 return getSema().BuildCXXThrow(ThrowLoc, Sub, IsThrownVariableInScope);
3410 }
3411
3412 /// Build a new C++ default-argument expression.
3413 ///
3414 /// By default, builds a new default-argument expression, which does not
3415 /// require any semantic analysis. Subclasses may override this routine to
3416 /// provide different behavior.
3417 ExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, ParmVarDecl *Param,
3418 Expr *RewrittenExpr) {
3419 return CXXDefaultArgExpr::Create(C: getSema().Context, Loc, Param,
3420 RewrittenExpr, UsedContext: getSema().CurContext);
3421 }
3422
3423 /// Build a new C++11 default-initialization expression.
3424 ///
3425 /// By default, builds a new default field initialization expression, which
3426 /// does not require any semantic analysis. Subclasses may override this
3427 /// routine to provide different behavior.
3428 ExprResult RebuildCXXDefaultInitExpr(SourceLocation Loc,
3429 FieldDecl *Field) {
3430 return getSema().BuildCXXDefaultInitExpr(Loc, Field);
3431 }
3432
3433 /// Build a new C++ zero-initialization expression.
3434 ///
3435 /// By default, performs semantic analysis to build the new expression.
3436 /// Subclasses may override this routine to provide different behavior.
3437 ExprResult RebuildCXXScalarValueInitExpr(TypeSourceInfo *TSInfo,
3438 SourceLocation LParenLoc,
3439 SourceLocation RParenLoc) {
3440 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, {}, RParenLoc,
3441 /*ListInitialization=*/false);
3442 }
3443
3444 /// Build a new C++ "new" expression.
3445 ///
3446 /// By default, performs semantic analysis to build the new expression.
3447 /// Subclasses may override this routine to provide different behavior.
3448 ExprResult RebuildCXXNewExpr(SourceLocation StartLoc, bool UseGlobal,
3449 SourceLocation PlacementLParen,
3450 MultiExprArg PlacementArgs,
3451 SourceLocation PlacementRParen,
3452 SourceRange TypeIdParens, QualType AllocatedType,
3453 TypeSourceInfo *AllocatedTypeInfo,
3454 std::optional<Expr *> ArraySize,
3455 SourceRange DirectInitRange, Expr *Initializer) {
3456 return getSema().BuildCXXNew(StartLoc, UseGlobal,
3457 PlacementLParen,
3458 PlacementArgs,
3459 PlacementRParen,
3460 TypeIdParens,
3461 AllocatedType,
3462 AllocatedTypeInfo,
3463 ArraySize,
3464 DirectInitRange,
3465 Initializer);
3466 }
3467
3468 /// Build a new C++ "delete" expression.
3469 ///
3470 /// By default, performs semantic analysis to build the new expression.
3471 /// Subclasses may override this routine to provide different behavior.
3472 ExprResult RebuildCXXDeleteExpr(SourceLocation StartLoc,
3473 bool IsGlobalDelete,
3474 bool IsArrayForm,
3475 Expr *Operand) {
3476 return getSema().ActOnCXXDelete(StartLoc, IsGlobalDelete, IsArrayForm,
3477 Operand);
3478 }
3479
3480 /// Build a new type trait expression.
3481 ///
3482 /// By default, performs semantic analysis to build the new expression.
3483 /// Subclasses may override this routine to provide different behavior.
3484 ExprResult RebuildTypeTrait(TypeTrait Trait,
3485 SourceLocation StartLoc,
3486 ArrayRef<TypeSourceInfo *> Args,
3487 SourceLocation RParenLoc) {
3488 return getSema().BuildTypeTrait(Trait, StartLoc, Args, RParenLoc);
3489 }
3490
3491 /// Build a new array type trait expression.
3492 ///
3493 /// By default, performs semantic analysis to build the new expression.
3494 /// Subclasses may override this routine to provide different behavior.
3495 ExprResult RebuildArrayTypeTrait(ArrayTypeTrait Trait,
3496 SourceLocation StartLoc,
3497 TypeSourceInfo *TSInfo,
3498 Expr *DimExpr,
3499 SourceLocation RParenLoc) {
3500 return getSema().BuildArrayTypeTrait(Trait, StartLoc, TSInfo, DimExpr, RParenLoc);
3501 }
3502
3503 /// Build a new expression trait expression.
3504 ///
3505 /// By default, performs semantic analysis to build the new expression.
3506 /// Subclasses may override this routine to provide different behavior.
3507 ExprResult RebuildExpressionTrait(ExpressionTrait Trait,
3508 SourceLocation StartLoc,
3509 Expr *Queried,
3510 SourceLocation RParenLoc) {
3511 return getSema().BuildExpressionTrait(Trait, StartLoc, Queried, RParenLoc);
3512 }
3513
3514 /// Build a new (previously unresolved) declaration reference
3515 /// expression.
3516 ///
3517 /// By default, performs semantic analysis to build the new expression.
3518 /// Subclasses may override this routine to provide different behavior.
3519 ExprResult RebuildDependentScopeDeclRefExpr(
3520 NestedNameSpecifierLoc QualifierLoc,
3521 SourceLocation TemplateKWLoc,
3522 const DeclarationNameInfo &NameInfo,
3523 const TemplateArgumentListInfo *TemplateArgs,
3524 bool IsAddressOfOperand,
3525 TypeSourceInfo **RecoveryTSI) {
3526 CXXScopeSpec SS;
3527 SS.Adopt(Other: QualifierLoc);
3528
3529 if (TemplateArgs || TemplateKWLoc.isValid())
3530 return getSema().BuildQualifiedTemplateIdExpr(
3531 SS, TemplateKWLoc, NameInfo, TemplateArgs, IsAddressOfOperand);
3532
3533 return getSema().BuildQualifiedDeclarationNameExpr(
3534 SS, NameInfo, IsAddressOfOperand, RecoveryTSI);
3535 }
3536
3537 /// Build a new template-id expression.
3538 ///
3539 /// By default, performs semantic analysis to build the new expression.
3540 /// Subclasses may override this routine to provide different behavior.
3541 ExprResult RebuildTemplateIdExpr(const CXXScopeSpec &SS,
3542 SourceLocation TemplateKWLoc,
3543 LookupResult &R,
3544 bool RequiresADL,
3545 const TemplateArgumentListInfo *TemplateArgs) {
3546 return getSema().BuildTemplateIdExpr(SS, TemplateKWLoc, R, RequiresADL,
3547 TemplateArgs);
3548 }
3549
3550 /// Build a new object-construction expression.
3551 ///
3552 /// By default, performs semantic analysis to build the new expression.
3553 /// Subclasses may override this routine to provide different behavior.
3554 ExprResult RebuildCXXConstructExpr(
3555 QualType T, SourceLocation Loc, CXXConstructorDecl *Constructor,
3556 bool IsElidable, MultiExprArg Args, bool HadMultipleCandidates,
3557 bool ListInitialization, bool StdInitListInitialization,
3558 bool RequiresZeroInit, CXXConstructionKind ConstructKind,
3559 SourceRange ParenRange) {
3560 // Reconstruct the constructor we originally found, which might be
3561 // different if this is a call to an inherited constructor.
3562 CXXConstructorDecl *FoundCtor = Constructor;
3563 if (Constructor->isInheritingConstructor())
3564 FoundCtor = Constructor->getInheritedConstructor().getConstructor();
3565
3566 SmallVector<Expr *, 8> ConvertedArgs;
3567 if (getSema().CompleteConstructorCall(FoundCtor, T, Args, Loc,
3568 ConvertedArgs))
3569 return ExprError();
3570
3571 return getSema().BuildCXXConstructExpr(Loc, T, Constructor,
3572 IsElidable,
3573 ConvertedArgs,
3574 HadMultipleCandidates,
3575 ListInitialization,
3576 StdInitListInitialization,
3577 RequiresZeroInit, ConstructKind,
3578 ParenRange);
3579 }
3580
3581 /// Build a new implicit construction via inherited constructor
3582 /// expression.
3583 ExprResult RebuildCXXInheritedCtorInitExpr(QualType T, SourceLocation Loc,
3584 CXXConstructorDecl *Constructor,
3585 bool ConstructsVBase,
3586 bool InheritedFromVBase) {
3587 return new (getSema().Context) CXXInheritedCtorInitExpr(
3588 Loc, T, Constructor, ConstructsVBase, InheritedFromVBase);
3589 }
3590
3591 /// Build a new object-construction expression.
3592 ///
3593 /// By default, performs semantic analysis to build the new expression.
3594 /// Subclasses may override this routine to provide different behavior.
3595 ExprResult RebuildCXXTemporaryObjectExpr(TypeSourceInfo *TSInfo,
3596 SourceLocation LParenOrBraceLoc,
3597 MultiExprArg Args,
3598 SourceLocation RParenOrBraceLoc,
3599 bool ListInitialization) {
3600 return getSema().BuildCXXTypeConstructExpr(
3601 TSInfo, LParenOrBraceLoc, Args, RParenOrBraceLoc, ListInitialization);
3602 }
3603
3604 /// Build a new object-construction expression.
3605 ///
3606 /// By default, performs semantic analysis to build the new expression.
3607 /// Subclasses may override this routine to provide different behavior.
3608 ExprResult RebuildCXXUnresolvedConstructExpr(TypeSourceInfo *TSInfo,
3609 SourceLocation LParenLoc,
3610 MultiExprArg Args,
3611 SourceLocation RParenLoc,
3612 bool ListInitialization) {
3613 return getSema().BuildCXXTypeConstructExpr(TSInfo, LParenLoc, Args,
3614 RParenLoc, ListInitialization);
3615 }
3616
3617 /// Build a new member reference expression.
3618 ///
3619 /// By default, performs semantic analysis to build the new expression.
3620 /// Subclasses may override this routine to provide different behavior.
3621 ExprResult RebuildCXXDependentScopeMemberExpr(Expr *BaseE,
3622 QualType BaseType,
3623 bool IsArrow,
3624 SourceLocation OperatorLoc,
3625 NestedNameSpecifierLoc QualifierLoc,
3626 SourceLocation TemplateKWLoc,
3627 NamedDecl *FirstQualifierInScope,
3628 const DeclarationNameInfo &MemberNameInfo,
3629 const TemplateArgumentListInfo *TemplateArgs) {
3630 CXXScopeSpec SS;
3631 SS.Adopt(Other: QualifierLoc);
3632
3633 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3634 OpLoc: OperatorLoc, IsArrow,
3635 SS, TemplateKWLoc,
3636 FirstQualifierInScope,
3637 NameInfo: MemberNameInfo,
3638 TemplateArgs, /*S*/S: nullptr);
3639 }
3640
3641 /// Build a new member reference expression.
3642 ///
3643 /// By default, performs semantic analysis to build the new expression.
3644 /// Subclasses may override this routine to provide different behavior.
3645 ExprResult RebuildUnresolvedMemberExpr(Expr *BaseE, QualType BaseType,
3646 SourceLocation OperatorLoc,
3647 bool IsArrow,
3648 NestedNameSpecifierLoc QualifierLoc,
3649 SourceLocation TemplateKWLoc,
3650 NamedDecl *FirstQualifierInScope,
3651 LookupResult &R,
3652 const TemplateArgumentListInfo *TemplateArgs) {
3653 CXXScopeSpec SS;
3654 SS.Adopt(Other: QualifierLoc);
3655
3656 return SemaRef.BuildMemberReferenceExpr(Base: BaseE, BaseType,
3657 OpLoc: OperatorLoc, IsArrow,
3658 SS, TemplateKWLoc,
3659 FirstQualifierInScope,
3660 R, TemplateArgs, /*S*/S: nullptr);
3661 }
3662
3663 /// Build a new noexcept expression.
3664 ///
3665 /// By default, performs semantic analysis to build the new expression.
3666 /// Subclasses may override this routine to provide different behavior.
3667 ExprResult RebuildCXXNoexceptExpr(SourceRange Range, Expr *Arg) {
3668 return SemaRef.BuildCXXNoexceptExpr(KeyLoc: Range.getBegin(), Operand: Arg, RParen: Range.getEnd());
3669 }
3670
3671 UnsignedOrNone
3672 ComputeSizeOfPackExprWithoutSubstitution(ArrayRef<TemplateArgument> PackArgs);
3673
3674 /// Build a new expression to compute the length of a parameter pack.
3675 ExprResult RebuildSizeOfPackExpr(SourceLocation OperatorLoc, NamedDecl *Pack,
3676 SourceLocation PackLoc,
3677 SourceLocation RParenLoc,
3678 UnsignedOrNone Length,
3679 ArrayRef<TemplateArgument> PartialArgs) {
3680 return SizeOfPackExpr::Create(Context&: SemaRef.Context, OperatorLoc, Pack, PackLoc,
3681 RParenLoc, Length, PartialArgs);
3682 }
3683
3684 ExprResult RebuildPackIndexingExpr(SourceLocation EllipsisLoc,
3685 SourceLocation RSquareLoc,
3686 Expr *PackIdExpression, Expr *IndexExpr,
3687 ArrayRef<Expr *> ExpandedExprs,
3688 bool FullySubstituted = false) {
3689 return getSema().BuildPackIndexingExpr(PackIdExpression, EllipsisLoc,
3690 IndexExpr, RSquareLoc, ExpandedExprs,
3691 FullySubstituted);
3692 }
3693
3694 /// Build a new expression representing a call to a source location
3695 /// builtin.
3696 ///
3697 /// By default, performs semantic analysis to build the new expression.
3698 /// Subclasses may override this routine to provide different behavior.
3699 ExprResult RebuildSourceLocExpr(SourceLocIdentKind Kind, QualType ResultTy,
3700 SourceLocation BuiltinLoc,
3701 SourceLocation RPLoc,
3702 DeclContext *ParentContext) {
3703 return getSema().BuildSourceLocExpr(Kind, ResultTy, BuiltinLoc, RPLoc,
3704 ParentContext);
3705 }
3706
3707 /// Build a new Objective-C boxed expression.
3708 ///
3709 /// By default, performs semantic analysis to build the new expression.
3710 /// Subclasses may override this routine to provide different behavior.
3711 ExprResult RebuildConceptSpecializationExpr(NestedNameSpecifierLoc NNS,
3712 SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
3713 NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
3714 TemplateArgumentListInfo *TALI) {
3715 CXXScopeSpec SS;
3716 SS.Adopt(Other: NNS);
3717 ExprResult Result = getSema().CheckConceptTemplateId(SS, TemplateKWLoc,
3718 ConceptNameInfo,
3719 FoundDecl,
3720 NamedConcept, TALI);
3721 if (Result.isInvalid())
3722 return ExprError();
3723 return Result;
3724 }
3725
3726 /// \brief Build a new requires expression.
3727 ///
3728 /// By default, performs semantic analysis to build the new expression.
3729 /// Subclasses may override this routine to provide different behavior.
3730 ExprResult RebuildRequiresExpr(SourceLocation RequiresKWLoc,
3731 RequiresExprBodyDecl *Body,
3732 SourceLocation LParenLoc,
3733 ArrayRef<ParmVarDecl *> LocalParameters,
3734 SourceLocation RParenLoc,
3735 ArrayRef<concepts::Requirement *> Requirements,
3736 SourceLocation ClosingBraceLoc) {
3737 return RequiresExpr::Create(SemaRef.Context, RequiresKWLoc, Body, LParenLoc,
3738 LocalParameters, RParenLoc, Requirements,
3739 ClosingBraceLoc);
3740 }
3741
3742 concepts::TypeRequirement *
3743 RebuildTypeRequirement(
3744 concepts::Requirement::SubstitutionDiagnostic *SubstDiag) {
3745 return SemaRef.BuildTypeRequirement(SubstDiag);
3746 }
3747
3748 concepts::TypeRequirement *RebuildTypeRequirement(TypeSourceInfo *T) {
3749 return SemaRef.BuildTypeRequirement(Type: T);
3750 }
3751
3752 concepts::ExprRequirement *
3753 RebuildExprRequirement(
3754 concepts::Requirement::SubstitutionDiagnostic *SubstDiag, bool IsSimple,
3755 SourceLocation NoexceptLoc,
3756 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3757 return SemaRef.BuildExprRequirement(SubstDiag, IsSimple, NoexceptLoc,
3758 std::move(Ret));
3759 }
3760
3761 concepts::ExprRequirement *
3762 RebuildExprRequirement(Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
3763 concepts::ExprRequirement::ReturnTypeRequirement Ret) {
3764 return SemaRef.BuildExprRequirement(E, IsSimple, NoexceptLoc,
3765 std::move(Ret));
3766 }
3767
3768 concepts::NestedRequirement *
3769 RebuildNestedRequirement(StringRef InvalidConstraintEntity,
3770 const ASTConstraintSatisfaction &Satisfaction) {
3771 return SemaRef.BuildNestedRequirement(InvalidConstraintEntity,
3772 Satisfaction);
3773 }
3774
3775 concepts::NestedRequirement *RebuildNestedRequirement(Expr *Constraint) {
3776 return SemaRef.BuildNestedRequirement(E: Constraint);
3777 }
3778
3779 /// \brief Build a new Objective-C boxed expression.
3780 ///
3781 /// By default, performs semantic analysis to build the new expression.
3782 /// Subclasses may override this routine to provide different behavior.
3783 ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
3784 return getSema().ObjC().BuildObjCBoxedExpr(SR, ValueExpr);
3785 }
3786
3787 /// Build a new Objective-C array literal.
3788 ///
3789 /// By default, performs semantic analysis to build the new expression.
3790 /// Subclasses may override this routine to provide different behavior.
3791 ExprResult RebuildObjCArrayLiteral(SourceRange Range,
3792 Expr **Elements, unsigned NumElements) {
3793 return getSema().ObjC().BuildObjCArrayLiteral(
3794 Range, MultiExprArg(Elements, NumElements));
3795 }
3796
3797 ExprResult RebuildObjCSubscriptRefExpr(SourceLocation RB,
3798 Expr *Base, Expr *Key,
3799 ObjCMethodDecl *getterMethod,
3800 ObjCMethodDecl *setterMethod) {
3801 return getSema().ObjC().BuildObjCSubscriptExpression(
3802 RB, Base, Key, getterMethod, setterMethod);
3803 }
3804
3805 /// Build a new Objective-C dictionary literal.
3806 ///
3807 /// By default, performs semantic analysis to build the new expression.
3808 /// Subclasses may override this routine to provide different behavior.
3809 ExprResult RebuildObjCDictionaryLiteral(SourceRange Range,
3810 MutableArrayRef<ObjCDictionaryElement> Elements) {
3811 return getSema().ObjC().BuildObjCDictionaryLiteral(Range, Elements);
3812 }
3813
3814 /// Build a new Objective-C \@encode expression.
3815 ///
3816 /// By default, performs semantic analysis to build the new expression.
3817 /// Subclasses may override this routine to provide different behavior.
3818 ExprResult RebuildObjCEncodeExpr(SourceLocation AtLoc,
3819 TypeSourceInfo *EncodeTypeInfo,
3820 SourceLocation RParenLoc) {
3821 return SemaRef.ObjC().BuildObjCEncodeExpression(AtLoc, EncodedTypeInfo: EncodeTypeInfo,
3822 RParenLoc);
3823 }
3824
3825 /// Build a new Objective-C class message.
3826 ExprResult RebuildObjCMessageExpr(TypeSourceInfo *ReceiverTypeInfo,
3827 Selector Sel,
3828 ArrayRef<SourceLocation> SelectorLocs,
3829 ObjCMethodDecl *Method,
3830 SourceLocation LBracLoc,
3831 MultiExprArg Args,
3832 SourceLocation RBracLoc) {
3833 return SemaRef.ObjC().BuildClassMessage(
3834 ReceiverTypeInfo, ReceiverType: ReceiverTypeInfo->getType(),
3835 /*SuperLoc=*/SuperLoc: SourceLocation(), Sel, Method, LBracLoc, SelectorLocs,
3836 RBracLoc, Args);
3837 }
3838
3839 /// Build a new Objective-C instance message.
3840 ExprResult RebuildObjCMessageExpr(Expr *Receiver,
3841 Selector Sel,
3842 ArrayRef<SourceLocation> SelectorLocs,
3843 ObjCMethodDecl *Method,
3844 SourceLocation LBracLoc,
3845 MultiExprArg Args,
3846 SourceLocation RBracLoc) {
3847 return SemaRef.ObjC().BuildInstanceMessage(Receiver, ReceiverType: Receiver->getType(),
3848 /*SuperLoc=*/SuperLoc: SourceLocation(),
3849 Sel, Method, LBracLoc,
3850 SelectorLocs, RBracLoc, Args);
3851 }
3852
3853 /// Build a new Objective-C instance/class message to 'super'.
3854 ExprResult RebuildObjCMessageExpr(SourceLocation SuperLoc,
3855 Selector Sel,
3856 ArrayRef<SourceLocation> SelectorLocs,
3857 QualType SuperType,
3858 ObjCMethodDecl *Method,
3859 SourceLocation LBracLoc,
3860 MultiExprArg Args,
3861 SourceLocation RBracLoc) {
3862 return Method->isInstanceMethod()
3863 ? SemaRef.ObjC().BuildInstanceMessage(
3864 Receiver: nullptr, ReceiverType: SuperType, SuperLoc, Sel, Method, LBracLoc,
3865 SelectorLocs, RBracLoc, Args)
3866 : SemaRef.ObjC().BuildClassMessage(ReceiverTypeInfo: nullptr, ReceiverType: SuperType, SuperLoc,
3867 Sel, Method, LBracLoc,
3868 SelectorLocs, RBracLoc, Args);
3869 }
3870
3871 /// Build a new Objective-C ivar reference expression.
3872 ///
3873 /// By default, performs semantic analysis to build the new expression.
3874 /// Subclasses may override this routine to provide different behavior.
3875 ExprResult RebuildObjCIvarRefExpr(Expr *BaseArg, ObjCIvarDecl *Ivar,
3876 SourceLocation IvarLoc,
3877 bool IsArrow, bool IsFreeIvar) {
3878 CXXScopeSpec SS;
3879 DeclarationNameInfo NameInfo(Ivar->getDeclName(), IvarLoc);
3880 ExprResult Result = getSema().BuildMemberReferenceExpr(
3881 BaseArg, BaseArg->getType(),
3882 /*FIXME:*/ IvarLoc, IsArrow, SS, SourceLocation(),
3883 /*FirstQualifierInScope=*/nullptr, NameInfo,
3884 /*TemplateArgs=*/nullptr,
3885 /*S=*/nullptr);
3886 if (IsFreeIvar && Result.isUsable())
3887 cast<ObjCIvarRefExpr>(Result.get())->setIsFreeIvar(IsFreeIvar);
3888 return Result;
3889 }
3890
3891 /// Build a new Objective-C property reference expression.
3892 ///
3893 /// By default, performs semantic analysis to build the new expression.
3894 /// Subclasses may override this routine to provide different behavior.
3895 ExprResult RebuildObjCPropertyRefExpr(Expr *BaseArg,
3896 ObjCPropertyDecl *Property,
3897 SourceLocation PropertyLoc) {
3898 CXXScopeSpec SS;
3899 DeclarationNameInfo NameInfo(Property->getDeclName(), PropertyLoc);
3900 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3901 /*FIXME:*/PropertyLoc,
3902 /*IsArrow=*/false,
3903 SS, SourceLocation(),
3904 /*FirstQualifierInScope=*/nullptr,
3905 NameInfo,
3906 /*TemplateArgs=*/nullptr,
3907 /*S=*/nullptr);
3908 }
3909
3910 /// Build a new Objective-C property reference expression.
3911 ///
3912 /// By default, performs semantic analysis to build the new expression.
3913 /// Subclasses may override this routine to provide different behavior.
3914 ExprResult RebuildObjCPropertyRefExpr(Expr *Base, QualType T,
3915 ObjCMethodDecl *Getter,
3916 ObjCMethodDecl *Setter,
3917 SourceLocation PropertyLoc) {
3918 // Since these expressions can only be value-dependent, we do not
3919 // need to perform semantic analysis again.
3920 return Owned(
3921 new (getSema().Context) ObjCPropertyRefExpr(Getter, Setter, T,
3922 VK_LValue, OK_ObjCProperty,
3923 PropertyLoc, Base));
3924 }
3925
3926 /// Build a new Objective-C "isa" expression.
3927 ///
3928 /// By default, performs semantic analysis to build the new expression.
3929 /// Subclasses may override this routine to provide different behavior.
3930 ExprResult RebuildObjCIsaExpr(Expr *BaseArg, SourceLocation IsaLoc,
3931 SourceLocation OpLoc, bool IsArrow) {
3932 CXXScopeSpec SS;
3933 DeclarationNameInfo NameInfo(&getSema().Context.Idents.get("isa"), IsaLoc);
3934 return getSema().BuildMemberReferenceExpr(BaseArg, BaseArg->getType(),
3935 OpLoc, IsArrow,
3936 SS, SourceLocation(),
3937 /*FirstQualifierInScope=*/nullptr,
3938 NameInfo,
3939 /*TemplateArgs=*/nullptr,
3940 /*S=*/nullptr);
3941 }
3942
3943 /// Build a new shuffle vector expression.
3944 ///
3945 /// By default, performs semantic analysis to build the new expression.
3946 /// Subclasses may override this routine to provide different behavior.
3947 ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc,
3948 MultiExprArg SubExprs,
3949 SourceLocation RParenLoc) {
3950 // Find the declaration for __builtin_shufflevector
3951 const IdentifierInfo &Name
3952 = SemaRef.Context.Idents.get(Name: "__builtin_shufflevector");
3953 TranslationUnitDecl *TUDecl = SemaRef.Context.getTranslationUnitDecl();
3954 DeclContext::lookup_result Lookup = TUDecl->lookup(DeclarationName(&Name));
3955 assert(!Lookup.empty() && "No __builtin_shufflevector?");
3956
3957 // Build a reference to the __builtin_shufflevector builtin
3958 FunctionDecl *Builtin = cast<FunctionDecl>(Lookup.front());
3959 Expr *Callee = new (SemaRef.Context)
3960 DeclRefExpr(SemaRef.Context, Builtin, false,
3961 SemaRef.Context.BuiltinFnTy, VK_PRValue, BuiltinLoc);
3962 QualType CalleePtrTy = SemaRef.Context.getPointerType(Builtin->getType());
3963 Callee = SemaRef.ImpCastExprToType(E: Callee, Type: CalleePtrTy,
3964 CK: CK_BuiltinFnToFnPtr).get();
3965
3966 // Build the CallExpr
3967 ExprResult TheCall = CallExpr::Create(
3968 Ctx: SemaRef.Context, Fn: Callee, Args: SubExprs, Ty: Builtin->getCallResultType(),
3969 VK: Expr::getValueKindForType(T: Builtin->getReturnType()), RParenLoc,
3970 FPFeatures: FPOptionsOverride());
3971
3972 // Type-check the __builtin_shufflevector expression.
3973 return SemaRef.BuiltinShuffleVector(TheCall: cast<CallExpr>(TheCall.get()));
3974 }
3975
3976 /// Build a new convert vector expression.
3977 ExprResult RebuildConvertVectorExpr(SourceLocation BuiltinLoc,
3978 Expr *SrcExpr, TypeSourceInfo *DstTInfo,
3979 SourceLocation RParenLoc) {
3980 return SemaRef.ConvertVectorExpr(E: SrcExpr, TInfo: DstTInfo, BuiltinLoc, RParenLoc);
3981 }
3982
3983 /// Build a new template argument pack expansion.
3984 ///
3985 /// By default, performs semantic analysis to build a new pack expansion
3986 /// for a template argument. Subclasses may override this routine to provide
3987 /// different behavior.
3988 TemplateArgumentLoc RebuildPackExpansion(TemplateArgumentLoc Pattern,
3989 SourceLocation EllipsisLoc,
3990 UnsignedOrNone NumExpansions) {
3991 switch (Pattern.getArgument().getKind()) {
3992 case TemplateArgument::Expression: {
3993 ExprResult Result
3994 = getSema().CheckPackExpansion(Pattern.getSourceExpression(),
3995 EllipsisLoc, NumExpansions);
3996 if (Result.isInvalid())
3997 return TemplateArgumentLoc();
3998
3999 return TemplateArgumentLoc(TemplateArgument(Result.get(),
4000 /*IsCanonical=*/false),
4001 Result.get());
4002 }
4003
4004 case TemplateArgument::Template:
4005 return TemplateArgumentLoc(
4006 SemaRef.Context,
4007 TemplateArgument(Pattern.getArgument().getAsTemplate(),
4008 NumExpansions),
4009 Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
4010 EllipsisLoc);
4011
4012 case TemplateArgument::Null:
4013 case TemplateArgument::Integral:
4014 case TemplateArgument::Declaration:
4015 case TemplateArgument::StructuralValue:
4016 case TemplateArgument::Pack:
4017 case TemplateArgument::TemplateExpansion:
4018 case TemplateArgument::NullPtr:
4019 llvm_unreachable("Pack expansion pattern has no parameter packs");
4020
4021 case TemplateArgument::Type:
4022 if (TypeSourceInfo *Expansion
4023 = getSema().CheckPackExpansion(Pattern.getTypeSourceInfo(),
4024 EllipsisLoc,
4025 NumExpansions))
4026 return TemplateArgumentLoc(TemplateArgument(Expansion->getType()),
4027 Expansion);
4028 break;
4029 }
4030
4031 return TemplateArgumentLoc();
4032 }
4033
4034 /// Build a new expression pack expansion.
4035 ///
4036 /// By default, performs semantic analysis to build a new pack expansion
4037 /// for an expression. Subclasses may override this routine to provide
4038 /// different behavior.
4039 ExprResult RebuildPackExpansion(Expr *Pattern, SourceLocation EllipsisLoc,
4040 UnsignedOrNone NumExpansions) {
4041 return getSema().CheckPackExpansion(Pattern, EllipsisLoc, NumExpansions);
4042 }
4043
4044 /// Build a new C++1z fold-expression.
4045 ///
4046 /// By default, performs semantic analysis in order to build a new fold
4047 /// expression.
4048 ExprResult RebuildCXXFoldExpr(UnresolvedLookupExpr *ULE,
4049 SourceLocation LParenLoc, Expr *LHS,
4050 BinaryOperatorKind Operator,
4051 SourceLocation EllipsisLoc, Expr *RHS,
4052 SourceLocation RParenLoc,
4053 UnsignedOrNone NumExpansions) {
4054 return getSema().BuildCXXFoldExpr(ULE, LParenLoc, LHS, Operator,
4055 EllipsisLoc, RHS, RParenLoc,
4056 NumExpansions);
4057 }
4058
4059 ExprResult RebuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
4060 LambdaScopeInfo *LSI) {
4061 for (ParmVarDecl *PVD : LSI->CallOperator->parameters()) {
4062 if (Expr *Init = PVD->getInit())
4063 LSI->ContainsUnexpandedParameterPack |=
4064 Init->containsUnexpandedParameterPack();
4065 else if (PVD->hasUninstantiatedDefaultArg())
4066 LSI->ContainsUnexpandedParameterPack |=
4067 PVD->getUninstantiatedDefaultArg()
4068 ->containsUnexpandedParameterPack();
4069 }
4070 return getSema().BuildLambdaExpr(StartLoc, EndLoc, LSI);
4071 }
4072
4073 /// Build an empty C++1z fold-expression with the given operator.
4074 ///
4075 /// By default, produces the fallback value for the fold-expression, or
4076 /// produce an error if there is no fallback value.
4077 ExprResult RebuildEmptyCXXFoldExpr(SourceLocation EllipsisLoc,
4078 BinaryOperatorKind Operator) {
4079 return getSema().BuildEmptyCXXFoldExpr(EllipsisLoc, Operator);
4080 }
4081
4082 /// Build a new atomic operation expression.
4083 ///
4084 /// By default, performs semantic analysis to build the new expression.
4085 /// Subclasses may override this routine to provide different behavior.
4086 ExprResult RebuildAtomicExpr(SourceLocation BuiltinLoc, MultiExprArg SubExprs,
4087 AtomicExpr::AtomicOp Op,
4088 SourceLocation RParenLoc) {
4089 // Use this for all of the locations, since we don't know the difference
4090 // between the call and the expr at this point.
4091 SourceRange Range{BuiltinLoc, RParenLoc};
4092 return getSema().BuildAtomicExpr(Range, Range, RParenLoc, SubExprs, Op,
4093 Sema::AtomicArgumentOrder::AST);
4094 }
4095
4096 ExprResult RebuildRecoveryExpr(SourceLocation BeginLoc, SourceLocation EndLoc,
4097 ArrayRef<Expr *> SubExprs, QualType Type) {
4098 return getSema().CreateRecoveryExpr(BeginLoc, EndLoc, SubExprs, Type);
4099 }
4100
4101 StmtResult RebuildOpenACCComputeConstruct(OpenACCDirectiveKind K,
4102 SourceLocation BeginLoc,
4103 SourceLocation DirLoc,
4104 SourceLocation EndLoc,
4105 ArrayRef<OpenACCClause *> Clauses,
4106 StmtResult StrBlock) {
4107 return getSema().OpenACC().ActOnEndStmtDirective(
4108 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4109 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, StrBlock);
4110 }
4111
4112 StmtResult RebuildOpenACCLoopConstruct(SourceLocation BeginLoc,
4113 SourceLocation DirLoc,
4114 SourceLocation EndLoc,
4115 ArrayRef<OpenACCClause *> Clauses,
4116 StmtResult Loop) {
4117 return getSema().OpenACC().ActOnEndStmtDirective(
4118 OpenACCDirectiveKind::Loop, BeginLoc, DirLoc, SourceLocation{},
4119 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4120 Clauses, Loop);
4121 }
4122
4123 StmtResult RebuildOpenACCCombinedConstruct(OpenACCDirectiveKind K,
4124 SourceLocation BeginLoc,
4125 SourceLocation DirLoc,
4126 SourceLocation EndLoc,
4127 ArrayRef<OpenACCClause *> Clauses,
4128 StmtResult Loop) {
4129 return getSema().OpenACC().ActOnEndStmtDirective(
4130 K, BeginLoc, DirLoc, SourceLocation{}, SourceLocation{}, {},
4131 OpenACCAtomicKind::None, SourceLocation{}, EndLoc, Clauses, Loop);
4132 }
4133
4134 StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc,
4135 SourceLocation DirLoc,
4136 SourceLocation EndLoc,
4137 ArrayRef<OpenACCClause *> Clauses,
4138 StmtResult StrBlock) {
4139 return getSema().OpenACC().ActOnEndStmtDirective(
4140 OpenACCDirectiveKind::Data, BeginLoc, DirLoc, SourceLocation{},
4141 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4142 Clauses, StrBlock);
4143 }
4144
4145 StmtResult
4146 RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc,
4147 SourceLocation DirLoc, SourceLocation EndLoc,
4148 ArrayRef<OpenACCClause *> Clauses) {
4149 return getSema().OpenACC().ActOnEndStmtDirective(
4150 OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, SourceLocation{},
4151 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4152 Clauses, {});
4153 }
4154
4155 StmtResult
4156 RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc,
4157 SourceLocation DirLoc, SourceLocation EndLoc,
4158 ArrayRef<OpenACCClause *> Clauses) {
4159 return getSema().OpenACC().ActOnEndStmtDirective(
4160 OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, SourceLocation{},
4161 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4162 Clauses, {});
4163 }
4164
4165 StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc,
4166 SourceLocation DirLoc,
4167 SourceLocation EndLoc,
4168 ArrayRef<OpenACCClause *> Clauses,
4169 StmtResult StrBlock) {
4170 return getSema().OpenACC().ActOnEndStmtDirective(
4171 OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, SourceLocation{},
4172 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4173 Clauses, StrBlock);
4174 }
4175
4176 StmtResult RebuildOpenACCInitConstruct(SourceLocation BeginLoc,
4177 SourceLocation DirLoc,
4178 SourceLocation EndLoc,
4179 ArrayRef<OpenACCClause *> Clauses) {
4180 return getSema().OpenACC().ActOnEndStmtDirective(
4181 OpenACCDirectiveKind::Init, BeginLoc, DirLoc, SourceLocation{},
4182 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4183 Clauses, {});
4184 }
4185
4186 StmtResult
4187 RebuildOpenACCShutdownConstruct(SourceLocation BeginLoc,
4188 SourceLocation DirLoc, SourceLocation EndLoc,
4189 ArrayRef<OpenACCClause *> Clauses) {
4190 return getSema().OpenACC().ActOnEndStmtDirective(
4191 OpenACCDirectiveKind::Shutdown, BeginLoc, DirLoc, SourceLocation{},
4192 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4193 Clauses, {});
4194 }
4195
4196 StmtResult RebuildOpenACCSetConstruct(SourceLocation BeginLoc,
4197 SourceLocation DirLoc,
4198 SourceLocation EndLoc,
4199 ArrayRef<OpenACCClause *> Clauses) {
4200 return getSema().OpenACC().ActOnEndStmtDirective(
4201 OpenACCDirectiveKind::Set, BeginLoc, DirLoc, SourceLocation{},
4202 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4203 Clauses, {});
4204 }
4205
4206 StmtResult RebuildOpenACCUpdateConstruct(SourceLocation BeginLoc,
4207 SourceLocation DirLoc,
4208 SourceLocation EndLoc,
4209 ArrayRef<OpenACCClause *> Clauses) {
4210 return getSema().OpenACC().ActOnEndStmtDirective(
4211 OpenACCDirectiveKind::Update, BeginLoc, DirLoc, SourceLocation{},
4212 SourceLocation{}, {}, OpenACCAtomicKind::None, SourceLocation{}, EndLoc,
4213 Clauses, {});
4214 }
4215
4216 StmtResult RebuildOpenACCWaitConstruct(
4217 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4218 Expr *DevNumExpr, SourceLocation QueuesLoc, ArrayRef<Expr *> QueueIdExprs,
4219 SourceLocation RParenLoc, SourceLocation EndLoc,
4220 ArrayRef<OpenACCClause *> Clauses) {
4221 llvm::SmallVector<Expr *> Exprs;
4222 Exprs.push_back(DevNumExpr);
4223 llvm::append_range(Exprs, QueueIdExprs);
4224 return getSema().OpenACC().ActOnEndStmtDirective(
4225 OpenACCDirectiveKind::Wait, BeginLoc, DirLoc, LParenLoc, QueuesLoc,
4226 Exprs, OpenACCAtomicKind::None, RParenLoc, EndLoc, Clauses, {});
4227 }
4228
4229 StmtResult RebuildOpenACCCacheConstruct(
4230 SourceLocation BeginLoc, SourceLocation DirLoc, SourceLocation LParenLoc,
4231 SourceLocation ReadOnlyLoc, ArrayRef<Expr *> VarList,
4232 SourceLocation RParenLoc, SourceLocation EndLoc) {
4233 return getSema().OpenACC().ActOnEndStmtDirective(
4234 OpenACCDirectiveKind::Cache, BeginLoc, DirLoc, LParenLoc, ReadOnlyLoc,
4235 VarList, OpenACCAtomicKind::None, RParenLoc, EndLoc, {}, {});
4236 }
4237
4238 StmtResult RebuildOpenACCAtomicConstruct(SourceLocation BeginLoc,
4239 SourceLocation DirLoc,
4240 OpenACCAtomicKind AtKind,
4241 SourceLocation EndLoc,
4242 ArrayRef<OpenACCClause *> Clauses,
4243 StmtResult AssociatedStmt) {
4244 return getSema().OpenACC().ActOnEndStmtDirective(
4245 OpenACCDirectiveKind::Atomic, BeginLoc, DirLoc, SourceLocation{},
4246 SourceLocation{}, {}, AtKind, SourceLocation{}, EndLoc, Clauses,
4247 AssociatedStmt);
4248 }
4249
4250 ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) {
4251 return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc);
4252 }
4253
4254private:
4255 TypeLoc TransformTypeInObjectScope(TypeLoc TL,
4256 QualType ObjectType,
4257 NamedDecl *FirstQualifierInScope,
4258 CXXScopeSpec &SS);
4259
4260 TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
4261 QualType ObjectType,
4262 NamedDecl *FirstQualifierInScope,
4263 CXXScopeSpec &SS);
4264
4265 TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
4266 NamedDecl *FirstQualifierInScope,
4267 CXXScopeSpec &SS);
4268
4269 QualType TransformDependentNameType(TypeLocBuilder &TLB,
4270 DependentNameTypeLoc TL,
4271 bool DeducibleTSTContext);
4272
4273 llvm::SmallVector<OpenACCClause *>
4274 TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
4275 ArrayRef<const OpenACCClause *> OldClauses);
4276
4277 OpenACCClause *
4278 TransformOpenACCClause(ArrayRef<const OpenACCClause *> ExistingClauses,
4279 OpenACCDirectiveKind DirKind,
4280 const OpenACCClause *OldClause);
4281};
4282
4283template <typename Derived>
4284StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, StmtDiscardKind SDK) {
4285 if (!S)
4286 return S;
4287
4288 switch (S->getStmtClass()) {
4289 case Stmt::NoStmtClass: break;
4290
4291 // Transform individual statement nodes
4292 // Pass SDK into statements that can produce a value
4293#define STMT(Node, Parent) \
4294 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(S));
4295#define VALUESTMT(Node, Parent) \
4296 case Stmt::Node##Class: \
4297 return getDerived().Transform##Node(cast<Node>(S), SDK);
4298#define ABSTRACT_STMT(Node)
4299#define EXPR(Node, Parent)
4300#include "clang/AST/StmtNodes.inc"
4301
4302 // Transform expressions by calling TransformExpr.
4303#define STMT(Node, Parent)
4304#define ABSTRACT_STMT(Stmt)
4305#define EXPR(Node, Parent) case Stmt::Node##Class:
4306#include "clang/AST/StmtNodes.inc"
4307 {
4308 ExprResult E = getDerived().TransformExpr(cast<Expr>(S));
4309
4310 if (SDK == StmtDiscardKind::StmtExprResult)
4311 E = getSema().ActOnStmtExprResult(E);
4312 return getSema().ActOnExprStmt(E, SDK == StmtDiscardKind::Discarded);
4313 }
4314 }
4315
4316 return S;
4317}
4318
4319template<typename Derived>
4320OMPClause *TreeTransform<Derived>::TransformOMPClause(OMPClause *S) {
4321 if (!S)
4322 return S;
4323
4324 switch (S->getClauseKind()) {
4325 default: break;
4326 // Transform individual clause nodes
4327#define GEN_CLANG_CLAUSE_CLASS
4328#define CLAUSE_CLASS(Enum, Str, Class) \
4329 case Enum: \
4330 return getDerived().Transform##Class(cast<Class>(S));
4331#include "llvm/Frontend/OpenMP/OMP.inc"
4332 }
4333
4334 return S;
4335}
4336
4337
4338template<typename Derived>
4339ExprResult TreeTransform<Derived>::TransformExpr(Expr *E) {
4340 if (!E)
4341 return E;
4342
4343 switch (E->getStmtClass()) {
4344 case Stmt::NoStmtClass: break;
4345#define STMT(Node, Parent) case Stmt::Node##Class: break;
4346#define ABSTRACT_STMT(Stmt)
4347#define EXPR(Node, Parent) \
4348 case Stmt::Node##Class: return getDerived().Transform##Node(cast<Node>(E));
4349#include "clang/AST/StmtNodes.inc"
4350 }
4351
4352 return E;
4353}
4354
4355template<typename Derived>
4356ExprResult TreeTransform<Derived>::TransformInitializer(Expr *Init,
4357 bool NotCopyInit) {
4358 // Initializers are instantiated like expressions, except that various outer
4359 // layers are stripped.
4360 if (!Init)
4361 return Init;
4362
4363 if (auto *FE = dyn_cast<FullExpr>(Init))
4364 Init = FE->getSubExpr();
4365
4366 if (auto *AIL = dyn_cast<ArrayInitLoopExpr>(Init)) {
4367 OpaqueValueExpr *OVE = AIL->getCommonExpr();
4368 Init = OVE->getSourceExpr();
4369 }
4370
4371 if (MaterializeTemporaryExpr *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
4372 Init = MTE->getSubExpr();
4373
4374 while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init))
4375 Init = Binder->getSubExpr();
4376
4377 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init))
4378 Init = ICE->getSubExprAsWritten();
4379
4380 if (CXXStdInitializerListExpr *ILE =
4381 dyn_cast<CXXStdInitializerListExpr>(Init))
4382 return TransformInitializer(Init: ILE->getSubExpr(), NotCopyInit);
4383
4384 // If this is copy-initialization, we only need to reconstruct
4385 // InitListExprs. Other forms of copy-initialization will be a no-op if
4386 // the initializer is already the right type.
4387 CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init);
4388 if (!NotCopyInit && !(Construct && Construct->isListInitialization()))
4389 return getDerived().TransformExpr(Init);
4390
4391 // Revert value-initialization back to empty parens.
4392 if (CXXScalarValueInitExpr *VIE = dyn_cast<CXXScalarValueInitExpr>(Init)) {
4393 SourceRange Parens = VIE->getSourceRange();
4394 return getDerived().RebuildParenListExpr(Parens.getBegin(), {},
4395 Parens.getEnd());
4396 }
4397
4398 // FIXME: We shouldn't build ImplicitValueInitExprs for direct-initialization.
4399 if (isa<ImplicitValueInitExpr>(Init))
4400 return getDerived().RebuildParenListExpr(SourceLocation(), {},
4401 SourceLocation());
4402
4403 // Revert initialization by constructor back to a parenthesized or braced list
4404 // of expressions. Any other form of initializer can just be reused directly.
4405 if (!Construct || isa<CXXTemporaryObjectExpr>(Construct))
4406 return getDerived().TransformExpr(Init);
4407
4408 // If the initialization implicitly converted an initializer list to a
4409 // std::initializer_list object, unwrap the std::initializer_list too.
4410 if (Construct && Construct->isStdInitListInitialization())
4411 return TransformInitializer(Init: Construct->getArg(Arg: 0), NotCopyInit);
4412
4413 // Enter a list-init context if this was list initialization.
4414 EnterExpressionEvaluationContext Context(
4415 getSema(), EnterExpressionEvaluationContext::InitList,
4416 Construct->isListInitialization());
4417
4418 getSema().currentEvaluationContext().InLifetimeExtendingContext =
4419 getSema().parentEvaluationContext().InLifetimeExtendingContext;
4420 getSema().currentEvaluationContext().RebuildDefaultArgOrDefaultInit =
4421 getSema().parentEvaluationContext().RebuildDefaultArgOrDefaultInit;
4422 SmallVector<Expr*, 8> NewArgs;
4423 bool ArgChanged = false;
4424 if (getDerived().TransformExprs(Construct->getArgs(), Construct->getNumArgs(),
4425 /*IsCall*/true, NewArgs, &ArgChanged))
4426 return ExprError();
4427
4428 // If this was list initialization, revert to syntactic list form.
4429 if (Construct->isListInitialization())
4430 return getDerived().RebuildInitList(Construct->getBeginLoc(), NewArgs,
4431 Construct->getEndLoc());
4432
4433 // Build a ParenListExpr to represent anything else.
4434 SourceRange Parens = Construct->getParenOrBraceRange();
4435 if (Parens.isInvalid()) {
4436 // This was a variable declaration's initialization for which no initializer
4437 // was specified.
4438 assert(NewArgs.empty() &&
4439 "no parens or braces but have direct init with arguments?");
4440 return ExprEmpty();
4441 }
4442 return getDerived().RebuildParenListExpr(Parens.getBegin(), NewArgs,
4443 Parens.getEnd());
4444}
4445
4446template<typename Derived>
4447bool TreeTransform<Derived>::TransformExprs(Expr *const *Inputs,
4448 unsigned NumInputs,
4449 bool IsCall,
4450 SmallVectorImpl<Expr *> &Outputs,
4451 bool *ArgChanged) {
4452 for (unsigned I = 0; I != NumInputs; ++I) {
4453 // If requested, drop call arguments that need to be dropped.
4454 if (IsCall && getDerived().DropCallArgument(Inputs[I])) {
4455 if (ArgChanged)
4456 *ArgChanged = true;
4457
4458 break;
4459 }
4460
4461 if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(Inputs[I])) {
4462 Expr *Pattern = Expansion->getPattern();
4463
4464 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
4465 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
4466 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
4467
4468 // Determine whether the set of unexpanded parameter packs can and should
4469 // be expanded.
4470 bool Expand = true;
4471 bool RetainExpansion = false;
4472 UnsignedOrNone OrigNumExpansions = Expansion->getNumExpansions();
4473 UnsignedOrNone NumExpansions = OrigNumExpansions;
4474 if (getDerived().TryExpandParameterPacks(Expansion->getEllipsisLoc(),
4475 Pattern->getSourceRange(),
4476 Unexpanded,
4477 Expand, RetainExpansion,
4478 NumExpansions))
4479 return true;
4480
4481 if (!Expand) {
4482 // The transform has determined that we should perform a simple
4483 // transformation on the pack expansion, producing another pack
4484 // expansion.
4485 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
4486 ExprResult OutPattern = getDerived().TransformExpr(Pattern);
4487 if (OutPattern.isInvalid())
4488 return true;
4489
4490 ExprResult Out = getDerived().RebuildPackExpansion(OutPattern.get(),
4491 Expansion->getEllipsisLoc(),
4492 NumExpansions);
4493 if (Out.isInvalid())
4494 return true;
4495
4496 if (ArgChanged)
4497 *ArgChanged = true;
4498 Outputs.push_back(Elt: Out.get());
4499 continue;
4500 }
4501
4502 // Record right away that the argument was changed. This needs
4503 // to happen even if the array expands to nothing.
4504 if (ArgChanged) *ArgChanged = true;
4505
4506 // The transform has determined that we should perform an elementwise
4507 // expansion of the pattern. Do so.
4508 for (unsigned I = 0; I != *NumExpansions; ++I) {
4509 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
4510 ExprResult Out = getDerived().TransformExpr(Pattern);
4511 if (Out.isInvalid())
4512 return true;
4513
4514 if (Out.get()->containsUnexpandedParameterPack()) {
4515 Out = getDerived().RebuildPackExpansion(
4516 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4517 if (Out.isInvalid())
4518 return true;
4519 }
4520
4521 Outputs.push_back(Elt: Out.get());
4522 }
4523
4524 // If we're supposed to retain a pack expansion, do so by temporarily
4525 // forgetting the partially-substituted parameter pack.
4526 if (RetainExpansion) {
4527 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
4528
4529 ExprResult Out = getDerived().TransformExpr(Pattern);
4530 if (Out.isInvalid())
4531 return true;
4532
4533 Out = getDerived().RebuildPackExpansion(
4534 Out.get(), Expansion->getEllipsisLoc(), OrigNumExpansions);
4535 if (Out.isInvalid())
4536 return true;
4537
4538 Outputs.push_back(Elt: Out.get());
4539 }
4540
4541 continue;
4542 }
4543
4544 ExprResult Result =
4545 IsCall ? getDerived().TransformInitializer(Inputs[I], /*DirectInit*/false)
4546 : getDerived().TransformExpr(Inputs[I]);
4547 if (Result.isInvalid())
4548 return true;
4549
4550 if (Result.get() != Inputs[I] && ArgChanged)
4551 *ArgChanged = true;
4552
4553 Outputs.push_back(Elt: Result.get());
4554 }
4555
4556 return false;
4557}
4558
4559template <typename Derived>
4560Sema::ConditionResult TreeTransform<Derived>::TransformCondition(
4561 SourceLocation Loc, VarDecl *Var, Expr *Expr, Sema::ConditionKind Kind) {
4562 if (Var) {
4563 VarDecl *ConditionVar = cast_or_null<VarDecl>(
4564 getDerived().TransformDefinition(Var->getLocation(), Var));
4565
4566 if (!ConditionVar)
4567 return Sema::ConditionError();
4568
4569 return getSema().ActOnConditionVariable(ConditionVar, Loc, Kind);
4570 }
4571
4572 if (Expr) {
4573 ExprResult CondExpr = getDerived().TransformExpr(Expr);
4574
4575 if (CondExpr.isInvalid())
4576 return Sema::ConditionError();
4577
4578 return getSema().ActOnCondition(nullptr, Loc, CondExpr.get(), Kind,
4579 /*MissingOK=*/true);
4580 }
4581
4582 return Sema::ConditionResult();
4583}
4584
4585template <typename Derived>
4586NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
4587 NestedNameSpecifierLoc NNS, QualType ObjectType,
4588 NamedDecl *FirstQualifierInScope) {
4589 SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
4590
4591 auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
4592 for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
4593 Qualifier = Qualifier.getPrefix())
4594 Qualifiers.push_back(Qualifier);
4595 };
4596 insertNNS(NNS);
4597
4598 CXXScopeSpec SS;
4599 while (!Qualifiers.empty()) {
4600 NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
4601 NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
4602
4603 switch (QNNS->getKind()) {
4604 case NestedNameSpecifier::Identifier: {
4605 Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
4606 Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
4607 ObjectType);
4608 if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/S: nullptr, IdInfo, EnteringContext: false,
4609 SS, ScopeLookupResult: FirstQualifierInScope, ErrorRecoveryLookup: false))
4610 return NestedNameSpecifierLoc();
4611 break;
4612 }
4613
4614 case NestedNameSpecifier::Namespace: {
4615 NamespaceDecl *NS =
4616 cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
4617 Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
4618 SS.Extend(Context&: SemaRef.Context, Namespace: NS, NamespaceLoc: Q.getLocalBeginLoc(), ColonColonLoc: Q.getLocalEndLoc());
4619 break;
4620 }
4621
4622 case NestedNameSpecifier::NamespaceAlias: {
4623 NamespaceAliasDecl *Alias =
4624 cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
4625 Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
4626 SS.Extend(Context&: SemaRef.Context, Alias, AliasLoc: Q.getLocalBeginLoc(),
4627 ColonColonLoc: Q.getLocalEndLoc());
4628 break;
4629 }
4630
4631 case NestedNameSpecifier::Global:
4632 // There is no meaningful transformation that one could perform on the
4633 // global scope.
4634 SS.MakeGlobal(Context&: SemaRef.Context, ColonColonLoc: Q.getBeginLoc());
4635 break;
4636
4637 case NestedNameSpecifier::Super: {
4638 CXXRecordDecl *RD =
4639 cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
4640 SourceLocation(), QNNS->getAsRecordDecl()));
4641 SS.MakeSuper(Context&: SemaRef.Context, RD, SuperLoc: Q.getBeginLoc(), ColonColonLoc: Q.getEndLoc());
4642 break;
4643 }
4644
4645 case NestedNameSpecifier::TypeSpec: {
4646 TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
4647 FirstQualifierInScope, SS);
4648
4649 if (!TL)
4650 return NestedNameSpecifierLoc();
4651
4652 QualType T = TL.getType();
4653 if (T->isDependentType() || T->isRecordType() ||
4654 (SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
4655 if (T->isEnumeralType())
4656 SemaRef.Diag(TL.getBeginLoc(),
4657 diag::warn_cxx98_compat_enum_nested_name_spec);
4658
4659 if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
4660 SS.Adopt(Other: ETL.getQualifierLoc());
4661 TL = ETL.getNamedTypeLoc();
4662 }
4663
4664 SS.Extend(Context&: SemaRef.Context, TL, ColonColonLoc: Q.getLocalEndLoc());
4665 break;
4666 }
4667 // If the nested-name-specifier is an invalid type def, don't emit an
4668 // error because a previous error should have already been emitted.
4669 TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
4670 if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
4671 SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
4672 << T << SS.getRange();
4673 }
4674 return NestedNameSpecifierLoc();
4675 }
4676 }
4677
4678 // The qualifier-in-scope and object type only apply to the leftmost entity.
4679 FirstQualifierInScope = nullptr;
4680 ObjectType = QualType();
4681 }
4682
4683 // Don't rebuild the nested-name-specifier if we don't have to.
4684 if (SS.getScopeRep() == NNS.getNestedNameSpecifier() &&
4685 !getDerived().AlwaysRebuild())
4686 return NNS;
4687
4688 // If we can re-use the source-location data from the original
4689 // nested-name-specifier, do so.
4690 if (SS.location_size() == NNS.getDataLength() &&
4691 memcmp(s1: SS.location_data(), s2: NNS.getOpaqueData(), n: SS.location_size()) == 0)
4692 return NestedNameSpecifierLoc(SS.getScopeRep(), NNS.getOpaqueData());
4693
4694 // Allocate new nested-name-specifier location information.
4695 return SS.getWithLocInContext(Context&: SemaRef.Context);
4696}
4697
4698template<typename Derived>
4699DeclarationNameInfo
4700TreeTransform<Derived>
4701::TransformDeclarationNameInfo(const DeclarationNameInfo &NameInfo) {
4702 DeclarationName Name = NameInfo.getName();
4703 if (!Name)
4704 return DeclarationNameInfo();
4705
4706 switch (Name.getNameKind()) {
4707 case DeclarationName::Identifier:
4708 case DeclarationName::ObjCZeroArgSelector:
4709 case DeclarationName::ObjCOneArgSelector:
4710 case DeclarationName::ObjCMultiArgSelector:
4711 case DeclarationName::CXXOperatorName:
4712 case DeclarationName::CXXLiteralOperatorName:
4713 case DeclarationName::CXXUsingDirective:
4714 return NameInfo;
4715
4716 case DeclarationName::CXXDeductionGuideName: {
4717 TemplateDecl *OldTemplate = Name.getCXXDeductionGuideTemplate();
4718 TemplateDecl *NewTemplate = cast_or_null<TemplateDecl>(
4719 getDerived().TransformDecl(NameInfo.getLoc(), OldTemplate));
4720 if (!NewTemplate)
4721 return DeclarationNameInfo();
4722
4723 DeclarationNameInfo NewNameInfo(NameInfo);
4724 NewNameInfo.setName(
4725 SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(TD: NewTemplate));
4726 return NewNameInfo;
4727 }
4728
4729 case DeclarationName::CXXConstructorName:
4730 case DeclarationName::CXXDestructorName:
4731 case DeclarationName::CXXConversionFunctionName: {
4732 TypeSourceInfo *NewTInfo;
4733 CanQualType NewCanTy;
4734 if (TypeSourceInfo *OldTInfo = NameInfo.getNamedTypeInfo()) {
4735 NewTInfo = getDerived().TransformType(OldTInfo);
4736 if (!NewTInfo)
4737 return DeclarationNameInfo();
4738 NewCanTy = SemaRef.Context.getCanonicalType(T: NewTInfo->getType());
4739 }
4740 else {
4741 NewTInfo = nullptr;
4742 TemporaryBase Rebase(*this, NameInfo.getLoc(), Name);
4743 QualType NewT = getDerived().TransformType(Name.getCXXNameType());
4744 if (NewT.isNull())
4745 return DeclarationNameInfo();
4746 NewCanTy = SemaRef.Context.getCanonicalType(T: NewT);
4747 }
4748
4749 DeclarationName NewName
4750 = SemaRef.Context.DeclarationNames.getCXXSpecialName(Kind: Name.getNameKind(),
4751 Ty: NewCanTy);
4752 DeclarationNameInfo NewNameInfo(NameInfo);
4753 NewNameInfo.setName(NewName);
4754 NewNameInfo.setNamedTypeInfo(NewTInfo);
4755 return NewNameInfo;
4756 }
4757 }
4758
4759 llvm_unreachable("Unknown name kind.");
4760}
4761
4762template <typename Derived>
4763TemplateName TreeTransform<Derived>::RebuildTemplateName(
4764 CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
4765 IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
4766 QualType ObjectType, NamedDecl *FirstQualifierInScope,
4767 bool AllowInjectedClassName) {
4768 if (const IdentifierInfo *II = IO.getIdentifier()) {
4769 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
4770 ObjectType, FirstQualifierInScope,
4771 AllowInjectedClassName);
4772 }
4773 return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
4774 NameLoc, ObjectType,
4775 AllowInjectedClassName);
4776}
4777
4778template<typename Derived>
4779TemplateName
4780TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
4781 TemplateName Name,
4782 SourceLocation NameLoc,
4783 QualType ObjectType,
4784 NamedDecl *FirstQualifierInScope,
4785 bool AllowInjectedClassName) {
4786 if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
4787 TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
4788 assert(Template && "qualified template name must refer to a template");
4789
4790 TemplateDecl *TransTemplate
4791 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4792 Template));
4793 if (!TransTemplate)
4794 return TemplateName();
4795
4796 if (!getDerived().AlwaysRebuild() &&
4797 SS.getScopeRep() == QTN->getQualifier() &&
4798 TransTemplate == Template)
4799 return Name;
4800
4801 return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
4802 TransTemplate);
4803 }
4804
4805 if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
4806 if (SS.getScopeRep()) {
4807 // These apply to the scope specifier, not the template.
4808 ObjectType = QualType();
4809 FirstQualifierInScope = nullptr;
4810 }
4811
4812 if (!getDerived().AlwaysRebuild() &&
4813 SS.getScopeRep() == DTN->getQualifier() &&
4814 ObjectType.isNull())
4815 return Name;
4816
4817 // FIXME: Preserve the location of the "template" keyword.
4818 SourceLocation TemplateKWLoc = NameLoc;
4819 return getDerived().RebuildTemplateName(
4820 SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType,
4821 FirstQualifierInScope, AllowInjectedClassName);
4822 }
4823
4824 // FIXME: Try to preserve more of the TemplateName.
4825 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
4826 TemplateDecl *TransTemplate
4827 = cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
4828 Template));
4829 if (!TransTemplate)
4830 return TemplateName();
4831
4832 return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
4833 TransTemplate);
4834 }
4835
4836 if (SubstTemplateTemplateParmPackStorage *SubstPack
4837 = Name.getAsSubstTemplateTemplateParmPack()) {
4838 return getDerived().RebuildTemplateName(
4839 SubstPack->getArgumentPack(), SubstPack->getAssociatedDecl(),
4840 SubstPack->getIndex(), SubstPack->getFinal());
4841 }
4842
4843 // These should be getting filtered out before they reach the AST.
4844 llvm_unreachable("overloaded function decl survived to here");
4845}
4846
4847template<typename Derived>
4848void TreeTransform<Derived>::InventTemplateArgumentLoc(
4849 const TemplateArgument &Arg,
4850 TemplateArgumentLoc &Output) {
4851 Output = getSema().getTrivialTemplateArgumentLoc(
4852 Arg, QualType(), getDerived().getBaseLocation());
4853}
4854
4855template <typename Derived>
4856bool TreeTransform<Derived>::TransformTemplateArgument(
4857 const TemplateArgumentLoc &Input, TemplateArgumentLoc &Output,
4858 bool Uneval) {
4859 const TemplateArgument &Arg = Input.getArgument();
4860 switch (Arg.getKind()) {
4861 case TemplateArgument::Null:
4862 case TemplateArgument::Pack:
4863 llvm_unreachable("Unexpected TemplateArgument");
4864
4865 case TemplateArgument::Integral:
4866 case TemplateArgument::NullPtr:
4867 case TemplateArgument::Declaration:
4868 case TemplateArgument::StructuralValue: {
4869 // Transform a resolved template argument straight to a resolved template
4870 // argument. We get here when substituting into an already-substituted
4871 // template type argument during concept satisfaction checking.
4872 QualType T = Arg.getNonTypeTemplateArgumentType();
4873 QualType NewT = getDerived().TransformType(T);
4874 if (NewT.isNull())
4875 return true;
4876
4877 ValueDecl *D = Arg.getKind() == TemplateArgument::Declaration
4878 ? Arg.getAsDecl()
4879 : nullptr;
4880 ValueDecl *NewD = D ? cast_or_null<ValueDecl>(getDerived().TransformDecl(
4881 getDerived().getBaseLocation(), D))
4882 : nullptr;
4883 if (D && !NewD)
4884 return true;
4885
4886 if (NewT == T && D == NewD)
4887 Output = Input;
4888 else if (Arg.getKind() == TemplateArgument::Integral)
4889 Output = TemplateArgumentLoc(
4890 TemplateArgument(getSema().Context, Arg.getAsIntegral(), NewT),
4891 TemplateArgumentLocInfo());
4892 else if (Arg.getKind() == TemplateArgument::NullPtr)
4893 Output = TemplateArgumentLoc(TemplateArgument(NewT, /*IsNullPtr=*/true),
4894 TemplateArgumentLocInfo());
4895 else if (Arg.getKind() == TemplateArgument::Declaration)
4896 Output = TemplateArgumentLoc(TemplateArgument(NewD, NewT),
4897 TemplateArgumentLocInfo());
4898 else if (Arg.getKind() == TemplateArgument::StructuralValue)
4899 Output = TemplateArgumentLoc(
4900 TemplateArgument(getSema().Context, NewT, Arg.getAsStructuralValue()),
4901 TemplateArgumentLocInfo());
4902 else
4903 llvm_unreachable("unexpected template argument kind");
4904
4905 return false;
4906 }
4907
4908 case TemplateArgument::Type: {
4909 TypeSourceInfo *DI = Input.getTypeSourceInfo();
4910 if (!DI)
4911 DI = InventTypeSourceInfo(T: Input.getArgument().getAsType());
4912
4913 DI = getDerived().TransformType(DI);
4914 if (!DI)
4915 return true;
4916
4917 Output = TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
4918 return false;
4919 }
4920
4921 case TemplateArgument::Template: {
4922 NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
4923 if (QualifierLoc) {
4924 QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
4925 if (!QualifierLoc)
4926 return true;
4927 }
4928
4929 CXXScopeSpec SS;
4930 SS.Adopt(Other: QualifierLoc);
4931 TemplateName Template = getDerived().TransformTemplateName(
4932 SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
4933 if (Template.isNull())
4934 return true;
4935
4936 Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
4937 QualifierLoc, Input.getTemplateNameLoc());
4938 return false;
4939 }
4940
4941 case TemplateArgument::TemplateExpansion:
4942 llvm_unreachable("Caller should expand pack expansions");
4943
4944 case TemplateArgument::Expression: {
4945 // Template argument expressions are constant expressions.
4946 EnterExpressionEvaluationContext Unevaluated(
4947 getSema(),
4948 Uneval ? Sema::ExpressionEvaluationContext::Unevaluated
4949 : Sema::ExpressionEvaluationContext::ConstantEvaluated,
4950 Sema::ReuseLambdaContextDecl, /*ExprContext=*/
4951 Sema::ExpressionEvaluationContextRecord::EK_TemplateArgument);
4952
4953 Expr *InputExpr = Input.getSourceExpression();
4954 if (!InputExpr)
4955 InputExpr = Input.getArgument().getAsExpr();
4956
4957 ExprResult E = getDerived().TransformExpr(InputExpr);
4958 E = SemaRef.ActOnConstantExpression(Res: E);
4959 if (E.isInvalid())
4960 return true;
4961 Output = TemplateArgumentLoc(
4962 TemplateArgument(E.get(), /*IsCanonical=*/false), E.get());
4963 return false;
4964 }
4965 }
4966
4967 // Work around bogus GCC warning
4968 return true;
4969}
4970
4971/// Iterator adaptor that invents template argument location information
4972/// for each of the template arguments in its underlying iterator.
4973template<typename Derived, typename InputIterator>
4974class TemplateArgumentLocInventIterator {
4975 TreeTransform<Derived> &Self;
4976 InputIterator Iter;
4977
4978public:
4979 typedef TemplateArgumentLoc value_type;
4980 typedef TemplateArgumentLoc reference;
4981 typedef typename std::iterator_traits<InputIterator>::difference_type
4982 difference_type;
4983 typedef std::input_iterator_tag iterator_category;
4984
4985 class pointer {
4986 TemplateArgumentLoc Arg;
4987
4988 public:
4989 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
4990
4991 const TemplateArgumentLoc *operator->() const { return &Arg; }
4992 };
4993
4994 explicit TemplateArgumentLocInventIterator(TreeTransform<Derived> &Self,
4995 InputIterator Iter)
4996 : Self(Self), Iter(Iter) { }
4997
4998 TemplateArgumentLocInventIterator &operator++() {
4999 ++Iter;
5000 return *this;
5001 }
5002
5003 TemplateArgumentLocInventIterator operator++(int) {
5004 TemplateArgumentLocInventIterator Old(*this);
5005 ++(*this);
5006 return Old;
5007 }
5008
5009 reference operator*() const {
5010 TemplateArgumentLoc Result;
5011 Self.InventTemplateArgumentLoc(*Iter, Result);
5012 return Result;
5013 }
5014
5015 pointer operator->() const { return pointer(**this); }
5016
5017 friend bool operator==(const TemplateArgumentLocInventIterator &X,
5018 const TemplateArgumentLocInventIterator &Y) {
5019 return X.Iter == Y.Iter;
5020 }
5021
5022 friend bool operator!=(const TemplateArgumentLocInventIterator &X,
5023 const TemplateArgumentLocInventIterator &Y) {
5024 return X.Iter != Y.Iter;
5025 }
5026};
5027
5028template<typename Derived>
5029template<typename InputIterator>
5030bool TreeTransform<Derived>::TransformTemplateArguments(
5031 InputIterator First, InputIterator Last, TemplateArgumentListInfo &Outputs,
5032 bool Uneval) {
5033 for (; First != Last; ++First) {
5034 TemplateArgumentLoc Out;
5035 TemplateArgumentLoc In = *First;
5036
5037 if (In.getArgument().getKind() == TemplateArgument::Pack) {
5038 // Unpack argument packs, which we translate them into separate
5039 // arguments.
5040 // FIXME: We could do much better if we could guarantee that the
5041 // TemplateArgumentLocInfo for the pack expansion would be usable for
5042 // all of the template arguments in the argument pack.
5043 typedef TemplateArgumentLocInventIterator<Derived,
5044 TemplateArgument::pack_iterator>
5045 PackLocIterator;
5046 if (TransformTemplateArguments(PackLocIterator(*this,
5047 In.getArgument().pack_begin()),
5048 PackLocIterator(*this,
5049 In.getArgument().pack_end()),
5050 Outputs, Uneval))
5051 return true;
5052
5053 continue;
5054 }
5055
5056 if (In.getArgument().isPackExpansion()) {
5057 // We have a pack expansion, for which we will be substituting into
5058 // the pattern.
5059 SourceLocation Ellipsis;
5060 UnsignedOrNone OrigNumExpansions = std::nullopt;
5061 TemplateArgumentLoc Pattern
5062 = getSema().getTemplateArgumentPackExpansionPattern(
5063 In, Ellipsis, OrigNumExpansions);
5064
5065 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
5066 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
5067 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
5068
5069 // Determine whether the set of unexpanded parameter packs can and should
5070 // be expanded.
5071 bool Expand = true;
5072 bool RetainExpansion = false;
5073 UnsignedOrNone NumExpansions = OrigNumExpansions;
5074 if (getDerived().TryExpandParameterPacks(Ellipsis,
5075 Pattern.getSourceRange(),
5076 Unexpanded,
5077 Expand,
5078 RetainExpansion,
5079 NumExpansions))
5080 return true;
5081
5082 if (!Expand) {
5083 // The transform has determined that we should perform a simple
5084 // transformation on the pack expansion, producing another pack
5085 // expansion.
5086 TemplateArgumentLoc OutPattern;
5087 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
5088 if (getDerived().TransformTemplateArgument(Pattern, OutPattern, Uneval))
5089 return true;
5090
5091 Out = getDerived().RebuildPackExpansion(OutPattern, Ellipsis,
5092 NumExpansions);
5093 if (Out.getArgument().isNull())
5094 return true;
5095
5096 Outputs.addArgument(Loc: Out);
5097 continue;
5098 }
5099
5100 // The transform has determined that we should perform an elementwise
5101 // expansion of the pattern. Do so.
5102 for (unsigned I = 0; I != *NumExpansions; ++I) {
5103 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
5104
5105 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5106 return true;
5107
5108 if (Out.getArgument().containsUnexpandedParameterPack()) {
5109 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5110 OrigNumExpansions);
5111 if (Out.getArgument().isNull())
5112 return true;
5113 }
5114
5115 Outputs.addArgument(Loc: Out);
5116 }
5117
5118 // If we're supposed to retain a pack expansion, do so by temporarily
5119 // forgetting the partially-substituted parameter pack.
5120 if (RetainExpansion) {
5121 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
5122
5123 if (getDerived().TransformTemplateArgument(Pattern, Out, Uneval))
5124 return true;
5125
5126 Out = getDerived().RebuildPackExpansion(Out, Ellipsis,
5127 OrigNumExpansions);
5128 if (Out.getArgument().isNull())
5129 return true;
5130
5131 Outputs.addArgument(Loc: Out);
5132 }
5133
5134 continue;
5135 }
5136
5137 // The simple case:
5138 if (getDerived().TransformTemplateArgument(In, Out, Uneval))
5139 return true;
5140
5141 Outputs.addArgument(Loc: Out);
5142 }
5143
5144 return false;
5145
5146}
5147
5148//===----------------------------------------------------------------------===//
5149// Type transformation
5150//===----------------------------------------------------------------------===//
5151
5152template<typename Derived>
5153QualType TreeTransform<Derived>::TransformType(QualType T) {
5154 if (getDerived().AlreadyTransformed(T))
5155 return T;
5156
5157 // Temporary workaround. All of these transformations should
5158 // eventually turn into transformations on TypeLocs.
5159 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5160 getDerived().getBaseLocation());
5161
5162 TypeSourceInfo *NewDI = getDerived().TransformType(DI);
5163
5164 if (!NewDI)
5165 return QualType();
5166
5167 return NewDI->getType();
5168}
5169
5170template<typename Derived>
5171TypeSourceInfo *TreeTransform<Derived>::TransformType(TypeSourceInfo *DI) {
5172 // Refine the base location to the type's location.
5173 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5174 getDerived().getBaseEntity());
5175 if (getDerived().AlreadyTransformed(DI->getType()))
5176 return DI;
5177
5178 TypeLocBuilder TLB;
5179
5180 TypeLoc TL = DI->getTypeLoc();
5181 TLB.reserve(Requested: TL.getFullDataSize());
5182
5183 QualType Result = getDerived().TransformType(TLB, TL);
5184 if (Result.isNull())
5185 return nullptr;
5186
5187 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5188}
5189
5190template<typename Derived>
5191QualType
5192TreeTransform<Derived>::TransformType(TypeLocBuilder &TLB, TypeLoc T) {
5193 switch (T.getTypeLocClass()) {
5194#define ABSTRACT_TYPELOC(CLASS, PARENT)
5195#define TYPELOC(CLASS, PARENT) \
5196 case TypeLoc::CLASS: \
5197 return getDerived().Transform##CLASS##Type(TLB, \
5198 T.castAs<CLASS##TypeLoc>());
5199#include "clang/AST/TypeLocNodes.def"
5200 }
5201
5202 llvm_unreachable("unhandled type loc!");
5203}
5204
5205template<typename Derived>
5206QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
5207 if (!isa<DependentNameType>(T))
5208 return TransformType(T);
5209
5210 if (getDerived().AlreadyTransformed(T))
5211 return T;
5212 TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
5213 getDerived().getBaseLocation());
5214 TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
5215 return NewDI ? NewDI->getType() : QualType();
5216}
5217
5218template<typename Derived>
5219TypeSourceInfo *
5220TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
5221 if (!isa<DependentNameType>(DI->getType()))
5222 return TransformType(DI);
5223
5224 // Refine the base location to the type's location.
5225 TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
5226 getDerived().getBaseEntity());
5227 if (getDerived().AlreadyTransformed(DI->getType()))
5228 return DI;
5229
5230 TypeLocBuilder TLB;
5231
5232 TypeLoc TL = DI->getTypeLoc();
5233 TLB.reserve(Requested: TL.getFullDataSize());
5234
5235 auto QTL = TL.getAs<QualifiedTypeLoc>();
5236 if (QTL)
5237 TL = QTL.getUnqualifiedLoc();
5238
5239 auto DNTL = TL.castAs<DependentNameTypeLoc>();
5240
5241 QualType Result = getDerived().TransformDependentNameType(
5242 TLB, DNTL, /*DeducedTSTContext*/true);
5243 if (Result.isNull())
5244 return nullptr;
5245
5246 if (QTL) {
5247 Result = getDerived().RebuildQualifiedType(Result, QTL);
5248 if (Result.isNull())
5249 return nullptr;
5250 TLB.TypeWasModifiedSafely(T: Result);
5251 }
5252
5253 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5254}
5255
5256template<typename Derived>
5257QualType
5258TreeTransform<Derived>::TransformQualifiedType(TypeLocBuilder &TLB,
5259 QualifiedTypeLoc T) {
5260 QualType Result;
5261 TypeLoc UnqualTL = T.getUnqualifiedLoc();
5262 auto SuppressObjCLifetime =
5263 T.getType().getLocalQualifiers().hasObjCLifetime();
5264 if (auto TTP = UnqualTL.getAs<TemplateTypeParmTypeLoc>()) {
5265 Result = getDerived().TransformTemplateTypeParmType(TLB, TTP,
5266 SuppressObjCLifetime);
5267 } else if (auto STTP = UnqualTL.getAs<SubstTemplateTypeParmPackTypeLoc>()) {
5268 Result = getDerived().TransformSubstTemplateTypeParmPackType(
5269 TLB, STTP, SuppressObjCLifetime);
5270 } else {
5271 Result = getDerived().TransformType(TLB, UnqualTL);
5272 }
5273
5274 if (Result.isNull())
5275 return QualType();
5276
5277 Result = getDerived().RebuildQualifiedType(Result, T);
5278
5279 if (Result.isNull())
5280 return QualType();
5281
5282 // RebuildQualifiedType might have updated the type, but not in a way
5283 // that invalidates the TypeLoc. (There's no location information for
5284 // qualifiers.)
5285 TLB.TypeWasModifiedSafely(T: Result);
5286
5287 return Result;
5288}
5289
5290template <typename Derived>
5291QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
5292 QualifiedTypeLoc TL) {
5293
5294 SourceLocation Loc = TL.getBeginLoc();
5295 Qualifiers Quals = TL.getType().getLocalQualifiers();
5296
5297 if ((T.getAddressSpace() != LangAS::Default &&
5298 Quals.getAddressSpace() != LangAS::Default) &&
5299 T.getAddressSpace() != Quals.getAddressSpace()) {
5300 SemaRef.Diag(Loc, diag::err_address_space_mismatch_templ_inst)
5301 << TL.getType() << T;
5302 return QualType();
5303 }
5304
5305 PointerAuthQualifier LocalPointerAuth = Quals.getPointerAuth();
5306 if (LocalPointerAuth.isPresent()) {
5307 if (T.getPointerAuth().isPresent()) {
5308 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_redundant) << TL.getType();
5309 return QualType();
5310 }
5311 if (!T->isDependentType()) {
5312 if (!T->isSignableType(Ctx: SemaRef.getASTContext())) {
5313 SemaRef.Diag(Loc, diag::err_ptrauth_qualifier_invalid_target) << T;
5314 return QualType();
5315 }
5316 }
5317 }
5318 // C++ [dcl.fct]p7:
5319 // [When] adding cv-qualifications on top of the function type [...] the
5320 // cv-qualifiers are ignored.
5321 if (T->isFunctionType()) {
5322 T = SemaRef.getASTContext().getAddrSpaceQualType(T,
5323 AddressSpace: Quals.getAddressSpace());
5324 return T;
5325 }
5326
5327 // C++ [dcl.ref]p1:
5328 // when the cv-qualifiers are introduced through the use of a typedef-name
5329 // or decltype-specifier [...] the cv-qualifiers are ignored.
5330 // Note that [dcl.ref]p1 lists all cases in which cv-qualifiers can be
5331 // applied to a reference type.
5332 if (T->isReferenceType()) {
5333 // The only qualifier that applies to a reference type is restrict.
5334 if (!Quals.hasRestrict())
5335 return T;
5336 Quals = Qualifiers::fromCVRMask(CVR: Qualifiers::Restrict);
5337 }
5338
5339 // Suppress Objective-C lifetime qualifiers if they don't make sense for the
5340 // resulting type.
5341 if (Quals.hasObjCLifetime()) {
5342 if (!T->isObjCLifetimeType() && !T->isDependentType())
5343 Quals.removeObjCLifetime();
5344 else if (T.getObjCLifetime()) {
5345 // Objective-C ARC:
5346 // A lifetime qualifier applied to a substituted template parameter
5347 // overrides the lifetime qualifier from the template argument.
5348 const AutoType *AutoTy;
5349 if ((AutoTy = dyn_cast<AutoType>(T)) && AutoTy->isDeduced()) {
5350 // 'auto' types behave the same way as template parameters.
5351 QualType Deduced = AutoTy->getDeducedType();
5352 Qualifiers Qs = Deduced.getQualifiers();
5353 Qs.removeObjCLifetime();
5354 Deduced =
5355 SemaRef.Context.getQualifiedType(T: Deduced.getUnqualifiedType(), Qs);
5356 T = SemaRef.Context.getAutoType(DeducedType: Deduced, Keyword: AutoTy->getKeyword(),
5357 IsDependent: AutoTy->isDependentType(),
5358 /*isPack=*/IsPack: false,
5359 TypeConstraintConcept: AutoTy->getTypeConstraintConcept(),
5360 TypeConstraintArgs: AutoTy->getTypeConstraintArguments());
5361 } else {
5362 // Otherwise, complain about the addition of a qualifier to an
5363 // already-qualified type.
5364 // FIXME: Why is this check not in Sema::BuildQualifiedType?
5365 SemaRef.Diag(Loc, diag::err_attr_objc_ownership_redundant) << T;
5366 Quals.removeObjCLifetime();
5367 }
5368 }
5369 }
5370
5371 return SemaRef.BuildQualifiedType(T, Loc, Qs: Quals);
5372}
5373
5374template<typename Derived>
5375TypeLoc
5376TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
5377 QualType ObjectType,
5378 NamedDecl *UnqualLookup,
5379 CXXScopeSpec &SS) {
5380 if (getDerived().AlreadyTransformed(TL.getType()))
5381 return TL;
5382
5383 TypeSourceInfo *TSI =
5384 TransformTSIInObjectScope(TL, ObjectType, FirstQualifierInScope: UnqualLookup, SS);
5385 if (TSI)
5386 return TSI->getTypeLoc();
5387 return TypeLoc();
5388}
5389
5390template<typename Derived>
5391TypeSourceInfo *
5392TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
5393 QualType ObjectType,
5394 NamedDecl *UnqualLookup,
5395 CXXScopeSpec &SS) {
5396 if (getDerived().AlreadyTransformed(TSInfo->getType()))
5397 return TSInfo;
5398
5399 return TransformTSIInObjectScope(TL: TSInfo->getTypeLoc(), ObjectType,
5400 FirstQualifierInScope: UnqualLookup, SS);
5401}
5402
5403template <typename Derived>
5404TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
5405 TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
5406 CXXScopeSpec &SS) {
5407 QualType T = TL.getType();
5408 assert(!getDerived().AlreadyTransformed(T));
5409
5410 TypeLocBuilder TLB;
5411 QualType Result;
5412
5413 if (isa<TemplateSpecializationType>(T)) {
5414 TemplateSpecializationTypeLoc SpecTL =
5415 TL.castAs<TemplateSpecializationTypeLoc>();
5416
5417 TemplateName Template = getDerived().TransformTemplateName(
5418 SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
5419 ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
5420 if (Template.isNull())
5421 return nullptr;
5422
5423 Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
5424 Template);
5425 } else if (isa<DependentTemplateSpecializationType>(T)) {
5426 DependentTemplateSpecializationTypeLoc SpecTL =
5427 TL.castAs<DependentTemplateSpecializationTypeLoc>();
5428
5429 const IdentifierInfo *II = SpecTL.getTypePtr()
5430 ->getDependentTemplateName()
5431 .getName()
5432 .getIdentifier();
5433 TemplateName Template = getDerived().RebuildTemplateName(
5434 SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(),
5435 ObjectType, UnqualLookup,
5436 /*AllowInjectedClassName*/ true);
5437 if (Template.isNull())
5438 return nullptr;
5439
5440 Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
5441 SpecTL,
5442 Template,
5443 SS);
5444 } else {
5445 // Nothing special needs to be done for these.
5446 Result = getDerived().TransformType(TLB, TL);
5447 }
5448
5449 if (Result.isNull())
5450 return nullptr;
5451
5452 return TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
5453}
5454
5455template <class TyLoc> static inline
5456QualType TransformTypeSpecType(TypeLocBuilder &TLB, TyLoc T) {
5457 TyLoc NewT = TLB.push<TyLoc>(T.getType());
5458 NewT.setNameLoc(T.getNameLoc());
5459 return T.getType();
5460}
5461
5462template<typename Derived>
5463QualType TreeTransform<Derived>::TransformBuiltinType(TypeLocBuilder &TLB,
5464 BuiltinTypeLoc T) {
5465 BuiltinTypeLoc NewT = TLB.push<BuiltinTypeLoc>(T.getType());
5466 NewT.setBuiltinLoc(T.getBuiltinLoc());
5467 if (T.needsExtraLocalData())
5468 NewT.getWrittenBuiltinSpecs() = T.getWrittenBuiltinSpecs();
5469 return T.getType();
5470}
5471
5472template<typename Derived>
5473QualType TreeTransform<Derived>::TransformComplexType(TypeLocBuilder &TLB,
5474 ComplexTypeLoc T) {
5475 // FIXME: recurse?
5476 return TransformTypeSpecType(TLB, T);
5477}
5478
5479template <typename Derived>
5480QualType TreeTransform<Derived>::TransformAdjustedType(TypeLocBuilder &TLB,
5481 AdjustedTypeLoc TL) {
5482 // Adjustments applied during transformation are handled elsewhere.
5483 return getDerived().TransformType(TLB, TL.getOriginalLoc());
5484}
5485
5486template<typename Derived>
5487QualType TreeTransform<Derived>::TransformDecayedType(TypeLocBuilder &TLB,
5488 DecayedTypeLoc TL) {
5489 QualType OriginalType = getDerived().TransformType(TLB, TL.getOriginalLoc());
5490 if (OriginalType.isNull())
5491 return QualType();
5492
5493 QualType Result = TL.getType();
5494 if (getDerived().AlwaysRebuild() ||
5495 OriginalType != TL.getOriginalLoc().getType())
5496 Result = SemaRef.Context.getDecayedType(T: OriginalType);
5497 TLB.push<DecayedTypeLoc>(Result);
5498 // Nothing to set for DecayedTypeLoc.
5499 return Result;
5500}
5501
5502template <typename Derived>
5503QualType
5504TreeTransform<Derived>::TransformArrayParameterType(TypeLocBuilder &TLB,
5505 ArrayParameterTypeLoc TL) {
5506 QualType OriginalType = getDerived().TransformType(TLB, TL.getElementLoc());
5507 if (OriginalType.isNull())
5508 return QualType();
5509
5510 QualType Result = TL.getType();
5511 if (getDerived().AlwaysRebuild() ||
5512 OriginalType != TL.getElementLoc().getType())
5513 Result = SemaRef.Context.getArrayParameterType(Ty: OriginalType);
5514 TLB.push<ArrayParameterTypeLoc>(Result);
5515 // Nothing to set for ArrayParameterTypeLoc.
5516 return Result;
5517}
5518
5519template<typename Derived>
5520QualType TreeTransform<Derived>::TransformPointerType(TypeLocBuilder &TLB,
5521 PointerTypeLoc TL) {
5522 QualType PointeeType
5523 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5524 if (PointeeType.isNull())
5525 return QualType();
5526
5527 QualType Result = TL.getType();
5528 if (PointeeType->getAs<ObjCObjectType>()) {
5529 // A dependent pointer type 'T *' has is being transformed such
5530 // that an Objective-C class type is being replaced for 'T'. The
5531 // resulting pointer type is an ObjCObjectPointerType, not a
5532 // PointerType.
5533 Result = SemaRef.Context.getObjCObjectPointerType(OIT: PointeeType);
5534
5535 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
5536 NewT.setStarLoc(TL.getStarLoc());
5537 return Result;
5538 }
5539
5540 if (getDerived().AlwaysRebuild() ||
5541 PointeeType != TL.getPointeeLoc().getType()) {
5542 Result = getDerived().RebuildPointerType(PointeeType, TL.getSigilLoc());
5543 if (Result.isNull())
5544 return QualType();
5545 }
5546
5547 // Objective-C ARC can add lifetime qualifiers to the type that we're
5548 // pointing to.
5549 TLB.TypeWasModifiedSafely(T: Result->getPointeeType());
5550
5551 PointerTypeLoc NewT = TLB.push<PointerTypeLoc>(Result);
5552 NewT.setSigilLoc(TL.getSigilLoc());
5553 return Result;
5554}
5555
5556template<typename Derived>
5557QualType
5558TreeTransform<Derived>::TransformBlockPointerType(TypeLocBuilder &TLB,
5559 BlockPointerTypeLoc TL) {
5560 QualType PointeeType
5561 = getDerived().TransformType(TLB, TL.getPointeeLoc());
5562 if (PointeeType.isNull())
5563 return QualType();
5564
5565 QualType Result = TL.getType();
5566 if (getDerived().AlwaysRebuild() ||
5567 PointeeType != TL.getPointeeLoc().getType()) {
5568 Result = getDerived().RebuildBlockPointerType(PointeeType,
5569 TL.getSigilLoc());
5570 if (Result.isNull())
5571 return QualType();
5572 }
5573
5574 BlockPointerTypeLoc NewT = TLB.push<BlockPointerTypeLoc>(Result);
5575 NewT.setSigilLoc(TL.getSigilLoc());
5576 return Result;
5577}
5578
5579/// Transforms a reference type. Note that somewhat paradoxically we
5580/// don't care whether the type itself is an l-value type or an r-value
5581/// type; we only care if the type was *written* as an l-value type
5582/// or an r-value type.
5583template<typename Derived>
5584QualType
5585TreeTransform<Derived>::TransformReferenceType(TypeLocBuilder &TLB,
5586 ReferenceTypeLoc TL) {
5587 const ReferenceType *T = TL.getTypePtr();
5588
5589 // Note that this works with the pointee-as-written.
5590 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5591 if (PointeeType.isNull())
5592 return QualType();
5593
5594 QualType Result = TL.getType();
5595 if (getDerived().AlwaysRebuild() ||
5596 PointeeType != T->getPointeeTypeAsWritten()) {
5597 Result = getDerived().RebuildReferenceType(PointeeType,
5598 T->isSpelledAsLValue(),
5599 TL.getSigilLoc());
5600 if (Result.isNull())
5601 return QualType();
5602 }
5603
5604 // Objective-C ARC can add lifetime qualifiers to the type that we're
5605 // referring to.
5606 TLB.TypeWasModifiedSafely(
5607 T: Result->castAs<ReferenceType>()->getPointeeTypeAsWritten());
5608
5609 // r-value references can be rebuilt as l-value references.
5610 ReferenceTypeLoc NewTL;
5611 if (isa<LValueReferenceType>(Result))
5612 NewTL = TLB.push<LValueReferenceTypeLoc>(Result);
5613 else
5614 NewTL = TLB.push<RValueReferenceTypeLoc>(Result);
5615 NewTL.setSigilLoc(TL.getSigilLoc());
5616
5617 return Result;
5618}
5619
5620template<typename Derived>
5621QualType
5622TreeTransform<Derived>::TransformLValueReferenceType(TypeLocBuilder &TLB,
5623 LValueReferenceTypeLoc TL) {
5624 return TransformReferenceType(TLB, TL);
5625}
5626
5627template<typename Derived>
5628QualType
5629TreeTransform<Derived>::TransformRValueReferenceType(TypeLocBuilder &TLB,
5630 RValueReferenceTypeLoc TL) {
5631 return TransformReferenceType(TLB, TL);
5632}
5633
5634template<typename Derived>
5635QualType
5636TreeTransform<Derived>::TransformMemberPointerType(TypeLocBuilder &TLB,
5637 MemberPointerTypeLoc TL) {
5638 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
5639 if (PointeeType.isNull())
5640 return QualType();
5641
5642 const MemberPointerType *T = TL.getTypePtr();
5643
5644 NestedNameSpecifierLoc OldQualifierLoc = TL.getQualifierLoc();
5645 NestedNameSpecifierLoc NewQualifierLoc =
5646 getDerived().TransformNestedNameSpecifierLoc(OldQualifierLoc);
5647 if (!NewQualifierLoc)
5648 return QualType();
5649
5650 CXXRecordDecl *OldCls = T->getMostRecentCXXRecordDecl(), *NewCls = nullptr;
5651 if (OldCls) {
5652 NewCls = cast_or_null<CXXRecordDecl>(
5653 getDerived().TransformDecl(TL.getStarLoc(), OldCls));
5654 if (!NewCls)
5655 return QualType();
5656 }
5657
5658 QualType Result = TL.getType();
5659 if (getDerived().AlwaysRebuild() || PointeeType != T->getPointeeType() ||
5660 NewQualifierLoc.getNestedNameSpecifier() !=
5661 OldQualifierLoc.getNestedNameSpecifier() ||
5662 NewCls != OldCls) {
5663 CXXScopeSpec SS;
5664 SS.Adopt(Other: NewQualifierLoc);
5665 Result = getDerived().RebuildMemberPointerType(PointeeType, SS, NewCls,
5666 TL.getStarLoc());
5667 if (Result.isNull())
5668 return QualType();
5669 }
5670
5671 // If we had to adjust the pointee type when building a member pointer, make
5672 // sure to push TypeLoc info for it.
5673 const MemberPointerType *MPT = Result->getAs<MemberPointerType>();
5674 if (MPT && PointeeType != MPT->getPointeeType()) {
5675 assert(isa<AdjustedType>(MPT->getPointeeType()));
5676 TLB.push<AdjustedTypeLoc>(MPT->getPointeeType());
5677 }
5678
5679 MemberPointerTypeLoc NewTL = TLB.push<MemberPointerTypeLoc>(Result);
5680 NewTL.setSigilLoc(TL.getSigilLoc());
5681 NewTL.setQualifierLoc(NewQualifierLoc);
5682
5683 return Result;
5684}
5685
5686template<typename Derived>
5687QualType
5688TreeTransform<Derived>::TransformConstantArrayType(TypeLocBuilder &TLB,
5689 ConstantArrayTypeLoc TL) {
5690 const ConstantArrayType *T = TL.getTypePtr();
5691 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5692 if (ElementType.isNull())
5693 return QualType();
5694
5695 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5696 Expr *OldSize = TL.getSizeExpr();
5697 if (!OldSize)
5698 OldSize = const_cast<Expr*>(T->getSizeExpr());
5699 Expr *NewSize = nullptr;
5700 if (OldSize) {
5701 EnterExpressionEvaluationContext Unevaluated(
5702 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5703 NewSize = getDerived().TransformExpr(OldSize).template getAs<Expr>();
5704 NewSize = SemaRef.ActOnConstantExpression(Res: NewSize).get();
5705 }
5706
5707 QualType Result = TL.getType();
5708 if (getDerived().AlwaysRebuild() ||
5709 ElementType != T->getElementType() ||
5710 (T->getSizeExpr() && NewSize != OldSize)) {
5711 Result = getDerived().RebuildConstantArrayType(ElementType,
5712 T->getSizeModifier(),
5713 T->getSize(), NewSize,
5714 T->getIndexTypeCVRQualifiers(),
5715 TL.getBracketsRange());
5716 if (Result.isNull())
5717 return QualType();
5718 }
5719
5720 // We might have either a ConstantArrayType or a VariableArrayType now:
5721 // a ConstantArrayType is allowed to have an element type which is a
5722 // VariableArrayType if the type is dependent. Fortunately, all array
5723 // types have the same location layout.
5724 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5725 NewTL.setLBracketLoc(TL.getLBracketLoc());
5726 NewTL.setRBracketLoc(TL.getRBracketLoc());
5727 NewTL.setSizeExpr(NewSize);
5728
5729 return Result;
5730}
5731
5732template<typename Derived>
5733QualType TreeTransform<Derived>::TransformIncompleteArrayType(
5734 TypeLocBuilder &TLB,
5735 IncompleteArrayTypeLoc TL) {
5736 const IncompleteArrayType *T = TL.getTypePtr();
5737 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5738 if (ElementType.isNull())
5739 return QualType();
5740
5741 QualType Result = TL.getType();
5742 if (getDerived().AlwaysRebuild() ||
5743 ElementType != T->getElementType()) {
5744 Result = getDerived().RebuildIncompleteArrayType(ElementType,
5745 T->getSizeModifier(),
5746 T->getIndexTypeCVRQualifiers(),
5747 TL.getBracketsRange());
5748 if (Result.isNull())
5749 return QualType();
5750 }
5751
5752 IncompleteArrayTypeLoc NewTL = TLB.push<IncompleteArrayTypeLoc>(Result);
5753 NewTL.setLBracketLoc(TL.getLBracketLoc());
5754 NewTL.setRBracketLoc(TL.getRBracketLoc());
5755 NewTL.setSizeExpr(nullptr);
5756
5757 return Result;
5758}
5759
5760template<typename Derived>
5761QualType
5762TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB,
5763 VariableArrayTypeLoc TL) {
5764 const VariableArrayType *T = TL.getTypePtr();
5765 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5766 if (ElementType.isNull())
5767 return QualType();
5768
5769 ExprResult SizeResult;
5770 {
5771 EnterExpressionEvaluationContext Context(
5772 SemaRef, Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
5773 SizeResult = getDerived().TransformExpr(T->getSizeExpr());
5774 }
5775 if (SizeResult.isInvalid())
5776 return QualType();
5777 SizeResult =
5778 SemaRef.ActOnFinishFullExpr(Expr: SizeResult.get(), /*DiscardedValue*/ DiscardedValue: false);
5779 if (SizeResult.isInvalid())
5780 return QualType();
5781
5782 Expr *Size = SizeResult.get();
5783
5784 QualType Result = TL.getType();
5785 if (getDerived().AlwaysRebuild() ||
5786 ElementType != T->getElementType() ||
5787 Size != T->getSizeExpr()) {
5788 Result = getDerived().RebuildVariableArrayType(ElementType,
5789 T->getSizeModifier(),
5790 Size,
5791 T->getIndexTypeCVRQualifiers(),
5792 TL.getBracketsRange());
5793 if (Result.isNull())
5794 return QualType();
5795 }
5796
5797 // We might have constant size array now, but fortunately it has the same
5798 // location layout.
5799 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5800 NewTL.setLBracketLoc(TL.getLBracketLoc());
5801 NewTL.setRBracketLoc(TL.getRBracketLoc());
5802 NewTL.setSizeExpr(Size);
5803
5804 return Result;
5805}
5806
5807template<typename Derived>
5808QualType
5809TreeTransform<Derived>::TransformDependentSizedArrayType(TypeLocBuilder &TLB,
5810 DependentSizedArrayTypeLoc TL) {
5811 const DependentSizedArrayType *T = TL.getTypePtr();
5812 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5813 if (ElementType.isNull())
5814 return QualType();
5815
5816 // Array bounds are constant expressions.
5817 EnterExpressionEvaluationContext Unevaluated(
5818 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5819
5820 // If we have a VLA then it won't be a constant.
5821 SemaRef.ExprEvalContexts.back().InConditionallyConstantEvaluateContext = true;
5822
5823 // Prefer the expression from the TypeLoc; the other may have been uniqued.
5824 Expr *origSize = TL.getSizeExpr();
5825 if (!origSize) origSize = T->getSizeExpr();
5826
5827 ExprResult sizeResult
5828 = getDerived().TransformExpr(origSize);
5829 sizeResult = SemaRef.ActOnConstantExpression(Res: sizeResult);
5830 if (sizeResult.isInvalid())
5831 return QualType();
5832
5833 Expr *size = sizeResult.get();
5834
5835 QualType Result = TL.getType();
5836 if (getDerived().AlwaysRebuild() ||
5837 ElementType != T->getElementType() ||
5838 size != origSize) {
5839 Result = getDerived().RebuildDependentSizedArrayType(ElementType,
5840 T->getSizeModifier(),
5841 size,
5842 T->getIndexTypeCVRQualifiers(),
5843 TL.getBracketsRange());
5844 if (Result.isNull())
5845 return QualType();
5846 }
5847
5848 // We might have any sort of array type now, but fortunately they
5849 // all have the same location layout.
5850 ArrayTypeLoc NewTL = TLB.push<ArrayTypeLoc>(Result);
5851 NewTL.setLBracketLoc(TL.getLBracketLoc());
5852 NewTL.setRBracketLoc(TL.getRBracketLoc());
5853 NewTL.setSizeExpr(size);
5854
5855 return Result;
5856}
5857
5858template <typename Derived>
5859QualType TreeTransform<Derived>::TransformDependentVectorType(
5860 TypeLocBuilder &TLB, DependentVectorTypeLoc TL) {
5861 const DependentVectorType *T = TL.getTypePtr();
5862 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5863 if (ElementType.isNull())
5864 return QualType();
5865
5866 EnterExpressionEvaluationContext Unevaluated(
5867 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5868
5869 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5870 Size = SemaRef.ActOnConstantExpression(Res: Size);
5871 if (Size.isInvalid())
5872 return QualType();
5873
5874 QualType Result = TL.getType();
5875 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
5876 Size.get() != T->getSizeExpr()) {
5877 Result = getDerived().RebuildDependentVectorType(
5878 ElementType, Size.get(), T->getAttributeLoc(), T->getVectorKind());
5879 if (Result.isNull())
5880 return QualType();
5881 }
5882
5883 // Result might be dependent or not.
5884 if (isa<DependentVectorType>(Result)) {
5885 DependentVectorTypeLoc NewTL =
5886 TLB.push<DependentVectorTypeLoc>(Result);
5887 NewTL.setNameLoc(TL.getNameLoc());
5888 } else {
5889 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
5890 NewTL.setNameLoc(TL.getNameLoc());
5891 }
5892
5893 return Result;
5894}
5895
5896template<typename Derived>
5897QualType TreeTransform<Derived>::TransformDependentSizedExtVectorType(
5898 TypeLocBuilder &TLB,
5899 DependentSizedExtVectorTypeLoc TL) {
5900 const DependentSizedExtVectorType *T = TL.getTypePtr();
5901
5902 // FIXME: ext vector locs should be nested
5903 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
5904 if (ElementType.isNull())
5905 return QualType();
5906
5907 // Vector sizes are constant expressions.
5908 EnterExpressionEvaluationContext Unevaluated(
5909 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5910
5911 ExprResult Size = getDerived().TransformExpr(T->getSizeExpr());
5912 Size = SemaRef.ActOnConstantExpression(Res: Size);
5913 if (Size.isInvalid())
5914 return QualType();
5915
5916 QualType Result = TL.getType();
5917 if (getDerived().AlwaysRebuild() ||
5918 ElementType != T->getElementType() ||
5919 Size.get() != T->getSizeExpr()) {
5920 Result = getDerived().RebuildDependentSizedExtVectorType(ElementType,
5921 Size.get(),
5922 T->getAttributeLoc());
5923 if (Result.isNull())
5924 return QualType();
5925 }
5926
5927 // Result might be dependent or not.
5928 if (isa<DependentSizedExtVectorType>(Result)) {
5929 DependentSizedExtVectorTypeLoc NewTL
5930 = TLB.push<DependentSizedExtVectorTypeLoc>(Result);
5931 NewTL.setNameLoc(TL.getNameLoc());
5932 } else {
5933 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
5934 NewTL.setNameLoc(TL.getNameLoc());
5935 }
5936
5937 return Result;
5938}
5939
5940template <typename Derived>
5941QualType
5942TreeTransform<Derived>::TransformConstantMatrixType(TypeLocBuilder &TLB,
5943 ConstantMatrixTypeLoc TL) {
5944 const ConstantMatrixType *T = TL.getTypePtr();
5945 QualType ElementType = getDerived().TransformType(T->getElementType());
5946 if (ElementType.isNull())
5947 return QualType();
5948
5949 QualType Result = TL.getType();
5950 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType()) {
5951 Result = getDerived().RebuildConstantMatrixType(
5952 ElementType, T->getNumRows(), T->getNumColumns());
5953 if (Result.isNull())
5954 return QualType();
5955 }
5956
5957 ConstantMatrixTypeLoc NewTL = TLB.push<ConstantMatrixTypeLoc>(Result);
5958 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
5959 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
5960 NewTL.setAttrRowOperand(TL.getAttrRowOperand());
5961 NewTL.setAttrColumnOperand(TL.getAttrColumnOperand());
5962
5963 return Result;
5964}
5965
5966template <typename Derived>
5967QualType TreeTransform<Derived>::TransformDependentSizedMatrixType(
5968 TypeLocBuilder &TLB, DependentSizedMatrixTypeLoc TL) {
5969 const DependentSizedMatrixType *T = TL.getTypePtr();
5970
5971 QualType ElementType = getDerived().TransformType(T->getElementType());
5972 if (ElementType.isNull()) {
5973 return QualType();
5974 }
5975
5976 // Matrix dimensions are constant expressions.
5977 EnterExpressionEvaluationContext Unevaluated(
5978 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
5979
5980 Expr *origRows = TL.getAttrRowOperand();
5981 if (!origRows)
5982 origRows = T->getRowExpr();
5983 Expr *origColumns = TL.getAttrColumnOperand();
5984 if (!origColumns)
5985 origColumns = T->getColumnExpr();
5986
5987 ExprResult rowResult = getDerived().TransformExpr(origRows);
5988 rowResult = SemaRef.ActOnConstantExpression(Res: rowResult);
5989 if (rowResult.isInvalid())
5990 return QualType();
5991
5992 ExprResult columnResult = getDerived().TransformExpr(origColumns);
5993 columnResult = SemaRef.ActOnConstantExpression(Res: columnResult);
5994 if (columnResult.isInvalid())
5995 return QualType();
5996
5997 Expr *rows = rowResult.get();
5998 Expr *columns = columnResult.get();
5999
6000 QualType Result = TL.getType();
6001 if (getDerived().AlwaysRebuild() || ElementType != T->getElementType() ||
6002 rows != origRows || columns != origColumns) {
6003 Result = getDerived().RebuildDependentSizedMatrixType(
6004 ElementType, rows, columns, T->getAttributeLoc());
6005
6006 if (Result.isNull())
6007 return QualType();
6008 }
6009
6010 // We might have any sort of matrix type now, but fortunately they
6011 // all have the same location layout.
6012 MatrixTypeLoc NewTL = TLB.push<MatrixTypeLoc>(Result);
6013 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6014 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6015 NewTL.setAttrRowOperand(rows);
6016 NewTL.setAttrColumnOperand(columns);
6017 return Result;
6018}
6019
6020template <typename Derived>
6021QualType TreeTransform<Derived>::TransformDependentAddressSpaceType(
6022 TypeLocBuilder &TLB, DependentAddressSpaceTypeLoc TL) {
6023 const DependentAddressSpaceType *T = TL.getTypePtr();
6024
6025 QualType pointeeType =
6026 getDerived().TransformType(TLB, TL.getPointeeTypeLoc());
6027
6028 if (pointeeType.isNull())
6029 return QualType();
6030
6031 // Address spaces are constant expressions.
6032 EnterExpressionEvaluationContext Unevaluated(
6033 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6034
6035 ExprResult AddrSpace = getDerived().TransformExpr(T->getAddrSpaceExpr());
6036 AddrSpace = SemaRef.ActOnConstantExpression(Res: AddrSpace);
6037 if (AddrSpace.isInvalid())
6038 return QualType();
6039
6040 QualType Result = TL.getType();
6041 if (getDerived().AlwaysRebuild() || pointeeType != T->getPointeeType() ||
6042 AddrSpace.get() != T->getAddrSpaceExpr()) {
6043 Result = getDerived().RebuildDependentAddressSpaceType(
6044 pointeeType, AddrSpace.get(), T->getAttributeLoc());
6045 if (Result.isNull())
6046 return QualType();
6047 }
6048
6049 // Result might be dependent or not.
6050 if (isa<DependentAddressSpaceType>(Result)) {
6051 DependentAddressSpaceTypeLoc NewTL =
6052 TLB.push<DependentAddressSpaceTypeLoc>(Result);
6053
6054 NewTL.setAttrOperandParensRange(TL.getAttrOperandParensRange());
6055 NewTL.setAttrExprOperand(TL.getAttrExprOperand());
6056 NewTL.setAttrNameLoc(TL.getAttrNameLoc());
6057
6058 } else {
6059 TLB.TypeWasModifiedSafely(T: Result);
6060 }
6061
6062 return Result;
6063}
6064
6065template <typename Derived>
6066QualType TreeTransform<Derived>::TransformVectorType(TypeLocBuilder &TLB,
6067 VectorTypeLoc TL) {
6068 const VectorType *T = TL.getTypePtr();
6069 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6070 if (ElementType.isNull())
6071 return QualType();
6072
6073 QualType Result = TL.getType();
6074 if (getDerived().AlwaysRebuild() ||
6075 ElementType != T->getElementType()) {
6076 Result = getDerived().RebuildVectorType(ElementType, T->getNumElements(),
6077 T->getVectorKind());
6078 if (Result.isNull())
6079 return QualType();
6080 }
6081
6082 VectorTypeLoc NewTL = TLB.push<VectorTypeLoc>(Result);
6083 NewTL.setNameLoc(TL.getNameLoc());
6084
6085 return Result;
6086}
6087
6088template<typename Derived>
6089QualType TreeTransform<Derived>::TransformExtVectorType(TypeLocBuilder &TLB,
6090 ExtVectorTypeLoc TL) {
6091 const VectorType *T = TL.getTypePtr();
6092 QualType ElementType = getDerived().TransformType(TLB, TL.getElementLoc());
6093 if (ElementType.isNull())
6094 return QualType();
6095
6096 QualType Result = TL.getType();
6097 if (getDerived().AlwaysRebuild() ||
6098 ElementType != T->getElementType()) {
6099 Result = getDerived().RebuildExtVectorType(ElementType,
6100 T->getNumElements(),
6101 /*FIXME*/ SourceLocation());
6102 if (Result.isNull())
6103 return QualType();
6104 }
6105
6106 ExtVectorTypeLoc NewTL = TLB.push<ExtVectorTypeLoc>(Result);
6107 NewTL.setNameLoc(TL.getNameLoc());
6108
6109 return Result;
6110}
6111
6112template <typename Derived>
6113ParmVarDecl *TreeTransform<Derived>::TransformFunctionTypeParam(
6114 ParmVarDecl *OldParm, int indexAdjustment, UnsignedOrNone NumExpansions,
6115 bool ExpectParameterPack) {
6116 TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
6117 TypeSourceInfo *NewDI = nullptr;
6118
6119 if (NumExpansions && isa<PackExpansionType>(OldDI->getType())) {
6120 // If we're substituting into a pack expansion type and we know the
6121 // length we want to expand to, just substitute for the pattern.
6122 TypeLoc OldTL = OldDI->getTypeLoc();
6123 PackExpansionTypeLoc OldExpansionTL = OldTL.castAs<PackExpansionTypeLoc>();
6124
6125 TypeLocBuilder TLB;
6126 TypeLoc NewTL = OldDI->getTypeLoc();
6127 TLB.reserve(Requested: NewTL.getFullDataSize());
6128
6129 QualType Result = getDerived().TransformType(TLB,
6130 OldExpansionTL.getPatternLoc());
6131 if (Result.isNull())
6132 return nullptr;
6133
6134 Result = RebuildPackExpansionType(Pattern: Result,
6135 PatternRange: OldExpansionTL.getPatternLoc().getSourceRange(),
6136 EllipsisLoc: OldExpansionTL.getEllipsisLoc(),
6137 NumExpansions);
6138 if (Result.isNull())
6139 return nullptr;
6140
6141 PackExpansionTypeLoc NewExpansionTL
6142 = TLB.push<PackExpansionTypeLoc>(Result);
6143 NewExpansionTL.setEllipsisLoc(OldExpansionTL.getEllipsisLoc());
6144 NewDI = TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: Result);
6145 } else
6146 NewDI = getDerived().TransformType(OldDI);
6147 if (!NewDI)
6148 return nullptr;
6149
6150 if (NewDI == OldDI && indexAdjustment == 0)
6151 return OldParm;
6152
6153 ParmVarDecl *newParm = ParmVarDecl::Create(C&: SemaRef.Context,
6154 DC: OldParm->getDeclContext(),
6155 StartLoc: OldParm->getInnerLocStart(),
6156 IdLoc: OldParm->getLocation(),
6157 Id: OldParm->getIdentifier(),
6158 T: NewDI->getType(),
6159 TInfo: NewDI,
6160 S: OldParm->getStorageClass(),
6161 /* DefArg */ DefArg: nullptr);
6162 newParm->setScopeInfo(scopeDepth: OldParm->getFunctionScopeDepth(),
6163 parameterIndex: OldParm->getFunctionScopeIndex() + indexAdjustment);
6164 transformedLocalDecl(Old: OldParm, New: {newParm});
6165 return newParm;
6166}
6167
6168template <typename Derived>
6169bool TreeTransform<Derived>::TransformFunctionTypeParams(
6170 SourceLocation Loc, ArrayRef<ParmVarDecl *> Params,
6171 const QualType *ParamTypes,
6172 const FunctionProtoType::ExtParameterInfo *ParamInfos,
6173 SmallVectorImpl<QualType> &OutParamTypes,
6174 SmallVectorImpl<ParmVarDecl *> *PVars,
6175 Sema::ExtParameterInfoBuilder &PInfos,
6176 unsigned *LastParamTransformed) {
6177 int indexAdjustment = 0;
6178
6179 unsigned NumParams = Params.size();
6180 for (unsigned i = 0; i != NumParams; ++i) {
6181 if (LastParamTransformed)
6182 *LastParamTransformed = i;
6183 if (ParmVarDecl *OldParm = Params[i]) {
6184 assert(OldParm->getFunctionScopeIndex() == i);
6185
6186 UnsignedOrNone NumExpansions = std::nullopt;
6187 ParmVarDecl *NewParm = nullptr;
6188 if (OldParm->isParameterPack()) {
6189 // We have a function parameter pack that may need to be expanded.
6190 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6191
6192 // Find the parameter packs that could be expanded.
6193 TypeLoc TL = OldParm->getTypeSourceInfo()->getTypeLoc();
6194 PackExpansionTypeLoc ExpansionTL = TL.castAs<PackExpansionTypeLoc>();
6195 TypeLoc Pattern = ExpansionTL.getPatternLoc();
6196 SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded);
6197
6198 // Determine whether we should expand the parameter packs.
6199 bool ShouldExpand = false;
6200 bool RetainExpansion = false;
6201 UnsignedOrNone OrigNumExpansions = std::nullopt;
6202 if (Unexpanded.size() > 0) {
6203 OrigNumExpansions = ExpansionTL.getTypePtr()->getNumExpansions();
6204 NumExpansions = OrigNumExpansions;
6205 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
6206 Pattern.getSourceRange(),
6207 Unexpanded,
6208 ShouldExpand,
6209 RetainExpansion,
6210 NumExpansions)) {
6211 return true;
6212 }
6213 } else {
6214#ifndef NDEBUG
6215 const AutoType *AT =
6216 Pattern.getType().getTypePtr()->getContainedAutoType();
6217 assert((AT && (!AT->isDeduced() || AT->getDeducedType().isNull())) &&
6218 "Could not find parameter packs or undeduced auto type!");
6219#endif
6220 }
6221
6222 if (ShouldExpand) {
6223 // Expand the function parameter pack into multiple, separate
6224 // parameters.
6225 getDerived().ExpandingFunctionParameterPack(OldParm);
6226 for (unsigned I = 0; I != *NumExpansions; ++I) {
6227 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6228 ParmVarDecl *NewParm
6229 = getDerived().TransformFunctionTypeParam(OldParm,
6230 indexAdjustment++,
6231 OrigNumExpansions,
6232 /*ExpectParameterPack=*/false);
6233 if (!NewParm)
6234 return true;
6235
6236 if (ParamInfos)
6237 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6238 OutParamTypes.push_back(Elt: NewParm->getType());
6239 if (PVars)
6240 PVars->push_back(NewParm);
6241 }
6242
6243 // If we're supposed to retain a pack expansion, do so by temporarily
6244 // forgetting the partially-substituted parameter pack.
6245 if (RetainExpansion) {
6246 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6247 ParmVarDecl *NewParm
6248 = getDerived().TransformFunctionTypeParam(OldParm,
6249 indexAdjustment++,
6250 OrigNumExpansions,
6251 /*ExpectParameterPack=*/false);
6252 if (!NewParm)
6253 return true;
6254
6255 if (ParamInfos)
6256 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6257 OutParamTypes.push_back(Elt: NewParm->getType());
6258 if (PVars)
6259 PVars->push_back(NewParm);
6260 }
6261
6262 // The next parameter should have the same adjustment as the
6263 // last thing we pushed, but we post-incremented indexAdjustment
6264 // on every push. Also, if we push nothing, the adjustment should
6265 // go down by one.
6266 indexAdjustment--;
6267
6268 // We're done with the pack expansion.
6269 continue;
6270 }
6271
6272 // We'll substitute the parameter now without expanding the pack
6273 // expansion.
6274 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6275 NewParm = getDerived().TransformFunctionTypeParam(OldParm,
6276 indexAdjustment,
6277 NumExpansions,
6278 /*ExpectParameterPack=*/true);
6279 assert(NewParm->isParameterPack() &&
6280 "Parameter pack no longer a parameter pack after "
6281 "transformation.");
6282 } else {
6283 NewParm = getDerived().TransformFunctionTypeParam(
6284 OldParm, indexAdjustment, std::nullopt,
6285 /*ExpectParameterPack=*/false);
6286 }
6287
6288 if (!NewParm)
6289 return true;
6290
6291 if (ParamInfos)
6292 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6293 OutParamTypes.push_back(Elt: NewParm->getType());
6294 if (PVars)
6295 PVars->push_back(NewParm);
6296 continue;
6297 }
6298
6299 // Deal with the possibility that we don't have a parameter
6300 // declaration for this parameter.
6301 assert(ParamTypes);
6302 QualType OldType = ParamTypes[i];
6303 bool IsPackExpansion = false;
6304 UnsignedOrNone NumExpansions = std::nullopt;
6305 QualType NewType;
6306 if (const PackExpansionType *Expansion
6307 = dyn_cast<PackExpansionType>(OldType)) {
6308 // We have a function parameter pack that may need to be expanded.
6309 QualType Pattern = Expansion->getPattern();
6310 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6311 getSema().collectUnexpandedParameterPacks(Pattern, Unexpanded);
6312
6313 // Determine whether we should expand the parameter packs.
6314 bool ShouldExpand = false;
6315 bool RetainExpansion = false;
6316 if (getDerived().TryExpandParameterPacks(Loc, SourceRange(),
6317 Unexpanded,
6318 ShouldExpand,
6319 RetainExpansion,
6320 NumExpansions)) {
6321 return true;
6322 }
6323
6324 if (ShouldExpand) {
6325 // Expand the function parameter pack into multiple, separate
6326 // parameters.
6327 for (unsigned I = 0; I != *NumExpansions; ++I) {
6328 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6329 QualType NewType = getDerived().TransformType(Pattern);
6330 if (NewType.isNull())
6331 return true;
6332
6333 if (NewType->containsUnexpandedParameterPack()) {
6334 NewType = getSema().getASTContext().getPackExpansionType(
6335 NewType, std::nullopt);
6336
6337 if (NewType.isNull())
6338 return true;
6339 }
6340
6341 if (ParamInfos)
6342 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6343 OutParamTypes.push_back(Elt: NewType);
6344 if (PVars)
6345 PVars->push_back(nullptr);
6346 }
6347
6348 // We're done with the pack expansion.
6349 continue;
6350 }
6351
6352 // If we're supposed to retain a pack expansion, do so by temporarily
6353 // forgetting the partially-substituted parameter pack.
6354 if (RetainExpansion) {
6355 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6356 QualType NewType = getDerived().TransformType(Pattern);
6357 if (NewType.isNull())
6358 return true;
6359
6360 if (ParamInfos)
6361 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6362 OutParamTypes.push_back(Elt: NewType);
6363 if (PVars)
6364 PVars->push_back(nullptr);
6365 }
6366
6367 // We'll substitute the parameter now without expanding the pack
6368 // expansion.
6369 OldType = Expansion->getPattern();
6370 IsPackExpansion = true;
6371 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6372 NewType = getDerived().TransformType(OldType);
6373 } else {
6374 NewType = getDerived().TransformType(OldType);
6375 }
6376
6377 if (NewType.isNull())
6378 return true;
6379
6380 if (IsPackExpansion)
6381 NewType = getSema().Context.getPackExpansionType(NewType,
6382 NumExpansions);
6383
6384 if (ParamInfos)
6385 PInfos.set(index: OutParamTypes.size(), info: ParamInfos[i]);
6386 OutParamTypes.push_back(Elt: NewType);
6387 if (PVars)
6388 PVars->push_back(nullptr);
6389 }
6390
6391#ifndef NDEBUG
6392 if (PVars) {
6393 for (unsigned i = 0, e = PVars->size(); i != e; ++i)
6394 if (ParmVarDecl *parm = (*PVars)[i])
6395 assert(parm->getFunctionScopeIndex() == i);
6396 }
6397#endif
6398
6399 return false;
6400}
6401
6402template<typename Derived>
6403QualType
6404TreeTransform<Derived>::TransformFunctionProtoType(TypeLocBuilder &TLB,
6405 FunctionProtoTypeLoc TL) {
6406 SmallVector<QualType, 4> ExceptionStorage;
6407 return getDerived().TransformFunctionProtoType(
6408 TLB, TL, nullptr, Qualifiers(),
6409 [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
6410 return getDerived().TransformExceptionSpec(TL.getBeginLoc(), ESI,
6411 ExceptionStorage, Changed);
6412 });
6413}
6414
6415template<typename Derived> template<typename Fn>
6416QualType TreeTransform<Derived>::TransformFunctionProtoType(
6417 TypeLocBuilder &TLB, FunctionProtoTypeLoc TL, CXXRecordDecl *ThisContext,
6418 Qualifiers ThisTypeQuals, Fn TransformExceptionSpec) {
6419
6420 // Transform the parameters and return type.
6421 //
6422 // We are required to instantiate the params and return type in source order.
6423 // When the function has a trailing return type, we instantiate the
6424 // parameters before the return type, since the return type can then refer
6425 // to the parameters themselves (via decltype, sizeof, etc.).
6426 //
6427 SmallVector<QualType, 4> ParamTypes;
6428 SmallVector<ParmVarDecl*, 4> ParamDecls;
6429 Sema::ExtParameterInfoBuilder ExtParamInfos;
6430 const FunctionProtoType *T = TL.getTypePtr();
6431
6432 QualType ResultType;
6433
6434 if (T->hasTrailingReturn()) {
6435 if (getDerived().TransformFunctionTypeParams(
6436 TL.getBeginLoc(), TL.getParams(),
6437 TL.getTypePtr()->param_type_begin(),
6438 T->getExtParameterInfosOrNull(),
6439 ParamTypes, &ParamDecls, ExtParamInfos))
6440 return QualType();
6441
6442 {
6443 // C++11 [expr.prim.general]p3:
6444 // If a declaration declares a member function or member function
6445 // template of a class X, the expression this is a prvalue of type
6446 // "pointer to cv-qualifier-seq X" between the optional cv-qualifer-seq
6447 // and the end of the function-definition, member-declarator, or
6448 // declarator.
6449 auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.getCurLexicalContext());
6450 Sema::CXXThisScopeRAII ThisScope(
6451 SemaRef, !ThisContext && RD ? RD : ThisContext, ThisTypeQuals);
6452
6453 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6454 if (ResultType.isNull())
6455 return QualType();
6456 }
6457 }
6458 else {
6459 ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6460 if (ResultType.isNull())
6461 return QualType();
6462
6463 if (getDerived().TransformFunctionTypeParams(
6464 TL.getBeginLoc(), TL.getParams(),
6465 TL.getTypePtr()->param_type_begin(),
6466 T->getExtParameterInfosOrNull(),
6467 ParamTypes, &ParamDecls, ExtParamInfos))
6468 return QualType();
6469 }
6470
6471 FunctionProtoType::ExtProtoInfo EPI = T->getExtProtoInfo();
6472
6473 bool EPIChanged = false;
6474 if (TransformExceptionSpec(EPI.ExceptionSpec, EPIChanged))
6475 return QualType();
6476
6477 // Handle extended parameter information.
6478 if (auto NewExtParamInfos =
6479 ExtParamInfos.getPointerOrNull(numParams: ParamTypes.size())) {
6480 if (!EPI.ExtParameterInfos ||
6481 llvm::ArrayRef(EPI.ExtParameterInfos, TL.getNumParams()) !=
6482 llvm::ArrayRef(NewExtParamInfos, ParamTypes.size())) {
6483 EPIChanged = true;
6484 }
6485 EPI.ExtParameterInfos = NewExtParamInfos;
6486 } else if (EPI.ExtParameterInfos) {
6487 EPIChanged = true;
6488 EPI.ExtParameterInfos = nullptr;
6489 }
6490
6491 // Transform any function effects with unevaluated conditions.
6492 // Hold this set in a local for the rest of this function, since EPI
6493 // may need to hold a FunctionEffectsRef pointing into it.
6494 std::optional<FunctionEffectSet> NewFX;
6495 if (ArrayRef FXConds = EPI.FunctionEffects.conditions(); !FXConds.empty()) {
6496 NewFX.emplace();
6497 EnterExpressionEvaluationContext Unevaluated(
6498 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6499
6500 for (const FunctionEffectWithCondition &PrevEC : EPI.FunctionEffects) {
6501 FunctionEffectWithCondition NewEC = PrevEC;
6502 if (Expr *CondExpr = PrevEC.Cond.getCondition()) {
6503 ExprResult NewExpr = getDerived().TransformExpr(CondExpr);
6504 if (NewExpr.isInvalid())
6505 return QualType();
6506 std::optional<FunctionEffectMode> Mode =
6507 SemaRef.ActOnEffectExpression(NewExpr.get(), PrevEC.Effect.name());
6508 if (!Mode)
6509 return QualType();
6510
6511 // The condition expression has been transformed, and re-evaluated.
6512 // It may or may not have become constant.
6513 switch (*Mode) {
6514 case FunctionEffectMode::True:
6515 NewEC.Cond = {};
6516 break;
6517 case FunctionEffectMode::False:
6518 NewEC.Effect = FunctionEffect(PrevEC.Effect.oppositeKind());
6519 NewEC.Cond = {};
6520 break;
6521 case FunctionEffectMode::Dependent:
6522 NewEC.Cond = EffectConditionExpr(NewExpr.get());
6523 break;
6524 case FunctionEffectMode::None:
6525 llvm_unreachable(
6526 "FunctionEffectMode::None shouldn't be possible here");
6527 }
6528 }
6529 if (!SemaRef.diagnoseConflictingFunctionEffect(*NewFX, NewEC,
6530 TL.getBeginLoc())) {
6531 FunctionEffectSet::Conflicts Errs;
6532 NewFX->insert(NewEC, Errs);
6533 assert(Errs.empty());
6534 }
6535 }
6536 EPI.FunctionEffects = *NewFX;
6537 EPIChanged = true;
6538 }
6539
6540 QualType Result = TL.getType();
6541 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType() ||
6542 T->getParamTypes() != llvm::ArrayRef(ParamTypes) || EPIChanged) {
6543 Result = getDerived().RebuildFunctionProtoType(ResultType, ParamTypes, EPI);
6544 if (Result.isNull())
6545 return QualType();
6546 }
6547
6548 FunctionProtoTypeLoc NewTL = TLB.push<FunctionProtoTypeLoc>(Result);
6549 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6550 NewTL.setLParenLoc(TL.getLParenLoc());
6551 NewTL.setRParenLoc(TL.getRParenLoc());
6552 NewTL.setExceptionSpecRange(TL.getExceptionSpecRange());
6553 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6554 for (unsigned i = 0, e = NewTL.getNumParams(); i != e; ++i)
6555 NewTL.setParam(i, ParamDecls[i]);
6556
6557 return Result;
6558}
6559
6560template<typename Derived>
6561bool TreeTransform<Derived>::TransformExceptionSpec(
6562 SourceLocation Loc, FunctionProtoType::ExceptionSpecInfo &ESI,
6563 SmallVectorImpl<QualType> &Exceptions, bool &Changed) {
6564 assert(ESI.Type != EST_Uninstantiated && ESI.Type != EST_Unevaluated);
6565
6566 // Instantiate a dynamic noexcept expression, if any.
6567 if (isComputedNoexcept(ESpecType: ESI.Type)) {
6568 // Update this scrope because ContextDecl in Sema will be used in
6569 // TransformExpr.
6570 auto *Method = dyn_cast_if_present<CXXMethodDecl>(ESI.SourceTemplate);
6571 Sema::CXXThisScopeRAII ThisScope(
6572 SemaRef, Method ? Method->getParent() : nullptr,
6573 Method ? Method->getMethodQualifiers() : Qualifiers{},
6574 Method != nullptr);
6575 EnterExpressionEvaluationContext Unevaluated(
6576 getSema(), Sema::ExpressionEvaluationContext::ConstantEvaluated);
6577 ExprResult NoexceptExpr = getDerived().TransformExpr(ESI.NoexceptExpr);
6578 if (NoexceptExpr.isInvalid())
6579 return true;
6580
6581 ExceptionSpecificationType EST = ESI.Type;
6582 NoexceptExpr =
6583 getSema().ActOnNoexceptSpec(NoexceptExpr.get(), EST);
6584 if (NoexceptExpr.isInvalid())
6585 return true;
6586
6587 if (ESI.NoexceptExpr != NoexceptExpr.get() || EST != ESI.Type)
6588 Changed = true;
6589 ESI.NoexceptExpr = NoexceptExpr.get();
6590 ESI.Type = EST;
6591 }
6592
6593 if (ESI.Type != EST_Dynamic)
6594 return false;
6595
6596 // Instantiate a dynamic exception specification's type.
6597 for (QualType T : ESI.Exceptions) {
6598 if (const PackExpansionType *PackExpansion =
6599 T->getAs<PackExpansionType>()) {
6600 Changed = true;
6601
6602 // We have a pack expansion. Instantiate it.
6603 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6604 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
6605 Unexpanded);
6606 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6607
6608 // Determine whether the set of unexpanded parameter packs can and
6609 // should
6610 // be expanded.
6611 bool Expand = false;
6612 bool RetainExpansion = false;
6613 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
6614 // FIXME: Track the location of the ellipsis (and track source location
6615 // information for the types in the exception specification in general).
6616 if (getDerived().TryExpandParameterPacks(
6617 Loc, SourceRange(), Unexpanded, Expand,
6618 RetainExpansion, NumExpansions))
6619 return true;
6620
6621 if (!Expand) {
6622 // We can't expand this pack expansion into separate arguments yet;
6623 // just substitute into the pattern and create a new pack expansion
6624 // type.
6625 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6626 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6627 if (U.isNull())
6628 return true;
6629
6630 U = SemaRef.Context.getPackExpansionType(U, NumExpansions);
6631 Exceptions.push_back(U);
6632 continue;
6633 }
6634
6635 // Substitute into the pack expansion pattern for each slice of the
6636 // pack.
6637 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
6638 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
6639
6640 QualType U = getDerived().TransformType(PackExpansion->getPattern());
6641 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6642 return true;
6643
6644 Exceptions.push_back(U);
6645 }
6646 } else {
6647 QualType U = getDerived().TransformType(T);
6648 if (U.isNull() || SemaRef.CheckSpecifiedExceptionType(U, Loc))
6649 return true;
6650 if (T != U)
6651 Changed = true;
6652
6653 Exceptions.push_back(U);
6654 }
6655 }
6656
6657 ESI.Exceptions = Exceptions;
6658 if (ESI.Exceptions.empty())
6659 ESI.Type = EST_DynamicNone;
6660 return false;
6661}
6662
6663template<typename Derived>
6664QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
6665 TypeLocBuilder &TLB,
6666 FunctionNoProtoTypeLoc TL) {
6667 const FunctionNoProtoType *T = TL.getTypePtr();
6668 QualType ResultType = getDerived().TransformType(TLB, TL.getReturnLoc());
6669 if (ResultType.isNull())
6670 return QualType();
6671
6672 QualType Result = TL.getType();
6673 if (getDerived().AlwaysRebuild() || ResultType != T->getReturnType())
6674 Result = getDerived().RebuildFunctionNoProtoType(ResultType);
6675
6676 FunctionNoProtoTypeLoc NewTL = TLB.push<FunctionNoProtoTypeLoc>(Result);
6677 NewTL.setLocalRangeBegin(TL.getLocalRangeBegin());
6678 NewTL.setLParenLoc(TL.getLParenLoc());
6679 NewTL.setRParenLoc(TL.getRParenLoc());
6680 NewTL.setLocalRangeEnd(TL.getLocalRangeEnd());
6681
6682 return Result;
6683}
6684
6685template <typename Derived>
6686QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
6687 TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
6688 const UnresolvedUsingType *T = TL.getTypePtr();
6689 Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
6690 if (!D)
6691 return QualType();
6692
6693 QualType Result = TL.getType();
6694 if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
6695 Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
6696 if (Result.isNull())
6697 return QualType();
6698 }
6699
6700 // We might get an arbitrary type spec type back. We should at
6701 // least always get a type spec type, though.
6702 TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(T: Result);
6703 NewTL.setNameLoc(TL.getNameLoc());
6704
6705 return Result;
6706}
6707
6708template <typename Derived>
6709QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
6710 UsingTypeLoc TL) {
6711 const UsingType *T = TL.getTypePtr();
6712
6713 auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
6714 TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
6715 if (!Found)
6716 return QualType();
6717
6718 QualType Underlying = getDerived().TransformType(T->desugar());
6719 if (Underlying.isNull())
6720 return QualType();
6721
6722 QualType Result = TL.getType();
6723 if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
6724 Underlying != T->getUnderlyingType()) {
6725 Result = getDerived().RebuildUsingType(Found, Underlying);
6726 if (Result.isNull())
6727 return QualType();
6728 }
6729
6730 TLB.pushTypeSpec(T: Result).setNameLoc(TL.getNameLoc());
6731 return Result;
6732}
6733
6734template<typename Derived>
6735QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
6736 TypedefTypeLoc TL) {
6737 const TypedefType *T = TL.getTypePtr();
6738 TypedefNameDecl *Typedef
6739 = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
6740 T->getDecl()));
6741 if (!Typedef)
6742 return QualType();
6743
6744 QualType Result = TL.getType();
6745 if (getDerived().AlwaysRebuild() ||
6746 Typedef != T->getDecl()) {
6747 Result = getDerived().RebuildTypedefType(Typedef);
6748 if (Result.isNull())
6749 return QualType();
6750 }
6751
6752 TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
6753 NewTL.setNameLoc(TL.getNameLoc());
6754
6755 return Result;
6756}
6757
6758template<typename Derived>
6759QualType TreeTransform<Derived>::TransformTypeOfExprType(TypeLocBuilder &TLB,
6760 TypeOfExprTypeLoc TL) {
6761 // typeof expressions are not potentially evaluated contexts
6762 EnterExpressionEvaluationContext Unevaluated(
6763 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
6764 Sema::ReuseLambdaContextDecl);
6765
6766 ExprResult E = getDerived().TransformExpr(TL.getUnderlyingExpr());
6767 if (E.isInvalid())
6768 return QualType();
6769
6770 E = SemaRef.HandleExprEvaluationContextForTypeof(E: E.get());
6771 if (E.isInvalid())
6772 return QualType();
6773
6774 QualType Result = TL.getType();
6775 TypeOfKind Kind = Result->castAs<TypeOfExprType>()->getKind();
6776 if (getDerived().AlwaysRebuild() || E.get() != TL.getUnderlyingExpr()) {
6777 Result =
6778 getDerived().RebuildTypeOfExprType(E.get(), TL.getTypeofLoc(), Kind);
6779 if (Result.isNull())
6780 return QualType();
6781 }
6782
6783 TypeOfExprTypeLoc NewTL = TLB.push<TypeOfExprTypeLoc>(Result);
6784 NewTL.setTypeofLoc(TL.getTypeofLoc());
6785 NewTL.setLParenLoc(TL.getLParenLoc());
6786 NewTL.setRParenLoc(TL.getRParenLoc());
6787
6788 return Result;
6789}
6790
6791template<typename Derived>
6792QualType TreeTransform<Derived>::TransformTypeOfType(TypeLocBuilder &TLB,
6793 TypeOfTypeLoc TL) {
6794 TypeSourceInfo* Old_Under_TI = TL.getUnmodifiedTInfo();
6795 TypeSourceInfo* New_Under_TI = getDerived().TransformType(Old_Under_TI);
6796 if (!New_Under_TI)
6797 return QualType();
6798
6799 QualType Result = TL.getType();
6800 TypeOfKind Kind = Result->castAs<TypeOfType>()->getKind();
6801 if (getDerived().AlwaysRebuild() || New_Under_TI != Old_Under_TI) {
6802 Result = getDerived().RebuildTypeOfType(New_Under_TI->getType(), Kind);
6803 if (Result.isNull())
6804 return QualType();
6805 }
6806
6807 TypeOfTypeLoc NewTL = TLB.push<TypeOfTypeLoc>(Result);
6808 NewTL.setTypeofLoc(TL.getTypeofLoc());
6809 NewTL.setLParenLoc(TL.getLParenLoc());
6810 NewTL.setRParenLoc(TL.getRParenLoc());
6811 NewTL.setUnmodifiedTInfo(New_Under_TI);
6812
6813 return Result;
6814}
6815
6816template<typename Derived>
6817QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB,
6818 DecltypeTypeLoc TL) {
6819 const DecltypeType *T = TL.getTypePtr();
6820
6821 // decltype expressions are not potentially evaluated contexts
6822 EnterExpressionEvaluationContext Unevaluated(
6823 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated, nullptr,
6824 Sema::ExpressionEvaluationContextRecord::EK_Decltype);
6825
6826 ExprResult E = getDerived().TransformExpr(T->getUnderlyingExpr());
6827 if (E.isInvalid())
6828 return QualType();
6829
6830 E = getSema().ActOnDecltypeExpression(E.get());
6831 if (E.isInvalid())
6832 return QualType();
6833
6834 QualType Result = TL.getType();
6835 if (getDerived().AlwaysRebuild() ||
6836 E.get() != T->getUnderlyingExpr()) {
6837 Result = getDerived().RebuildDecltypeType(E.get(), TL.getDecltypeLoc());
6838 if (Result.isNull())
6839 return QualType();
6840 }
6841 else E.get();
6842
6843 DecltypeTypeLoc NewTL = TLB.push<DecltypeTypeLoc>(Result);
6844 NewTL.setDecltypeLoc(TL.getDecltypeLoc());
6845 NewTL.setRParenLoc(TL.getRParenLoc());
6846 return Result;
6847}
6848
6849template <typename Derived>
6850QualType
6851TreeTransform<Derived>::TransformPackIndexingType(TypeLocBuilder &TLB,
6852 PackIndexingTypeLoc TL) {
6853 // Transform the index
6854 ExprResult IndexExpr;
6855 {
6856 EnterExpressionEvaluationContext ConstantContext(
6857 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
6858
6859 IndexExpr = getDerived().TransformExpr(TL.getIndexExpr());
6860 if (IndexExpr.isInvalid())
6861 return QualType();
6862 }
6863 QualType Pattern = TL.getPattern();
6864
6865 const PackIndexingType *PIT = TL.getTypePtr();
6866 SmallVector<QualType, 5> SubtitutedTypes;
6867 llvm::ArrayRef<QualType> Types = PIT->getExpansions();
6868
6869 bool NotYetExpanded = Types.empty();
6870 bool FullySubstituted = true;
6871
6872 if (Types.empty() && !PIT->expandsToEmptyPack())
6873 Types = llvm::ArrayRef<QualType>(&Pattern, 1);
6874
6875 for (QualType T : Types) {
6876 if (!T->containsUnexpandedParameterPack()) {
6877 QualType Transformed = getDerived().TransformType(T);
6878 if (Transformed.isNull())
6879 return QualType();
6880 SubtitutedTypes.push_back(Transformed);
6881 continue;
6882 }
6883
6884 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
6885 getSema().collectUnexpandedParameterPacks(T, Unexpanded);
6886 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
6887 // Determine whether the set of unexpanded parameter packs can and should
6888 // be expanded.
6889 bool ShouldExpand = true;
6890 bool RetainExpansion = false;
6891 UnsignedOrNone NumExpansions = std::nullopt;
6892 if (getDerived().TryExpandParameterPacks(TL.getEllipsisLoc(), SourceRange(),
6893 Unexpanded, ShouldExpand,
6894 RetainExpansion, NumExpansions))
6895 return QualType();
6896 if (!ShouldExpand) {
6897 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6898 // FIXME: should we keep TypeLoc for individual expansions in
6899 // PackIndexingTypeLoc?
6900 TypeSourceInfo *TI =
6901 SemaRef.getASTContext().getTrivialTypeSourceInfo(T, TL.getBeginLoc());
6902 QualType Pack = getDerived().TransformType(TLB, TI->getTypeLoc());
6903 if (Pack.isNull())
6904 return QualType();
6905 if (NotYetExpanded) {
6906 FullySubstituted = false;
6907 QualType Out = getDerived().RebuildPackIndexingType(
6908 Pack, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6909 FullySubstituted);
6910 if (Out.isNull())
6911 return QualType();
6912
6913 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6914 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6915 return Out;
6916 }
6917 SubtitutedTypes.push_back(Pack);
6918 continue;
6919 }
6920 for (unsigned I = 0; I != *NumExpansions; ++I) {
6921 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
6922 QualType Out = getDerived().TransformType(T);
6923 if (Out.isNull())
6924 return QualType();
6925 SubtitutedTypes.push_back(Out);
6926 FullySubstituted &= !Out->containsUnexpandedParameterPack();
6927 }
6928 // If we're supposed to retain a pack expansion, do so by temporarily
6929 // forgetting the partially-substituted parameter pack.
6930 if (RetainExpansion) {
6931 FullySubstituted = false;
6932 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
6933 QualType Out = getDerived().TransformType(T);
6934 if (Out.isNull())
6935 return QualType();
6936 SubtitutedTypes.push_back(Out);
6937 }
6938 }
6939
6940 // A pack indexing type can appear in a larger pack expansion,
6941 // e.g. `Pack...[pack_of_indexes]...`
6942 // so we need to temporarily disable substitution of pack elements
6943 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
6944 QualType Result = getDerived().TransformType(TLB, TL.getPatternLoc());
6945
6946 QualType Out = getDerived().RebuildPackIndexingType(
6947 Result, IndexExpr.get(), SourceLocation(), TL.getEllipsisLoc(),
6948 FullySubstituted, SubtitutedTypes);
6949 if (Out.isNull())
6950 return Out;
6951
6952 PackIndexingTypeLoc Loc = TLB.push<PackIndexingTypeLoc>(Out);
6953 Loc.setEllipsisLoc(TL.getEllipsisLoc());
6954 return Out;
6955}
6956
6957template<typename Derived>
6958QualType TreeTransform<Derived>::TransformUnaryTransformType(
6959 TypeLocBuilder &TLB,
6960 UnaryTransformTypeLoc TL) {
6961 QualType Result = TL.getType();
6962 if (Result->isDependentType()) {
6963 const UnaryTransformType *T = TL.getTypePtr();
6964
6965 TypeSourceInfo *NewBaseTSI =
6966 getDerived().TransformType(TL.getUnderlyingTInfo());
6967 if (!NewBaseTSI)
6968 return QualType();
6969 QualType NewBase = NewBaseTSI->getType();
6970
6971 Result = getDerived().RebuildUnaryTransformType(NewBase,
6972 T->getUTTKind(),
6973 TL.getKWLoc());
6974 if (Result.isNull())
6975 return QualType();
6976 }
6977
6978 UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result);
6979 NewTL.setKWLoc(TL.getKWLoc());
6980 NewTL.setParensRange(TL.getParensRange());
6981 NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo());
6982 return Result;
6983}
6984
6985template<typename Derived>
6986QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
6987 TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
6988 const DeducedTemplateSpecializationType *T = TL.getTypePtr();
6989
6990 CXXScopeSpec SS;
6991 TemplateName TemplateName = getDerived().TransformTemplateName(
6992 SS, T->getTemplateName(), TL.getTemplateNameLoc());
6993 if (TemplateName.isNull())
6994 return QualType();
6995
6996 QualType OldDeduced = T->getDeducedType();
6997 QualType NewDeduced;
6998 if (!OldDeduced.isNull()) {
6999 NewDeduced = getDerived().TransformType(OldDeduced);
7000 if (NewDeduced.isNull())
7001 return QualType();
7002 }
7003
7004 QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
7005 TemplateName, NewDeduced);
7006 if (Result.isNull())
7007 return QualType();
7008
7009 DeducedTemplateSpecializationTypeLoc NewTL =
7010 TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
7011 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7012
7013 return Result;
7014}
7015
7016template<typename Derived>
7017QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
7018 RecordTypeLoc TL) {
7019 const RecordType *T = TL.getTypePtr();
7020 RecordDecl *Record
7021 = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7022 T->getDecl()));
7023 if (!Record)
7024 return QualType();
7025
7026 QualType Result = TL.getType();
7027 if (getDerived().AlwaysRebuild() ||
7028 Record != T->getDecl()) {
7029 Result = getDerived().RebuildRecordType(Record);
7030 if (Result.isNull())
7031 return QualType();
7032 }
7033
7034 RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
7035 NewTL.setNameLoc(TL.getNameLoc());
7036
7037 return Result;
7038}
7039
7040template<typename Derived>
7041QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
7042 EnumTypeLoc TL) {
7043 const EnumType *T = TL.getTypePtr();
7044 EnumDecl *Enum
7045 = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
7046 T->getDecl()));
7047 if (!Enum)
7048 return QualType();
7049
7050 QualType Result = TL.getType();
7051 if (getDerived().AlwaysRebuild() ||
7052 Enum != T->getDecl()) {
7053 Result = getDerived().RebuildEnumType(Enum);
7054 if (Result.isNull())
7055 return QualType();
7056 }
7057
7058 EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
7059 NewTL.setNameLoc(TL.getNameLoc());
7060
7061 return Result;
7062}
7063
7064template<typename Derived>
7065QualType TreeTransform<Derived>::TransformInjectedClassNameType(
7066 TypeLocBuilder &TLB,
7067 InjectedClassNameTypeLoc TL) {
7068 Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
7069 TL.getTypePtr()->getDecl());
7070 if (!D) return QualType();
7071
7072 QualType T = SemaRef.Context.getTypeDeclType(Decl: cast<TypeDecl>(D));
7073 TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
7074 return T;
7075}
7076
7077template<typename Derived>
7078QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7079 TypeLocBuilder &TLB,
7080 TemplateTypeParmTypeLoc TL) {
7081 return getDerived().TransformTemplateTypeParmType(
7082 TLB, TL,
7083 /*SuppressObjCLifetime=*/false);
7084}
7085
7086template <typename Derived>
7087QualType TreeTransform<Derived>::TransformTemplateTypeParmType(
7088 TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL, bool) {
7089 return TransformTypeSpecType(TLB, TL);
7090}
7091
7092template<typename Derived>
7093QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType(
7094 TypeLocBuilder &TLB,
7095 SubstTemplateTypeParmTypeLoc TL) {
7096 const SubstTemplateTypeParmType *T = TL.getTypePtr();
7097
7098 Decl *NewReplaced =
7099 getDerived().TransformDecl(TL.getNameLoc(), T->getAssociatedDecl());
7100
7101 // Substitute into the replacement type, which itself might involve something
7102 // that needs to be transformed. This only tends to occur with default
7103 // template arguments of template template parameters.
7104 TemporaryBase Rebase(*this, TL.getNameLoc(), DeclarationName());
7105 QualType Replacement = getDerived().TransformType(T->getReplacementType());
7106 if (Replacement.isNull())
7107 return QualType();
7108
7109 QualType Result = SemaRef.Context.getSubstTemplateTypeParmType(
7110 Replacement, AssociatedDecl: NewReplaced, Index: T->getIndex(), PackIndex: T->getPackIndex(),
7111 Final: T->getFinal());
7112
7113 // Propagate type-source information.
7114 SubstTemplateTypeParmTypeLoc NewTL
7115 = TLB.push<SubstTemplateTypeParmTypeLoc>(Result);
7116 NewTL.setNameLoc(TL.getNameLoc());
7117 return Result;
7118
7119}
7120
7121template<typename Derived>
7122QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7123 TypeLocBuilder &TLB,
7124 SubstTemplateTypeParmPackTypeLoc TL) {
7125 return getDerived().TransformSubstTemplateTypeParmPackType(
7126 TLB, TL, /*SuppressObjCLifetime=*/false);
7127}
7128
7129template <typename Derived>
7130QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
7131 TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL, bool) {
7132 return TransformTypeSpecType(TLB, TL);
7133}
7134
7135template<typename Derived>
7136QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7137 TypeLocBuilder &TLB,
7138 TemplateSpecializationTypeLoc TL) {
7139 const TemplateSpecializationType *T = TL.getTypePtr();
7140
7141 // The nested-name-specifier never matters in a TemplateSpecializationType,
7142 // because we can't have a dependent nested-name-specifier anyway.
7143 CXXScopeSpec SS;
7144 TemplateName Template
7145 = getDerived().TransformTemplateName(SS, T->getTemplateName(),
7146 TL.getTemplateNameLoc());
7147 if (Template.isNull())
7148 return QualType();
7149
7150 return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
7151}
7152
7153template<typename Derived>
7154QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
7155 AtomicTypeLoc TL) {
7156 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7157 if (ValueType.isNull())
7158 return QualType();
7159
7160 QualType Result = TL.getType();
7161 if (getDerived().AlwaysRebuild() ||
7162 ValueType != TL.getValueLoc().getType()) {
7163 Result = getDerived().RebuildAtomicType(ValueType, TL.getKWLoc());
7164 if (Result.isNull())
7165 return QualType();
7166 }
7167
7168 AtomicTypeLoc NewTL = TLB.push<AtomicTypeLoc>(Result);
7169 NewTL.setKWLoc(TL.getKWLoc());
7170 NewTL.setLParenLoc(TL.getLParenLoc());
7171 NewTL.setRParenLoc(TL.getRParenLoc());
7172
7173 return Result;
7174}
7175
7176template <typename Derived>
7177QualType TreeTransform<Derived>::TransformPipeType(TypeLocBuilder &TLB,
7178 PipeTypeLoc TL) {
7179 QualType ValueType = getDerived().TransformType(TLB, TL.getValueLoc());
7180 if (ValueType.isNull())
7181 return QualType();
7182
7183 QualType Result = TL.getType();
7184 if (getDerived().AlwaysRebuild() || ValueType != TL.getValueLoc().getType()) {
7185 const PipeType *PT = Result->castAs<PipeType>();
7186 bool isReadPipe = PT->isReadOnly();
7187 Result = getDerived().RebuildPipeType(ValueType, TL.getKWLoc(), isReadPipe);
7188 if (Result.isNull())
7189 return QualType();
7190 }
7191
7192 PipeTypeLoc NewTL = TLB.push<PipeTypeLoc>(Result);
7193 NewTL.setKWLoc(TL.getKWLoc());
7194
7195 return Result;
7196}
7197
7198template <typename Derived>
7199QualType TreeTransform<Derived>::TransformBitIntType(TypeLocBuilder &TLB,
7200 BitIntTypeLoc TL) {
7201 const BitIntType *EIT = TL.getTypePtr();
7202 QualType Result = TL.getType();
7203
7204 if (getDerived().AlwaysRebuild()) {
7205 Result = getDerived().RebuildBitIntType(EIT->isUnsigned(),
7206 EIT->getNumBits(), TL.getNameLoc());
7207 if (Result.isNull())
7208 return QualType();
7209 }
7210
7211 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7212 NewTL.setNameLoc(TL.getNameLoc());
7213 return Result;
7214}
7215
7216template <typename Derived>
7217QualType TreeTransform<Derived>::TransformDependentBitIntType(
7218 TypeLocBuilder &TLB, DependentBitIntTypeLoc TL) {
7219 const DependentBitIntType *EIT = TL.getTypePtr();
7220
7221 EnterExpressionEvaluationContext Unevaluated(
7222 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
7223 ExprResult BitsExpr = getDerived().TransformExpr(EIT->getNumBitsExpr());
7224 BitsExpr = SemaRef.ActOnConstantExpression(Res: BitsExpr);
7225
7226 if (BitsExpr.isInvalid())
7227 return QualType();
7228
7229 QualType Result = TL.getType();
7230
7231 if (getDerived().AlwaysRebuild() || BitsExpr.get() != EIT->getNumBitsExpr()) {
7232 Result = getDerived().RebuildDependentBitIntType(
7233 EIT->isUnsigned(), BitsExpr.get(), TL.getNameLoc());
7234
7235 if (Result.isNull())
7236 return QualType();
7237 }
7238
7239 if (isa<DependentBitIntType>(Result)) {
7240 DependentBitIntTypeLoc NewTL = TLB.push<DependentBitIntTypeLoc>(Result);
7241 NewTL.setNameLoc(TL.getNameLoc());
7242 } else {
7243 BitIntTypeLoc NewTL = TLB.push<BitIntTypeLoc>(Result);
7244 NewTL.setNameLoc(TL.getNameLoc());
7245 }
7246 return Result;
7247}
7248
7249 /// Simple iterator that traverses the template arguments in a
7250 /// container that provides a \c getArgLoc() member function.
7251 ///
7252 /// This iterator is intended to be used with the iterator form of
7253 /// \c TreeTransform<Derived>::TransformTemplateArguments().
7254 template<typename ArgLocContainer>
7255 class TemplateArgumentLocContainerIterator {
7256 ArgLocContainer *Container;
7257 unsigned Index;
7258
7259 public:
7260 typedef TemplateArgumentLoc value_type;
7261 typedef TemplateArgumentLoc reference;
7262 typedef int difference_type;
7263 typedef std::input_iterator_tag iterator_category;
7264
7265 class pointer {
7266 TemplateArgumentLoc Arg;
7267
7268 public:
7269 explicit pointer(TemplateArgumentLoc Arg) : Arg(Arg) { }
7270
7271 const TemplateArgumentLoc *operator->() const {
7272 return &Arg;
7273 }
7274 };
7275
7276
7277 TemplateArgumentLocContainerIterator() {}
7278
7279 TemplateArgumentLocContainerIterator(ArgLocContainer &Container,
7280 unsigned Index)
7281 : Container(&Container), Index(Index) { }
7282
7283 TemplateArgumentLocContainerIterator &operator++() {
7284 ++Index;
7285 return *this;
7286 }
7287
7288 TemplateArgumentLocContainerIterator operator++(int) {
7289 TemplateArgumentLocContainerIterator Old(*this);
7290 ++(*this);
7291 return Old;
7292 }
7293
7294 TemplateArgumentLoc operator*() const {
7295 return Container->getArgLoc(Index);
7296 }
7297
7298 pointer operator->() const {
7299 return pointer(Container->getArgLoc(Index));
7300 }
7301
7302 friend bool operator==(const TemplateArgumentLocContainerIterator &X,
7303 const TemplateArgumentLocContainerIterator &Y) {
7304 return X.Container == Y.Container && X.Index == Y.Index;
7305 }
7306
7307 friend bool operator!=(const TemplateArgumentLocContainerIterator &X,
7308 const TemplateArgumentLocContainerIterator &Y) {
7309 return !(X == Y);
7310 }
7311 };
7312
7313template<typename Derived>
7314QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
7315 AutoTypeLoc TL) {
7316 const AutoType *T = TL.getTypePtr();
7317 QualType OldDeduced = T->getDeducedType();
7318 QualType NewDeduced;
7319 if (!OldDeduced.isNull()) {
7320 NewDeduced = getDerived().TransformType(OldDeduced);
7321 if (NewDeduced.isNull())
7322 return QualType();
7323 }
7324
7325 ConceptDecl *NewCD = nullptr;
7326 TemplateArgumentListInfo NewTemplateArgs;
7327 NestedNameSpecifierLoc NewNestedNameSpec;
7328 if (T->isConstrained()) {
7329 assert(TL.getConceptReference());
7330 NewCD = cast_or_null<ConceptDecl>(getDerived().TransformDecl(
7331 TL.getConceptNameLoc(), T->getTypeConstraintConcept()));
7332
7333 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7334 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7335 typedef TemplateArgumentLocContainerIterator<AutoTypeLoc> ArgIterator;
7336 if (getDerived().TransformTemplateArguments(
7337 ArgIterator(TL, 0), ArgIterator(TL, TL.getNumArgs()),
7338 NewTemplateArgs))
7339 return QualType();
7340
7341 if (TL.getNestedNameSpecifierLoc()) {
7342 NewNestedNameSpec
7343 = getDerived().TransformNestedNameSpecifierLoc(
7344 TL.getNestedNameSpecifierLoc());
7345 if (!NewNestedNameSpec)
7346 return QualType();
7347 }
7348 }
7349
7350 QualType Result = TL.getType();
7351 if (getDerived().AlwaysRebuild() || NewDeduced != OldDeduced ||
7352 T->isDependentType() || T->isConstrained()) {
7353 // FIXME: Maybe don't rebuild if all template arguments are the same.
7354 llvm::SmallVector<TemplateArgument, 4> NewArgList;
7355 NewArgList.reserve(N: NewTemplateArgs.size());
7356 for (const auto &ArgLoc : NewTemplateArgs.arguments())
7357 NewArgList.push_back(ArgLoc.getArgument());
7358 Result = getDerived().RebuildAutoType(NewDeduced, T->getKeyword(), NewCD,
7359 NewArgList);
7360 if (Result.isNull())
7361 return QualType();
7362 }
7363
7364 AutoTypeLoc NewTL = TLB.push<AutoTypeLoc>(Result);
7365 NewTL.setNameLoc(TL.getNameLoc());
7366 NewTL.setRParenLoc(TL.getRParenLoc());
7367 NewTL.setConceptReference(nullptr);
7368
7369 if (T->isConstrained()) {
7370 DeclarationNameInfo DNI = DeclarationNameInfo(
7371 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
7372 TL.getConceptNameLoc(),
7373 TL.getTypePtr()->getTypeConstraintConcept()->getDeclName());
7374 auto *CR = ConceptReference::Create(
7375 C: SemaRef.Context, NNS: NewNestedNameSpec, TemplateKWLoc: TL.getTemplateKWLoc(), ConceptNameInfo: DNI,
7376 FoundDecl: TL.getFoundDecl(), NamedConcept: TL.getTypePtr()->getTypeConstraintConcept(),
7377 ArgsAsWritten: ASTTemplateArgumentListInfo::Create(C: SemaRef.Context, List: NewTemplateArgs));
7378 NewTL.setConceptReference(CR);
7379 }
7380
7381 return Result;
7382}
7383
7384template <typename Derived>
7385QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
7386 TypeLocBuilder &TLB,
7387 TemplateSpecializationTypeLoc TL,
7388 TemplateName Template) {
7389 TemplateArgumentListInfo NewTemplateArgs;
7390 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7391 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7392 typedef TemplateArgumentLocContainerIterator<TemplateSpecializationTypeLoc>
7393 ArgIterator;
7394 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7395 ArgIterator(TL, TL.getNumArgs()),
7396 NewTemplateArgs))
7397 return QualType();
7398
7399 // This needs to be rebuilt if either the arguments changed, or if the
7400 // original template changed. If the template changed, and even if the
7401 // arguments didn't change, these arguments might not correspond to their
7402 // respective parameters, therefore needing conversions.
7403 QualType Result =
7404 getDerived().RebuildTemplateSpecializationType(Template,
7405 TL.getTemplateNameLoc(),
7406 NewTemplateArgs);
7407
7408 if (!Result.isNull()) {
7409 // Specializations of template template parameters are represented as
7410 // TemplateSpecializationTypes, and substitution of type alias templates
7411 // within a dependent context can transform them into
7412 // DependentTemplateSpecializationTypes.
7413 if (isa<DependentTemplateSpecializationType>(Result)) {
7414 DependentTemplateSpecializationTypeLoc NewTL
7415 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7416 NewTL.setElaboratedKeywordLoc(SourceLocation());
7417 NewTL.setQualifierLoc(NestedNameSpecifierLoc());
7418 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7419 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7420 NewTL.setLAngleLoc(TL.getLAngleLoc());
7421 NewTL.setRAngleLoc(TL.getRAngleLoc());
7422 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7423 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7424 return Result;
7425 }
7426
7427 TemplateSpecializationTypeLoc NewTL
7428 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7429 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7430 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7431 NewTL.setLAngleLoc(TL.getLAngleLoc());
7432 NewTL.setRAngleLoc(TL.getRAngleLoc());
7433 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7434 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7435 }
7436
7437 return Result;
7438}
7439
7440template <typename Derived>
7441QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7442 TypeLocBuilder &TLB,
7443 DependentTemplateSpecializationTypeLoc TL,
7444 TemplateName Template,
7445 CXXScopeSpec &SS) {
7446 TemplateArgumentListInfo NewTemplateArgs;
7447 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7448 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7449 typedef TemplateArgumentLocContainerIterator<
7450 DependentTemplateSpecializationTypeLoc> ArgIterator;
7451 if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
7452 ArgIterator(TL, TL.getNumArgs()),
7453 NewTemplateArgs))
7454 return QualType();
7455
7456 // FIXME: maybe don't rebuild if all the template arguments are the same.
7457
7458 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
7459 assert(DTN->getQualifier() == SS.getScopeRep());
7460 QualType Result = getSema().Context.getDependentTemplateSpecializationType(
7461 TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments());
7462
7463 DependentTemplateSpecializationTypeLoc NewTL
7464 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7465 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7466 NewTL.setQualifierLoc(SS.getWithLocInContext(Context&: SemaRef.Context));
7467 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7468 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7469 NewTL.setLAngleLoc(TL.getLAngleLoc());
7470 NewTL.setRAngleLoc(TL.getRAngleLoc());
7471 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7472 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7473 return Result;
7474 }
7475
7476 QualType Result
7477 = getDerived().RebuildTemplateSpecializationType(Template,
7478 TL.getTemplateNameLoc(),
7479 NewTemplateArgs);
7480
7481 if (!Result.isNull()) {
7482 /// FIXME: Wrap this in an elaborated-type-specifier?
7483 TemplateSpecializationTypeLoc NewTL
7484 = TLB.push<TemplateSpecializationTypeLoc>(Result);
7485 NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7486 NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7487 NewTL.setLAngleLoc(TL.getLAngleLoc());
7488 NewTL.setRAngleLoc(TL.getRAngleLoc());
7489 for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
7490 NewTL.setArgLocInfo(i, AI: NewTemplateArgs[i].getLocInfo());
7491 }
7492
7493 return Result;
7494}
7495
7496template<typename Derived>
7497QualType
7498TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
7499 ElaboratedTypeLoc TL) {
7500 const ElaboratedType *T = TL.getTypePtr();
7501
7502 NestedNameSpecifierLoc QualifierLoc;
7503 // NOTE: the qualifier in an ElaboratedType is optional.
7504 if (TL.getQualifierLoc()) {
7505 QualifierLoc
7506 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7507 if (!QualifierLoc)
7508 return QualType();
7509 }
7510
7511 QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
7512 if (NamedT.isNull())
7513 return QualType();
7514
7515 // C++0x [dcl.type.elab]p2:
7516 // If the identifier resolves to a typedef-name or the simple-template-id
7517 // resolves to an alias template specialization, the
7518 // elaborated-type-specifier is ill-formed.
7519 if (T->getKeyword() != ElaboratedTypeKeyword::None &&
7520 T->getKeyword() != ElaboratedTypeKeyword::Typename) {
7521 if (const TemplateSpecializationType *TST =
7522 NamedT->getAs<TemplateSpecializationType>()) {
7523 TemplateName Template = TST->getTemplateName();
7524 if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
7525 Template.getAsTemplateDecl())) {
7526 SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
7527 diag::err_tag_reference_non_tag)
7528 << TAT << NonTagKind::TypeAliasTemplate
7529 << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
7530 SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
7531 }
7532 }
7533 }
7534
7535 QualType Result = TL.getType();
7536 if (getDerived().AlwaysRebuild() ||
7537 QualifierLoc != TL.getQualifierLoc() ||
7538 NamedT != T->getNamedType()) {
7539 Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
7540 T->getKeyword(),
7541 QualifierLoc, NamedT);
7542 if (Result.isNull())
7543 return QualType();
7544 }
7545
7546 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7547 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7548 NewTL.setQualifierLoc(QualifierLoc);
7549 return Result;
7550}
7551
7552template <typename Derived>
7553QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
7554 AttributedTypeLoc TL) {
7555 const AttributedType *oldType = TL.getTypePtr();
7556 QualType modifiedType = getDerived().TransformType(TLB, TL.getModifiedLoc());
7557 if (modifiedType.isNull())
7558 return QualType();
7559
7560 // oldAttr can be null if we started with a QualType rather than a TypeLoc.
7561 const Attr *oldAttr = TL.getAttr();
7562 const Attr *newAttr = oldAttr ? getDerived().TransformAttr(oldAttr) : nullptr;
7563 if (oldAttr && !newAttr)
7564 return QualType();
7565
7566 QualType result = TL.getType();
7567
7568 // FIXME: dependent operand expressions?
7569 if (getDerived().AlwaysRebuild() ||
7570 modifiedType != oldType->getModifiedType()) {
7571 // If the equivalent type is equal to the modified type, we don't want to
7572 // transform it as well because:
7573 //
7574 // 1. The transformation would yield the same result and is therefore
7575 // superfluous, and
7576 //
7577 // 2. Transforming the same type twice can cause problems, e.g. if it
7578 // is a FunctionProtoType, we may end up instantiating the function
7579 // parameters twice, which causes an assertion since the parameters
7580 // are already bound to their counterparts in the template for this
7581 // instantiation.
7582 //
7583 QualType equivalentType = modifiedType;
7584 if (TL.getModifiedLoc().getType() != TL.getEquivalentTypeLoc().getType()) {
7585 TypeLocBuilder AuxiliaryTLB;
7586 AuxiliaryTLB.reserve(Requested: TL.getFullDataSize());
7587 equivalentType =
7588 getDerived().TransformType(AuxiliaryTLB, TL.getEquivalentTypeLoc());
7589 if (equivalentType.isNull())
7590 return QualType();
7591 }
7592
7593 // Check whether we can add nullability; it is only represented as
7594 // type sugar, and therefore cannot be diagnosed in any other way.
7595 if (auto nullability = oldType->getImmediateNullability()) {
7596 if (!modifiedType->canHaveNullability()) {
7597 SemaRef.Diag((TL.getAttr() ? TL.getAttr()->getLocation()
7598 : TL.getModifiedLoc().getBeginLoc()),
7599 diag::err_nullability_nonpointer)
7600 << DiagNullabilityKind(*nullability, false) << modifiedType;
7601 return QualType();
7602 }
7603 }
7604
7605 result = SemaRef.Context.getAttributedType(attrKind: TL.getAttrKind(),
7606 modifiedType,
7607 equivalentType,
7608 attr: TL.getAttr());
7609 }
7610
7611 AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
7612 newTL.setAttr(newAttr);
7613 return result;
7614}
7615
7616template <typename Derived>
7617QualType TreeTransform<Derived>::TransformCountAttributedType(
7618 TypeLocBuilder &TLB, CountAttributedTypeLoc TL) {
7619 const CountAttributedType *OldTy = TL.getTypePtr();
7620 QualType InnerTy = getDerived().TransformType(TLB, TL.getInnerLoc());
7621 if (InnerTy.isNull())
7622 return QualType();
7623
7624 Expr *OldCount = TL.getCountExpr();
7625 Expr *NewCount = nullptr;
7626 if (OldCount) {
7627 ExprResult CountResult = getDerived().TransformExpr(OldCount);
7628 if (CountResult.isInvalid())
7629 return QualType();
7630 NewCount = CountResult.get();
7631 }
7632
7633 QualType Result = TL.getType();
7634 if (getDerived().AlwaysRebuild() || InnerTy != OldTy->desugar() ||
7635 OldCount != NewCount) {
7636 // Currently, CountAttributedType can only wrap incomplete array types.
7637 Result = SemaRef.BuildCountAttributedArrayOrPointerType(
7638 WrappedTy: InnerTy, CountExpr: NewCount, CountInBytes: OldTy->isCountInBytes(), OrNull: OldTy->isOrNull());
7639 }
7640
7641 TLB.push<CountAttributedTypeLoc>(Result);
7642 return Result;
7643}
7644
7645template <typename Derived>
7646QualType TreeTransform<Derived>::TransformBTFTagAttributedType(
7647 TypeLocBuilder &TLB, BTFTagAttributedTypeLoc TL) {
7648 // The BTFTagAttributedType is available for C only.
7649 llvm_unreachable("Unexpected TreeTransform for BTFTagAttributedType");
7650}
7651
7652template <typename Derived>
7653QualType TreeTransform<Derived>::TransformHLSLAttributedResourceType(
7654 TypeLocBuilder &TLB, HLSLAttributedResourceTypeLoc TL) {
7655
7656 const HLSLAttributedResourceType *oldType = TL.getTypePtr();
7657
7658 QualType WrappedTy = getDerived().TransformType(TLB, TL.getWrappedLoc());
7659 if (WrappedTy.isNull())
7660 return QualType();
7661
7662 QualType ContainedTy = QualType();
7663 QualType OldContainedTy = oldType->getContainedType();
7664 if (!OldContainedTy.isNull()) {
7665 TypeSourceInfo *oldContainedTSI = TL.getContainedTypeSourceInfo();
7666 if (!oldContainedTSI)
7667 oldContainedTSI = getSema().getASTContext().getTrivialTypeSourceInfo(
7668 OldContainedTy, SourceLocation());
7669 TypeSourceInfo *ContainedTSI = getDerived().TransformType(oldContainedTSI);
7670 if (!ContainedTSI)
7671 return QualType();
7672 ContainedTy = ContainedTSI->getType();
7673 }
7674
7675 QualType Result = TL.getType();
7676 if (getDerived().AlwaysRebuild() || WrappedTy != oldType->getWrappedType() ||
7677 ContainedTy != oldType->getContainedType()) {
7678 Result = SemaRef.Context.getHLSLAttributedResourceType(
7679 Wrapped: WrappedTy, Contained: ContainedTy, Attrs: oldType->getAttrs());
7680 }
7681
7682 TLB.push<HLSLAttributedResourceTypeLoc>(Result);
7683 return Result;
7684}
7685
7686template <typename Derived>
7687QualType TreeTransform<Derived>::TransformHLSLInlineSpirvType(
7688 TypeLocBuilder &TLB, HLSLInlineSpirvTypeLoc TL) {
7689 // No transformations needed.
7690 return TL.getType();
7691}
7692
7693template<typename Derived>
7694QualType
7695TreeTransform<Derived>::TransformParenType(TypeLocBuilder &TLB,
7696 ParenTypeLoc TL) {
7697 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7698 if (Inner.isNull())
7699 return QualType();
7700
7701 QualType Result = TL.getType();
7702 if (getDerived().AlwaysRebuild() ||
7703 Inner != TL.getInnerLoc().getType()) {
7704 Result = getDerived().RebuildParenType(Inner);
7705 if (Result.isNull())
7706 return QualType();
7707 }
7708
7709 ParenTypeLoc NewTL = TLB.push<ParenTypeLoc>(Result);
7710 NewTL.setLParenLoc(TL.getLParenLoc());
7711 NewTL.setRParenLoc(TL.getRParenLoc());
7712 return Result;
7713}
7714
7715template <typename Derived>
7716QualType
7717TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder &TLB,
7718 MacroQualifiedTypeLoc TL) {
7719 QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
7720 if (Inner.isNull())
7721 return QualType();
7722
7723 QualType Result = TL.getType();
7724 if (getDerived().AlwaysRebuild() || Inner != TL.getInnerLoc().getType()) {
7725 Result =
7726 getDerived().RebuildMacroQualifiedType(Inner, TL.getMacroIdentifier());
7727 if (Result.isNull())
7728 return QualType();
7729 }
7730
7731 MacroQualifiedTypeLoc NewTL = TLB.push<MacroQualifiedTypeLoc>(Result);
7732 NewTL.setExpansionLoc(TL.getExpansionLoc());
7733 return Result;
7734}
7735
7736template<typename Derived>
7737QualType TreeTransform<Derived>::TransformDependentNameType(
7738 TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
7739 return TransformDependentNameType(TLB, TL, DeducibleTSTContext: false);
7740}
7741
7742template<typename Derived>
7743QualType TreeTransform<Derived>::TransformDependentNameType(
7744 TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
7745 const DependentNameType *T = TL.getTypePtr();
7746
7747 NestedNameSpecifierLoc QualifierLoc
7748 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7749 if (!QualifierLoc)
7750 return QualType();
7751
7752 QualType Result
7753 = getDerived().RebuildDependentNameType(T->getKeyword(),
7754 TL.getElaboratedKeywordLoc(),
7755 QualifierLoc,
7756 T->getIdentifier(),
7757 TL.getNameLoc(),
7758 DeducedTSTContext);
7759 if (Result.isNull())
7760 return QualType();
7761
7762 if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
7763 QualType NamedT = ElabT->getNamedType();
7764 TLB.pushTypeSpec(T: NamedT).setNameLoc(TL.getNameLoc());
7765
7766 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7767 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7768 NewTL.setQualifierLoc(QualifierLoc);
7769 } else {
7770 DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
7771 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7772 NewTL.setQualifierLoc(QualifierLoc);
7773 NewTL.setNameLoc(TL.getNameLoc());
7774 }
7775 return Result;
7776}
7777
7778template<typename Derived>
7779QualType TreeTransform<Derived>::
7780 TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
7781 DependentTemplateSpecializationTypeLoc TL) {
7782 NestedNameSpecifierLoc QualifierLoc;
7783 if (TL.getQualifierLoc()) {
7784 QualifierLoc
7785 = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
7786 if (!QualifierLoc)
7787 return QualType();
7788 }
7789
7790 CXXScopeSpec SS;
7791 SS.Adopt(Other: QualifierLoc);
7792 return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS);
7793}
7794
7795template <typename Derived>
7796QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
7797 TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
7798 CXXScopeSpec &SS) {
7799 const DependentTemplateSpecializationType *T = TL.getTypePtr();
7800
7801 TemplateArgumentListInfo NewTemplateArgs;
7802 NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
7803 NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
7804
7805 auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator<
7806 DependentTemplateSpecializationTypeLoc>>({TL, 0}, {TL, TL.getNumArgs()});
7807
7808 if (getDerived().TransformTemplateArguments(ArgsRange.begin(),
7809 ArgsRange.end(), NewTemplateArgs))
7810 return QualType();
7811 bool TemplateArgumentsChanged = !llvm::equal(
7812 ArgsRange, NewTemplateArgs.arguments(),
7813 [](const TemplateArgumentLoc &A, const TemplateArgumentLoc &B) {
7814 return A.getArgument().structurallyEquals(Other: B.getArgument());
7815 });
7816
7817 const DependentTemplateStorage &DTN = T->getDependentTemplateName();
7818
7819 QualType Result = TL.getType();
7820 if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() ||
7821 TemplateArgumentsChanged) {
7822 TemplateName Name = getDerived().RebuildTemplateName(
7823 SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(),
7824 /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
7825 /*AllowInjectedClassName=*/false);
7826 if (Name.isNull())
7827 return QualType();
7828 Result = getDerived().RebuildDependentTemplateSpecializationType(
7829 T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name,
7830 TL.getTemplateNameLoc(), NewTemplateArgs,
7831 /*AllowInjectedClassName=*/false);
7832 if (Result.isNull())
7833 return QualType();
7834 }
7835
7836 NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context&: SemaRef.Context);
7837 if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
7838 QualType NamedT = ElabT->getNamedType();
7839
7840 // Copy information relevant to the template specialization.
7841 TemplateSpecializationTypeLoc NamedTL
7842 = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
7843 NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7844 NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7845 NamedTL.setLAngleLoc(TL.getLAngleLoc());
7846 NamedTL.setRAngleLoc(TL.getRAngleLoc());
7847 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7848 NamedTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7849
7850 // Copy information relevant to the elaborated type.
7851 ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
7852 NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7853 NewTL.setQualifierLoc(QualifierLoc);
7854 } else {
7855 assert(isa<DependentTemplateSpecializationType>(Result));
7856 DependentTemplateSpecializationTypeLoc SpecTL
7857 = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
7858 SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
7859 SpecTL.setQualifierLoc(QualifierLoc);
7860 SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
7861 SpecTL.setTemplateNameLoc(TL.getTemplateNameLoc());
7862 SpecTL.setLAngleLoc(TL.getLAngleLoc());
7863 SpecTL.setRAngleLoc(TL.getRAngleLoc());
7864 for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
7865 SpecTL.setArgLocInfo(i: I, AI: NewTemplateArgs[I].getLocInfo());
7866 }
7867 return Result;
7868}
7869
7870template<typename Derived>
7871QualType TreeTransform<Derived>::TransformPackExpansionType(TypeLocBuilder &TLB,
7872 PackExpansionTypeLoc TL) {
7873 QualType Pattern
7874 = getDerived().TransformType(TLB, TL.getPatternLoc());
7875 if (Pattern.isNull())
7876 return QualType();
7877
7878 QualType Result = TL.getType();
7879 if (getDerived().AlwaysRebuild() ||
7880 Pattern != TL.getPatternLoc().getType()) {
7881 Result = getDerived().RebuildPackExpansionType(Pattern,
7882 TL.getPatternLoc().getSourceRange(),
7883 TL.getEllipsisLoc(),
7884 TL.getTypePtr()->getNumExpansions());
7885 if (Result.isNull())
7886 return QualType();
7887 }
7888
7889 PackExpansionTypeLoc NewT = TLB.push<PackExpansionTypeLoc>(Result);
7890 NewT.setEllipsisLoc(TL.getEllipsisLoc());
7891 return Result;
7892}
7893
7894template<typename Derived>
7895QualType
7896TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
7897 ObjCInterfaceTypeLoc TL) {
7898 // ObjCInterfaceType is never dependent.
7899 TLB.pushFullCopy(TL);
7900 return TL.getType();
7901}
7902
7903template<typename Derived>
7904QualType
7905TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
7906 ObjCTypeParamTypeLoc TL) {
7907 const ObjCTypeParamType *T = TL.getTypePtr();
7908 ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
7909 getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
7910 if (!OTP)
7911 return QualType();
7912
7913 QualType Result = TL.getType();
7914 if (getDerived().AlwaysRebuild() ||
7915 OTP != T->getDecl()) {
7916 Result = getDerived().RebuildObjCTypeParamType(
7917 OTP, TL.getProtocolLAngleLoc(),
7918 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
7919 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
7920 if (Result.isNull())
7921 return QualType();
7922 }
7923
7924 ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
7925 if (TL.getNumProtocols()) {
7926 NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
7927 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
7928 NewTL.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
7929 NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
7930 }
7931 return Result;
7932}
7933
7934template<typename Derived>
7935QualType
7936TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
7937 ObjCObjectTypeLoc TL) {
7938 // Transform base type.
7939 QualType BaseType = getDerived().TransformType(TLB, TL.getBaseLoc());
7940 if (BaseType.isNull())
7941 return QualType();
7942
7943 bool AnyChanged = BaseType != TL.getBaseLoc().getType();
7944
7945 // Transform type arguments.
7946 SmallVector<TypeSourceInfo *, 4> NewTypeArgInfos;
7947 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i) {
7948 TypeSourceInfo *TypeArgInfo = TL.getTypeArgTInfo(i);
7949 TypeLoc TypeArgLoc = TypeArgInfo->getTypeLoc();
7950 QualType TypeArg = TypeArgInfo->getType();
7951 if (auto PackExpansionLoc = TypeArgLoc.getAs<PackExpansionTypeLoc>()) {
7952 AnyChanged = true;
7953
7954 // We have a pack expansion. Instantiate it.
7955 const auto *PackExpansion = PackExpansionLoc.getType()
7956 ->castAs<PackExpansionType>();
7957 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
7958 SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(),
7959 Unexpanded);
7960 assert(!Unexpanded.empty() && "Pack expansion without parameter packs?");
7961
7962 // Determine whether the set of unexpanded parameter packs can
7963 // and should be expanded.
7964 TypeLoc PatternLoc = PackExpansionLoc.getPatternLoc();
7965 bool Expand = false;
7966 bool RetainExpansion = false;
7967 UnsignedOrNone NumExpansions = PackExpansion->getNumExpansions();
7968 if (getDerived().TryExpandParameterPacks(
7969 PackExpansionLoc.getEllipsisLoc(), PatternLoc.getSourceRange(),
7970 Unexpanded, Expand, RetainExpansion, NumExpansions))
7971 return QualType();
7972
7973 if (!Expand) {
7974 // We can't expand this pack expansion into separate arguments yet;
7975 // just substitute into the pattern and create a new pack expansion
7976 // type.
7977 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
7978
7979 TypeLocBuilder TypeArgBuilder;
7980 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
7981 QualType NewPatternType = getDerived().TransformType(TypeArgBuilder,
7982 PatternLoc);
7983 if (NewPatternType.isNull())
7984 return QualType();
7985
7986 QualType NewExpansionType = SemaRef.Context.getPackExpansionType(
7987 Pattern: NewPatternType, NumExpansions);
7988 auto NewExpansionLoc = TLB.push<PackExpansionTypeLoc>(NewExpansionType);
7989 NewExpansionLoc.setEllipsisLoc(PackExpansionLoc.getEllipsisLoc());
7990 NewTypeArgInfos.push_back(
7991 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewExpansionType));
7992 continue;
7993 }
7994
7995 // Substitute into the pack expansion pattern for each slice of the
7996 // pack.
7997 for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) {
7998 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), ArgIdx);
7999
8000 TypeLocBuilder TypeArgBuilder;
8001 TypeArgBuilder.reserve(Requested: PatternLoc.getFullDataSize());
8002
8003 QualType NewTypeArg = getDerived().TransformType(TypeArgBuilder,
8004 PatternLoc);
8005 if (NewTypeArg.isNull())
8006 return QualType();
8007
8008 NewTypeArgInfos.push_back(
8009 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8010 }
8011
8012 continue;
8013 }
8014
8015 TypeLocBuilder TypeArgBuilder;
8016 TypeArgBuilder.reserve(Requested: TypeArgLoc.getFullDataSize());
8017 QualType NewTypeArg =
8018 getDerived().TransformType(TypeArgBuilder, TypeArgLoc);
8019 if (NewTypeArg.isNull())
8020 return QualType();
8021
8022 // If nothing changed, just keep the old TypeSourceInfo.
8023 if (NewTypeArg == TypeArg) {
8024 NewTypeArgInfos.push_back(TypeArgInfo);
8025 continue;
8026 }
8027
8028 NewTypeArgInfos.push_back(
8029 TypeArgBuilder.getTypeSourceInfo(Context&: SemaRef.Context, T: NewTypeArg));
8030 AnyChanged = true;
8031 }
8032
8033 QualType Result = TL.getType();
8034 if (getDerived().AlwaysRebuild() || AnyChanged) {
8035 // Rebuild the type.
8036 Result = getDerived().RebuildObjCObjectType(
8037 BaseType, TL.getBeginLoc(), TL.getTypeArgsLAngleLoc(), NewTypeArgInfos,
8038 TL.getTypeArgsRAngleLoc(), TL.getProtocolLAngleLoc(),
8039 llvm::ArrayRef(TL.getTypePtr()->qual_begin(), TL.getNumProtocols()),
8040 TL.getProtocolLocs(), TL.getProtocolRAngleLoc());
8041
8042 if (Result.isNull())
8043 return QualType();
8044 }
8045
8046 ObjCObjectTypeLoc NewT = TLB.push<ObjCObjectTypeLoc>(Result);
8047 NewT.setHasBaseTypeAsWritten(true);
8048 NewT.setTypeArgsLAngleLoc(TL.getTypeArgsLAngleLoc());
8049 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
8050 NewT.setTypeArgTInfo(i, TInfo: NewTypeArgInfos[i]);
8051 NewT.setTypeArgsRAngleLoc(TL.getTypeArgsRAngleLoc());
8052 NewT.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
8053 for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
8054 NewT.setProtocolLoc(i, Loc: TL.getProtocolLoc(i));
8055 NewT.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
8056 return Result;
8057}
8058
8059template<typename Derived>
8060QualType
8061TreeTransform<Derived>::TransformObjCObjectPointerType(TypeLocBuilder &TLB,
8062 ObjCObjectPointerTypeLoc TL) {
8063 QualType PointeeType = getDerived().TransformType(TLB, TL.getPointeeLoc());
8064 if (PointeeType.isNull())
8065 return QualType();
8066
8067 QualType Result = TL.getType();
8068 if (getDerived().AlwaysRebuild() ||
8069 PointeeType != TL.getPointeeLoc().getType()) {
8070 Result = getDerived().RebuildObjCObjectPointerType(PointeeType,
8071 TL.getStarLoc());
8072 if (Result.isNull())
8073 return QualType();
8074 }
8075
8076 ObjCObjectPointerTypeLoc NewT = TLB.push<ObjCObjectPointerTypeLoc>(Result);
8077 NewT.setStarLoc(TL.getStarLoc());
8078 return Result;
8079}
8080
8081//===----------------------------------------------------------------------===//
8082// Statement transformation
8083//===----------------------------------------------------------------------===//
8084template<typename Derived>
8085StmtResult
8086TreeTransform<Derived>::TransformNullStmt(NullStmt *S) {
8087 return S;
8088}
8089
8090template<typename Derived>
8091StmtResult
8092TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S) {
8093 return getDerived().TransformCompoundStmt(S, false);
8094}
8095
8096template<typename Derived>
8097StmtResult
8098TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S,
8099 bool IsStmtExpr) {
8100 Sema::CompoundScopeRAII CompoundScope(getSema());
8101 Sema::FPFeaturesStateRAII FPSave(getSema());
8102 if (S->hasStoredFPFeatures())
8103 getSema().resetFPOptions(
8104 S->getStoredFPFeatures().applyOverrides(getSema().getLangOpts()));
8105
8106 const Stmt *ExprResult = S->getStmtExprResult();
8107 bool SubStmtInvalid = false;
8108 bool SubStmtChanged = false;
8109 SmallVector<Stmt*, 8> Statements;
8110 for (auto *B : S->body()) {
8111 StmtResult Result = getDerived().TransformStmt(
8112 B, IsStmtExpr && B == ExprResult ? StmtDiscardKind::StmtExprResult
8113 : StmtDiscardKind::Discarded);
8114
8115 if (Result.isInvalid()) {
8116 // Immediately fail if this was a DeclStmt, since it's very
8117 // likely that this will cause problems for future statements.
8118 if (isa<DeclStmt>(B))
8119 return StmtError();
8120
8121 // Otherwise, just keep processing substatements and fail later.
8122 SubStmtInvalid = true;
8123 continue;
8124 }
8125
8126 SubStmtChanged = SubStmtChanged || Result.get() != B;
8127 Statements.push_back(Result.getAs<Stmt>());
8128 }
8129
8130 if (SubStmtInvalid)
8131 return StmtError();
8132
8133 if (!getDerived().AlwaysRebuild() &&
8134 !SubStmtChanged)
8135 return S;
8136
8137 return getDerived().RebuildCompoundStmt(S->getLBracLoc(),
8138 Statements,
8139 S->getRBracLoc(),
8140 IsStmtExpr);
8141}
8142
8143template<typename Derived>
8144StmtResult
8145TreeTransform<Derived>::TransformCaseStmt(CaseStmt *S) {
8146 ExprResult LHS, RHS;
8147 {
8148 EnterExpressionEvaluationContext Unevaluated(
8149 SemaRef, Sema::ExpressionEvaluationContext::ConstantEvaluated);
8150
8151 // Transform the left-hand case value.
8152 LHS = getDerived().TransformExpr(S->getLHS());
8153 LHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: LHS);
8154 if (LHS.isInvalid())
8155 return StmtError();
8156
8157 // Transform the right-hand case value (for the GNU case-range extension).
8158 RHS = getDerived().TransformExpr(S->getRHS());
8159 RHS = SemaRef.ActOnCaseExpr(CaseLoc: S->getCaseLoc(), Val: RHS);
8160 if (RHS.isInvalid())
8161 return StmtError();
8162 }
8163
8164 // Build the case statement.
8165 // Case statements are always rebuilt so that they will attached to their
8166 // transformed switch statement.
8167 StmtResult Case = getDerived().RebuildCaseStmt(S->getCaseLoc(),
8168 LHS.get(),
8169 S->getEllipsisLoc(),
8170 RHS.get(),
8171 S->getColonLoc());
8172 if (Case.isInvalid())
8173 return StmtError();
8174
8175 // Transform the statement following the case
8176 StmtResult SubStmt =
8177 getDerived().TransformStmt(S->getSubStmt());
8178 if (SubStmt.isInvalid())
8179 return StmtError();
8180
8181 // Attach the body to the case statement
8182 return getDerived().RebuildCaseStmtBody(Case.get(), SubStmt.get());
8183}
8184
8185template <typename Derived>
8186StmtResult TreeTransform<Derived>::TransformDefaultStmt(DefaultStmt *S) {
8187 // Transform the statement following the default case
8188 StmtResult SubStmt =
8189 getDerived().TransformStmt(S->getSubStmt());
8190 if (SubStmt.isInvalid())
8191 return StmtError();
8192
8193 // Default statements are always rebuilt
8194 return getDerived().RebuildDefaultStmt(S->getDefaultLoc(), S->getColonLoc(),
8195 SubStmt.get());
8196}
8197
8198template<typename Derived>
8199StmtResult
8200TreeTransform<Derived>::TransformLabelStmt(LabelStmt *S, StmtDiscardKind SDK) {
8201 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8202 if (SubStmt.isInvalid())
8203 return StmtError();
8204
8205 Decl *LD = getDerived().TransformDecl(S->getDecl()->getLocation(),
8206 S->getDecl());
8207 if (!LD)
8208 return StmtError();
8209
8210 // If we're transforming "in-place" (we're not creating new local
8211 // declarations), assume we're replacing the old label statement
8212 // and clear out the reference to it.
8213 if (LD == S->getDecl())
8214 S->getDecl()->setStmt(nullptr);
8215
8216 // FIXME: Pass the real colon location in.
8217 return getDerived().RebuildLabelStmt(S->getIdentLoc(),
8218 cast<LabelDecl>(LD), SourceLocation(),
8219 SubStmt.get());
8220}
8221
8222template <typename Derived>
8223const Attr *TreeTransform<Derived>::TransformAttr(const Attr *R) {
8224 if (!R)
8225 return R;
8226
8227 switch (R->getKind()) {
8228// Transform attributes by calling TransformXXXAttr.
8229#define ATTR(X) \
8230 case attr::X: \
8231 return getDerived().Transform##X##Attr(cast<X##Attr>(R));
8232#include "clang/Basic/AttrList.inc"
8233 }
8234 return R;
8235}
8236
8237template <typename Derived>
8238const Attr *TreeTransform<Derived>::TransformStmtAttr(const Stmt *OrigS,
8239 const Stmt *InstS,
8240 const Attr *R) {
8241 if (!R)
8242 return R;
8243
8244 switch (R->getKind()) {
8245// Transform attributes by calling TransformStmtXXXAttr.
8246#define ATTR(X) \
8247 case attr::X: \
8248 return getDerived().TransformStmt##X##Attr(OrigS, InstS, cast<X##Attr>(R));
8249#include "clang/Basic/AttrList.inc"
8250 }
8251 return TransformAttr(R);
8252}
8253
8254template <typename Derived>
8255StmtResult
8256TreeTransform<Derived>::TransformAttributedStmt(AttributedStmt *S,
8257 StmtDiscardKind SDK) {
8258 StmtResult SubStmt = getDerived().TransformStmt(S->getSubStmt(), SDK);
8259 if (SubStmt.isInvalid())
8260 return StmtError();
8261
8262 bool AttrsChanged = false;
8263 SmallVector<const Attr *, 1> Attrs;
8264
8265 // Visit attributes and keep track if any are transformed.
8266 for (const auto *I : S->getAttrs()) {
8267 const Attr *R =
8268 getDerived().TransformStmtAttr(S->getSubStmt(), SubStmt.get(), I);
8269 AttrsChanged |= (I != R);
8270 if (R)
8271 Attrs.push_back(R);
8272 }
8273
8274 if (SubStmt.get() == S->getSubStmt() && !AttrsChanged)
8275 return S;
8276
8277 // If transforming the attributes failed for all of the attributes in the
8278 // statement, don't make an AttributedStmt without attributes.
8279 if (Attrs.empty())
8280 return SubStmt;
8281
8282 return getDerived().RebuildAttributedStmt(S->getAttrLoc(), Attrs,
8283 SubStmt.get());
8284}
8285
8286template<typename Derived>
8287StmtResult
8288TreeTransform<Derived>::TransformIfStmt(IfStmt *S) {
8289 // Transform the initialization statement
8290 StmtResult Init = getDerived().TransformStmt(S->getInit());
8291 if (Init.isInvalid())
8292 return StmtError();
8293
8294 Sema::ConditionResult Cond;
8295 if (!S->isConsteval()) {
8296 // Transform the condition
8297 Cond = getDerived().TransformCondition(
8298 S->getIfLoc(), S->getConditionVariable(), S->getCond(),
8299 S->isConstexpr() ? Sema::ConditionKind::ConstexprIf
8300 : Sema::ConditionKind::Boolean);
8301 if (Cond.isInvalid())
8302 return StmtError();
8303 }
8304
8305 // If this is a constexpr if, determine which arm we should instantiate.
8306 std::optional<bool> ConstexprConditionValue;
8307 if (S->isConstexpr())
8308 ConstexprConditionValue = Cond.getKnownValue();
8309
8310 // Transform the "then" branch.
8311 StmtResult Then;
8312 if (!ConstexprConditionValue || *ConstexprConditionValue) {
8313 EnterExpressionEvaluationContext Ctx(
8314 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8315 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8316 S->isNonNegatedConsteval());
8317
8318 Then = getDerived().TransformStmt(S->getThen());
8319 if (Then.isInvalid())
8320 return StmtError();
8321 } else {
8322 // Discarded branch is replaced with empty CompoundStmt so we can keep
8323 // proper source location for start and end of original branch, so
8324 // subsequent transformations like CoverageMapping work properly
8325 Then = new (getSema().Context)
8326 CompoundStmt(S->getThen()->getBeginLoc(), S->getThen()->getEndLoc());
8327 }
8328
8329 // Transform the "else" branch.
8330 StmtResult Else;
8331 if (!ConstexprConditionValue || !*ConstexprConditionValue) {
8332 EnterExpressionEvaluationContext Ctx(
8333 getSema(), Sema::ExpressionEvaluationContext::ImmediateFunctionContext,
8334 nullptr, Sema::ExpressionEvaluationContextRecord::EK_Other,
8335 S->isNegatedConsteval());
8336
8337 Else = getDerived().TransformStmt(S->getElse());
8338 if (Else.isInvalid())
8339 return StmtError();
8340 } else if (S->getElse() && ConstexprConditionValue &&
8341 *ConstexprConditionValue) {
8342 // Same thing here as with <then> branch, we are discarding it, we can't
8343 // replace it with NULL nor NullStmt as we need to keep for source location
8344 // range, for CoverageMapping
8345 Else = new (getSema().Context)
8346 CompoundStmt(S->getElse()->getBeginLoc(), S->getElse()->getEndLoc());
8347 }
8348
8349 if (!getDerived().AlwaysRebuild() &&
8350 Init.get() == S->getInit() &&
8351 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8352 Then.get() == S->getThen() &&
8353 Else.get() == S->getElse())
8354 return S;
8355
8356 return getDerived().RebuildIfStmt(
8357 S->getIfLoc(), S->getStatementKind(), S->getLParenLoc(), Cond,
8358 S->getRParenLoc(), Init.get(), Then.get(), S->getElseLoc(), Else.get());
8359}
8360
8361template<typename Derived>
8362StmtResult
8363TreeTransform<Derived>::TransformSwitchStmt(SwitchStmt *S) {
8364 // Transform the initialization statement
8365 StmtResult Init = getDerived().TransformStmt(S->getInit());
8366 if (Init.isInvalid())
8367 return StmtError();
8368
8369 // Transform the condition.
8370 Sema::ConditionResult Cond = getDerived().TransformCondition(
8371 S->getSwitchLoc(), S->getConditionVariable(), S->getCond(),
8372 Sema::ConditionKind::Switch);
8373 if (Cond.isInvalid())
8374 return StmtError();
8375
8376 // Rebuild the switch statement.
8377 StmtResult Switch =
8378 getDerived().RebuildSwitchStmtStart(S->getSwitchLoc(), S->getLParenLoc(),
8379 Init.get(), Cond, S->getRParenLoc());
8380 if (Switch.isInvalid())
8381 return StmtError();
8382
8383 // Transform the body of the switch statement.
8384 StmtResult Body = getDerived().TransformStmt(S->getBody());
8385 if (Body.isInvalid())
8386 return StmtError();
8387
8388 // Complete the switch statement.
8389 return getDerived().RebuildSwitchStmtBody(S->getSwitchLoc(), Switch.get(),
8390 Body.get());
8391}
8392
8393template<typename Derived>
8394StmtResult
8395TreeTransform<Derived>::TransformWhileStmt(WhileStmt *S) {
8396 // Transform the condition
8397 Sema::ConditionResult Cond = getDerived().TransformCondition(
8398 S->getWhileLoc(), S->getConditionVariable(), S->getCond(),
8399 Sema::ConditionKind::Boolean);
8400 if (Cond.isInvalid())
8401 return StmtError();
8402
8403 // OpenACC Restricts a while-loop inside of certain construct/clause
8404 // combinations, so diagnose that here in OpenACC mode.
8405 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8406 SemaRef.OpenACC().ActOnWhileStmt(WhileLoc: S->getBeginLoc());
8407
8408 // Transform the body
8409 StmtResult Body = getDerived().TransformStmt(S->getBody());
8410 if (Body.isInvalid())
8411 return StmtError();
8412
8413 if (!getDerived().AlwaysRebuild() &&
8414 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8415 Body.get() == S->getBody())
8416 return Owned(S);
8417
8418 return getDerived().RebuildWhileStmt(S->getWhileLoc(), S->getLParenLoc(),
8419 Cond, S->getRParenLoc(), Body.get());
8420}
8421
8422template<typename Derived>
8423StmtResult
8424TreeTransform<Derived>::TransformDoStmt(DoStmt *S) {
8425 // OpenACC Restricts a do-loop inside of certain construct/clause
8426 // combinations, so diagnose that here in OpenACC mode.
8427 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8428 SemaRef.OpenACC().ActOnDoStmt(DoLoc: S->getBeginLoc());
8429
8430 // Transform the body
8431 StmtResult Body = getDerived().TransformStmt(S->getBody());
8432 if (Body.isInvalid())
8433 return StmtError();
8434
8435 // Transform the condition
8436 ExprResult Cond = getDerived().TransformExpr(S->getCond());
8437 if (Cond.isInvalid())
8438 return StmtError();
8439
8440 if (!getDerived().AlwaysRebuild() &&
8441 Cond.get() == S->getCond() &&
8442 Body.get() == S->getBody())
8443 return S;
8444
8445 return getDerived().RebuildDoStmt(S->getDoLoc(), Body.get(), S->getWhileLoc(),
8446 /*FIXME:*/S->getWhileLoc(), Cond.get(),
8447 S->getRParenLoc());
8448}
8449
8450template<typename Derived>
8451StmtResult
8452TreeTransform<Derived>::TransformForStmt(ForStmt *S) {
8453 if (getSema().getLangOpts().OpenMP)
8454 getSema().OpenMP().startOpenMPLoop();
8455
8456 // Transform the initialization statement
8457 StmtResult Init = getDerived().TransformStmt(S->getInit());
8458 if (Init.isInvalid())
8459 return StmtError();
8460
8461 // In OpenMP loop region loop control variable must be captured and be
8462 // private. Perform analysis of first part (if any).
8463 if (getSema().getLangOpts().OpenMP && Init.isUsable())
8464 getSema().OpenMP().ActOnOpenMPLoopInitialization(S->getForLoc(),
8465 Init.get());
8466
8467 // Transform the condition
8468 Sema::ConditionResult Cond = getDerived().TransformCondition(
8469 S->getForLoc(), S->getConditionVariable(), S->getCond(),
8470 Sema::ConditionKind::Boolean);
8471 if (Cond.isInvalid())
8472 return StmtError();
8473
8474 // Transform the increment
8475 ExprResult Inc = getDerived().TransformExpr(S->getInc());
8476 if (Inc.isInvalid())
8477 return StmtError();
8478
8479 Sema::FullExprArg FullInc(getSema().MakeFullDiscardedValueExpr(Inc.get()));
8480 if (S->getInc() && !FullInc.get())
8481 return StmtError();
8482
8483 // OpenACC Restricts a for-loop inside of certain construct/clause
8484 // combinations, so diagnose that here in OpenACC mode.
8485 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
8486 SemaRef.OpenACC().ActOnForStmtBegin(
8487 S->getBeginLoc(), S->getInit(), Init.get(), S->getCond(),
8488 Cond.get().second, S->getInc(), Inc.get());
8489
8490 // Transform the body
8491 StmtResult Body = getDerived().TransformStmt(S->getBody());
8492 if (Body.isInvalid())
8493 return StmtError();
8494
8495 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
8496
8497 if (!getDerived().AlwaysRebuild() &&
8498 Init.get() == S->getInit() &&
8499 Cond.get() == std::make_pair(S->getConditionVariable(), S->getCond()) &&
8500 Inc.get() == S->getInc() &&
8501 Body.get() == S->getBody())
8502 return S;
8503
8504 return getDerived().RebuildForStmt(S->getForLoc(), S->getLParenLoc(),
8505 Init.get(), Cond, FullInc,
8506 S->getRParenLoc(), Body.get());
8507}
8508
8509template<typename Derived>
8510StmtResult
8511TreeTransform<Derived>::TransformGotoStmt(GotoStmt *S) {
8512 Decl *LD = getDerived().TransformDecl(S->getLabel()->getLocation(),
8513 S->getLabel());
8514 if (!LD)
8515 return StmtError();
8516
8517 // Goto statements must always be rebuilt, to resolve the label.
8518 return getDerived().RebuildGotoStmt(S->getGotoLoc(), S->getLabelLoc(),
8519 cast<LabelDecl>(LD));
8520}
8521
8522template<typename Derived>
8523StmtResult
8524TreeTransform<Derived>::TransformIndirectGotoStmt(IndirectGotoStmt *S) {
8525 ExprResult Target = getDerived().TransformExpr(S->getTarget());
8526 if (Target.isInvalid())
8527 return StmtError();
8528 Target = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Target.get());
8529
8530 if (!getDerived().AlwaysRebuild() &&
8531 Target.get() == S->getTarget())
8532 return S;
8533
8534 return getDerived().RebuildIndirectGotoStmt(S->getGotoLoc(), S->getStarLoc(),
8535 Target.get());
8536}
8537
8538template<typename Derived>
8539StmtResult
8540TreeTransform<Derived>::TransformContinueStmt(ContinueStmt *S) {
8541 return S;
8542}
8543
8544template<typename Derived>
8545StmtResult
8546TreeTransform<Derived>::TransformBreakStmt(BreakStmt *S) {
8547 return S;
8548}
8549
8550template<typename Derived>
8551StmtResult
8552TreeTransform<Derived>::TransformReturnStmt(ReturnStmt *S) {
8553 ExprResult Result = getDerived().TransformInitializer(S->getRetValue(),
8554 /*NotCopyInit*/false);
8555 if (Result.isInvalid())
8556 return StmtError();
8557
8558 // FIXME: We always rebuild the return statement because there is no way
8559 // to tell whether the return type of the function has changed.
8560 return getDerived().RebuildReturnStmt(S->getReturnLoc(), Result.get());
8561}
8562
8563template<typename Derived>
8564StmtResult
8565TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
8566 bool DeclChanged = false;
8567 SmallVector<Decl *, 4> Decls;
8568 LambdaScopeInfo *LSI = getSema().getCurLambda();
8569 for (auto *D : S->decls()) {
8570 Decl *Transformed = getDerived().TransformDefinition(D->getLocation(), D);
8571 if (!Transformed)
8572 return StmtError();
8573
8574 if (Transformed != D)
8575 DeclChanged = true;
8576
8577 if (LSI) {
8578 if (auto *TD = dyn_cast<TypeDecl>(Transformed))
8579 LSI->ContainsUnexpandedParameterPack |=
8580 getSema()
8581 .getASTContext()
8582 .getTypeDeclType(TD)
8583 .getSingleStepDesugaredType(getSema().getASTContext())
8584 ->containsUnexpandedParameterPack();
8585
8586 if (auto *VD = dyn_cast<VarDecl>(Transformed))
8587 LSI->ContainsUnexpandedParameterPack |=
8588 VD->getType()->containsUnexpandedParameterPack();
8589 }
8590
8591 Decls.push_back(Transformed);
8592 }
8593
8594 if (!getDerived().AlwaysRebuild() && !DeclChanged)
8595 return S;
8596
8597 return getDerived().RebuildDeclStmt(Decls, S->getBeginLoc(), S->getEndLoc());
8598}
8599
8600template<typename Derived>
8601StmtResult
8602TreeTransform<Derived>::TransformGCCAsmStmt(GCCAsmStmt *S) {
8603
8604 SmallVector<Expr*, 8> Constraints;
8605 SmallVector<Expr*, 8> Exprs;
8606 SmallVector<IdentifierInfo *, 4> Names;
8607
8608 SmallVector<Expr*, 8> Clobbers;
8609
8610 bool ExprsChanged = false;
8611
8612 auto RebuildString = [&](Expr *E) {
8613 ExprResult Result = getDerived().TransformExpr(E);
8614 if (!Result.isUsable())
8615 return Result;
8616 if (Result.get() != E) {
8617 ExprsChanged = true;
8618 Result = SemaRef.ActOnGCCAsmStmtString(Stm: Result.get(), /*ForLabel=*/ForAsmLabel: false);
8619 }
8620 return Result;
8621 };
8622
8623 // Go through the outputs.
8624 for (unsigned I = 0, E = S->getNumOutputs(); I != E; ++I) {
8625 Names.push_back(S->getOutputIdentifier(i: I));
8626
8627 ExprResult Result = RebuildString(S->getOutputConstraintExpr(i: I));
8628 if (Result.isInvalid())
8629 return StmtError();
8630
8631 Constraints.push_back(Result.get());
8632
8633 // Transform the output expr.
8634 Expr *OutputExpr = S->getOutputExpr(i: I);
8635 Result = getDerived().TransformExpr(OutputExpr);
8636 if (Result.isInvalid())
8637 return StmtError();
8638
8639 ExprsChanged |= Result.get() != OutputExpr;
8640
8641 Exprs.push_back(Result.get());
8642 }
8643
8644 // Go through the inputs.
8645 for (unsigned I = 0, E = S->getNumInputs(); I != E; ++I) {
8646 Names.push_back(S->getInputIdentifier(i: I));
8647
8648 ExprResult Result = RebuildString(S->getInputConstraintExpr(i: I));
8649 if (Result.isInvalid())
8650 return StmtError();
8651
8652 Constraints.push_back(Result.get());
8653
8654 // Transform the input expr.
8655 Expr *InputExpr = S->getInputExpr(i: I);
8656 Result = getDerived().TransformExpr(InputExpr);
8657 if (Result.isInvalid())
8658 return StmtError();
8659
8660 ExprsChanged |= Result.get() != InputExpr;
8661
8662 Exprs.push_back(Result.get());
8663 }
8664
8665 // Go through the Labels.
8666 for (unsigned I = 0, E = S->getNumLabels(); I != E; ++I) {
8667 Names.push_back(S->getLabelIdentifier(i: I));
8668
8669 ExprResult Result = getDerived().TransformExpr(S->getLabelExpr(i: I));
8670 if (Result.isInvalid())
8671 return StmtError();
8672 ExprsChanged |= Result.get() != S->getLabelExpr(i: I);
8673 Exprs.push_back(Result.get());
8674 }
8675
8676 // Go through the clobbers.
8677 for (unsigned I = 0, E = S->getNumClobbers(); I != E; ++I) {
8678 ExprResult Result = RebuildString(S->getClobberExpr(i: I));
8679 if (Result.isInvalid())
8680 return StmtError();
8681 Clobbers.push_back(Result.get());
8682 }
8683
8684 ExprResult AsmString = RebuildString(S->getAsmStringExpr());
8685 if (AsmString.isInvalid())
8686 return StmtError();
8687
8688 if (!getDerived().AlwaysRebuild() && !ExprsChanged)
8689 return S;
8690
8691 return getDerived().RebuildGCCAsmStmt(S->getAsmLoc(), S->isSimple(),
8692 S->isVolatile(), S->getNumOutputs(),
8693 S->getNumInputs(), Names.data(),
8694 Constraints, Exprs, AsmString.get(),
8695 Clobbers, S->getNumLabels(),
8696 S->getRParenLoc());
8697}
8698
8699template<typename Derived>
8700StmtResult
8701TreeTransform<Derived>::TransformMSAsmStmt(MSAsmStmt *S) {
8702 ArrayRef<Token> AsmToks = llvm::ArrayRef(S->getAsmToks(), S->getNumAsmToks());
8703
8704 bool HadError = false, HadChange = false;
8705
8706 ArrayRef<Expr*> SrcExprs = S->getAllExprs();
8707 SmallVector<Expr*, 8> TransformedExprs;
8708 TransformedExprs.reserve(SrcExprs.size());
8709 for (unsigned i = 0, e = SrcExprs.size(); i != e; ++i) {
8710 ExprResult Result = getDerived().TransformExpr(SrcExprs[i]);
8711 if (!Result.isUsable()) {
8712 HadError = true;
8713 } else {
8714 HadChange |= (Result.get() != SrcExprs[i]);
8715 TransformedExprs.push_back(Result.get());
8716 }
8717 }
8718
8719 if (HadError) return StmtError();
8720 if (!HadChange && !getDerived().AlwaysRebuild())
8721 return Owned(S);
8722
8723 return getDerived().RebuildMSAsmStmt(S->getAsmLoc(), S->getLBraceLoc(),
8724 AsmToks, S->getAsmString(),
8725 S->getNumOutputs(), S->getNumInputs(),
8726 S->getAllConstraints(), S->getClobbers(),
8727 TransformedExprs, S->getEndLoc());
8728}
8729
8730// C++ Coroutines
8731template<typename Derived>
8732StmtResult
8733TreeTransform<Derived>::TransformCoroutineBodyStmt(CoroutineBodyStmt *S) {
8734 auto *ScopeInfo = SemaRef.getCurFunction();
8735 auto *FD = cast<FunctionDecl>(SemaRef.CurContext);
8736 assert(FD && ScopeInfo && !ScopeInfo->CoroutinePromise &&
8737 ScopeInfo->NeedsCoroutineSuspends &&
8738 ScopeInfo->CoroutineSuspends.first == nullptr &&
8739 ScopeInfo->CoroutineSuspends.second == nullptr &&
8740 "expected clean scope info");
8741
8742 // Set that we have (possibly-invalid) suspend points before we do anything
8743 // that may fail.
8744 ScopeInfo->setNeedsCoroutineSuspends(false);
8745
8746 // We re-build the coroutine promise object (and the coroutine parameters its
8747 // type and constructor depend on) based on the types used in our current
8748 // function. We must do so, and set it on the current FunctionScopeInfo,
8749 // before attempting to transform the other parts of the coroutine body
8750 // statement, such as the implicit suspend statements (because those
8751 // statements reference the FunctionScopeInfo::CoroutinePromise).
8752 if (!SemaRef.buildCoroutineParameterMoves(Loc: FD->getLocation()))
8753 return StmtError();
8754 auto *Promise = SemaRef.buildCoroutinePromise(Loc: FD->getLocation());
8755 if (!Promise)
8756 return StmtError();
8757 getDerived().transformedLocalDecl(S->getPromiseDecl(), {Promise});
8758 ScopeInfo->CoroutinePromise = Promise;
8759
8760 // Transform the implicit coroutine statements constructed using dependent
8761 // types during the previous parse: initial and final suspensions, the return
8762 // object, and others. We also transform the coroutine function's body.
8763 StmtResult InitSuspend = getDerived().TransformStmt(S->getInitSuspendStmt());
8764 if (InitSuspend.isInvalid())
8765 return StmtError();
8766 StmtResult FinalSuspend =
8767 getDerived().TransformStmt(S->getFinalSuspendStmt());
8768 if (FinalSuspend.isInvalid() ||
8769 !SemaRef.checkFinalSuspendNoThrow(FinalSuspend: FinalSuspend.get()))
8770 return StmtError();
8771 ScopeInfo->setCoroutineSuspends(Initial: InitSuspend.get(), Final: FinalSuspend.get());
8772 assert(isa<Expr>(InitSuspend.get()) && isa<Expr>(FinalSuspend.get()));
8773
8774 StmtResult BodyRes = getDerived().TransformStmt(S->getBody());
8775 if (BodyRes.isInvalid())
8776 return StmtError();
8777
8778 CoroutineStmtBuilder Builder(SemaRef, *FD, *ScopeInfo, BodyRes.get());
8779 if (Builder.isInvalid())
8780 return StmtError();
8781
8782 Expr *ReturnObject = S->getReturnValueInit();
8783 assert(ReturnObject && "the return object is expected to be valid");
8784 ExprResult Res = getDerived().TransformInitializer(ReturnObject,
8785 /*NoCopyInit*/ false);
8786 if (Res.isInvalid())
8787 return StmtError();
8788 Builder.ReturnValue = Res.get();
8789
8790 // If during the previous parse the coroutine still had a dependent promise
8791 // statement, we may need to build some implicit coroutine statements
8792 // (such as exception and fallthrough handlers) for the first time.
8793 if (S->hasDependentPromiseType()) {
8794 // We can only build these statements, however, if the current promise type
8795 // is not dependent.
8796 if (!Promise->getType()->isDependentType()) {
8797 assert(!S->getFallthroughHandler() && !S->getExceptionHandler() &&
8798 !S->getReturnStmtOnAllocFailure() && !S->getDeallocate() &&
8799 "these nodes should not have been built yet");
8800 if (!Builder.buildDependentStatements())
8801 return StmtError();
8802 }
8803 } else {
8804 if (auto *OnFallthrough = S->getFallthroughHandler()) {
8805 StmtResult Res = getDerived().TransformStmt(OnFallthrough);
8806 if (Res.isInvalid())
8807 return StmtError();
8808 Builder.OnFallthrough = Res.get();
8809 }
8810
8811 if (auto *OnException = S->getExceptionHandler()) {
8812 StmtResult Res = getDerived().TransformStmt(OnException);
8813 if (Res.isInvalid())
8814 return StmtError();
8815 Builder.OnException = Res.get();
8816 }
8817
8818 if (auto *OnAllocFailure = S->getReturnStmtOnAllocFailure()) {
8819 StmtResult Res = getDerived().TransformStmt(OnAllocFailure);
8820 if (Res.isInvalid())
8821 return StmtError();
8822 Builder.ReturnStmtOnAllocFailure = Res.get();
8823 }
8824
8825 // Transform any additional statements we may have already built
8826 assert(S->getAllocate() && S->getDeallocate() &&
8827 "allocation and deallocation calls must already be built");
8828 ExprResult AllocRes = getDerived().TransformExpr(S->getAllocate());
8829 if (AllocRes.isInvalid())
8830 return StmtError();
8831 Builder.Allocate = AllocRes.get();
8832
8833 ExprResult DeallocRes = getDerived().TransformExpr(S->getDeallocate());
8834 if (DeallocRes.isInvalid())
8835 return StmtError();
8836 Builder.Deallocate = DeallocRes.get();
8837
8838 if (auto *ResultDecl = S->getResultDecl()) {
8839 StmtResult Res = getDerived().TransformStmt(ResultDecl);
8840 if (Res.isInvalid())
8841 return StmtError();
8842 Builder.ResultDecl = Res.get();
8843 }
8844
8845 if (auto *ReturnStmt = S->getReturnStmt()) {
8846 StmtResult Res = getDerived().TransformStmt(ReturnStmt);
8847 if (Res.isInvalid())
8848 return StmtError();
8849 Builder.ReturnStmt = Res.get();
8850 }
8851 }
8852
8853 return getDerived().RebuildCoroutineBodyStmt(Builder);
8854}
8855
8856template<typename Derived>
8857StmtResult
8858TreeTransform<Derived>::TransformCoreturnStmt(CoreturnStmt *S) {
8859 ExprResult Result = getDerived().TransformInitializer(S->getOperand(),
8860 /*NotCopyInit*/false);
8861 if (Result.isInvalid())
8862 return StmtError();
8863
8864 // Always rebuild; we don't know if this needs to be injected into a new
8865 // context or if the promise type has changed.
8866 return getDerived().RebuildCoreturnStmt(S->getKeywordLoc(), Result.get(),
8867 S->isImplicit());
8868}
8869
8870template <typename Derived>
8871ExprResult TreeTransform<Derived>::TransformCoawaitExpr(CoawaitExpr *E) {
8872 ExprResult Operand = getDerived().TransformInitializer(E->getOperand(),
8873 /*NotCopyInit*/ false);
8874 if (Operand.isInvalid())
8875 return ExprError();
8876
8877 // Rebuild the common-expr from the operand rather than transforming it
8878 // separately.
8879
8880 // FIXME: getCurScope() should not be used during template instantiation.
8881 // We should pick up the set of unqualified lookup results for operator
8882 // co_await during the initial parse.
8883 ExprResult Lookup = getSema().BuildOperatorCoawaitLookupExpr(
8884 getSema().getCurScope(), E->getKeywordLoc());
8885
8886 // Always rebuild; we don't know if this needs to be injected into a new
8887 // context or if the promise type has changed.
8888 return getDerived().RebuildCoawaitExpr(
8889 E->getKeywordLoc(), Operand.get(),
8890 cast<UnresolvedLookupExpr>(Lookup.get()), E->isImplicit());
8891}
8892
8893template <typename Derived>
8894ExprResult
8895TreeTransform<Derived>::TransformDependentCoawaitExpr(DependentCoawaitExpr *E) {
8896 ExprResult OperandResult = getDerived().TransformInitializer(E->getOperand(),
8897 /*NotCopyInit*/ false);
8898 if (OperandResult.isInvalid())
8899 return ExprError();
8900
8901 ExprResult LookupResult = getDerived().TransformUnresolvedLookupExpr(
8902 E->getOperatorCoawaitLookup());
8903
8904 if (LookupResult.isInvalid())
8905 return ExprError();
8906
8907 // Always rebuild; we don't know if this needs to be injected into a new
8908 // context or if the promise type has changed.
8909 return getDerived().RebuildDependentCoawaitExpr(
8910 E->getKeywordLoc(), OperandResult.get(),
8911 cast<UnresolvedLookupExpr>(LookupResult.get()));
8912}
8913
8914template<typename Derived>
8915ExprResult
8916TreeTransform<Derived>::TransformCoyieldExpr(CoyieldExpr *E) {
8917 ExprResult Result = getDerived().TransformInitializer(E->getOperand(),
8918 /*NotCopyInit*/false);
8919 if (Result.isInvalid())
8920 return ExprError();
8921
8922 // Always rebuild; we don't know if this needs to be injected into a new
8923 // context or if the promise type has changed.
8924 return getDerived().RebuildCoyieldExpr(E->getKeywordLoc(), Result.get());
8925}
8926
8927// Objective-C Statements.
8928
8929template<typename Derived>
8930StmtResult
8931TreeTransform<Derived>::TransformObjCAtTryStmt(ObjCAtTryStmt *S) {
8932 // Transform the body of the @try.
8933 StmtResult TryBody = getDerived().TransformStmt(S->getTryBody());
8934 if (TryBody.isInvalid())
8935 return StmtError();
8936
8937 // Transform the @catch statements (if present).
8938 bool AnyCatchChanged = false;
8939 SmallVector<Stmt*, 8> CatchStmts;
8940 for (unsigned I = 0, N = S->getNumCatchStmts(); I != N; ++I) {
8941 StmtResult Catch = getDerived().TransformStmt(S->getCatchStmt(I));
8942 if (Catch.isInvalid())
8943 return StmtError();
8944 if (Catch.get() != S->getCatchStmt(I))
8945 AnyCatchChanged = true;
8946 CatchStmts.push_back(Catch.get());
8947 }
8948
8949 // Transform the @finally statement (if present).
8950 StmtResult Finally;
8951 if (S->getFinallyStmt()) {
8952 Finally = getDerived().TransformStmt(S->getFinallyStmt());
8953 if (Finally.isInvalid())
8954 return StmtError();
8955 }
8956
8957 // If nothing changed, just retain this statement.
8958 if (!getDerived().AlwaysRebuild() &&
8959 TryBody.get() == S->getTryBody() &&
8960 !AnyCatchChanged &&
8961 Finally.get() == S->getFinallyStmt())
8962 return S;
8963
8964 // Build a new statement.
8965 return getDerived().RebuildObjCAtTryStmt(S->getAtTryLoc(), TryBody.get(),
8966 CatchStmts, Finally.get());
8967}
8968
8969template<typename Derived>
8970StmtResult
8971TreeTransform<Derived>::TransformObjCAtCatchStmt(ObjCAtCatchStmt *S) {
8972 // Transform the @catch parameter, if there is one.
8973 VarDecl *Var = nullptr;
8974 if (VarDecl *FromVar = S->getCatchParamDecl()) {
8975 TypeSourceInfo *TSInfo = nullptr;
8976 if (FromVar->getTypeSourceInfo()) {
8977 TSInfo = getDerived().TransformType(FromVar->getTypeSourceInfo());
8978 if (!TSInfo)
8979 return StmtError();
8980 }
8981
8982 QualType T;
8983 if (TSInfo)
8984 T = TSInfo->getType();
8985 else {
8986 T = getDerived().TransformType(FromVar->getType());
8987 if (T.isNull())
8988 return StmtError();
8989 }
8990
8991 Var = getDerived().RebuildObjCExceptionDecl(FromVar, TSInfo, T);
8992 if (!Var)
8993 return StmtError();
8994 }
8995
8996 StmtResult Body = getDerived().TransformStmt(S->getCatchBody());
8997 if (Body.isInvalid())
8998 return StmtError();
8999
9000 return getDerived().RebuildObjCAtCatchStmt(S->getAtCatchLoc(),
9001 S->getRParenLoc(),
9002 Var, Body.get());
9003}
9004
9005template<typename Derived>
9006StmtResult
9007TreeTransform<Derived>::TransformObjCAtFinallyStmt(ObjCAtFinallyStmt *S) {
9008 // Transform the body.
9009 StmtResult Body = getDerived().TransformStmt(S->getFinallyBody());
9010 if (Body.isInvalid())
9011 return StmtError();
9012
9013 // If nothing changed, just retain this statement.
9014 if (!getDerived().AlwaysRebuild() &&
9015 Body.get() == S->getFinallyBody())
9016 return S;
9017
9018 // Build a new statement.
9019 return getDerived().RebuildObjCAtFinallyStmt(S->getAtFinallyLoc(),
9020 Body.get());
9021}
9022
9023template<typename Derived>
9024StmtResult
9025TreeTransform<Derived>::TransformObjCAtThrowStmt(ObjCAtThrowStmt *S) {
9026 ExprResult Operand;
9027 if (S->getThrowExpr()) {
9028 Operand = getDerived().TransformExpr(S->getThrowExpr());
9029 if (Operand.isInvalid())
9030 return StmtError();
9031 }
9032
9033 if (!getDerived().AlwaysRebuild() &&
9034 Operand.get() == S->getThrowExpr())
9035 return S;
9036
9037 return getDerived().RebuildObjCAtThrowStmt(S->getThrowLoc(), Operand.get());
9038}
9039
9040template<typename Derived>
9041StmtResult
9042TreeTransform<Derived>::TransformObjCAtSynchronizedStmt(
9043 ObjCAtSynchronizedStmt *S) {
9044 // Transform the object we are locking.
9045 ExprResult Object = getDerived().TransformExpr(S->getSynchExpr());
9046 if (Object.isInvalid())
9047 return StmtError();
9048 Object =
9049 getDerived().RebuildObjCAtSynchronizedOperand(S->getAtSynchronizedLoc(),
9050 Object.get());
9051 if (Object.isInvalid())
9052 return StmtError();
9053
9054 // Transform the body.
9055 StmtResult Body = getDerived().TransformStmt(S->getSynchBody());
9056 if (Body.isInvalid())
9057 return StmtError();
9058
9059 // If nothing change, just retain the current statement.
9060 if (!getDerived().AlwaysRebuild() &&
9061 Object.get() == S->getSynchExpr() &&
9062 Body.get() == S->getSynchBody())
9063 return S;
9064
9065 // Build a new statement.
9066 return getDerived().RebuildObjCAtSynchronizedStmt(S->getAtSynchronizedLoc(),
9067 Object.get(), Body.get());
9068}
9069
9070template<typename Derived>
9071StmtResult
9072TreeTransform<Derived>::TransformObjCAutoreleasePoolStmt(
9073 ObjCAutoreleasePoolStmt *S) {
9074 // Transform the body.
9075 StmtResult Body = getDerived().TransformStmt(S->getSubStmt());
9076 if (Body.isInvalid())
9077 return StmtError();
9078
9079 // If nothing changed, just retain this statement.
9080 if (!getDerived().AlwaysRebuild() &&
9081 Body.get() == S->getSubStmt())
9082 return S;
9083
9084 // Build a new statement.
9085 return getDerived().RebuildObjCAutoreleasePoolStmt(
9086 S->getAtLoc(), Body.get());
9087}
9088
9089template<typename Derived>
9090StmtResult
9091TreeTransform<Derived>::TransformObjCForCollectionStmt(
9092 ObjCForCollectionStmt *S) {
9093 // Transform the element statement.
9094 StmtResult Element = getDerived().TransformStmt(
9095 S->getElement(), StmtDiscardKind::NotDiscarded);
9096 if (Element.isInvalid())
9097 return StmtError();
9098
9099 // Transform the collection expression.
9100 ExprResult Collection = getDerived().TransformExpr(S->getCollection());
9101 if (Collection.isInvalid())
9102 return StmtError();
9103
9104 // Transform the body.
9105 StmtResult Body = getDerived().TransformStmt(S->getBody());
9106 if (Body.isInvalid())
9107 return StmtError();
9108
9109 // If nothing changed, just retain this statement.
9110 if (!getDerived().AlwaysRebuild() &&
9111 Element.get() == S->getElement() &&
9112 Collection.get() == S->getCollection() &&
9113 Body.get() == S->getBody())
9114 return S;
9115
9116 // Build a new statement.
9117 return getDerived().RebuildObjCForCollectionStmt(S->getForLoc(),
9118 Element.get(),
9119 Collection.get(),
9120 S->getRParenLoc(),
9121 Body.get());
9122}
9123
9124template <typename Derived>
9125StmtResult TreeTransform<Derived>::TransformCXXCatchStmt(CXXCatchStmt *S) {
9126 // Transform the exception declaration, if any.
9127 VarDecl *Var = nullptr;
9128 if (VarDecl *ExceptionDecl = S->getExceptionDecl()) {
9129 TypeSourceInfo *T =
9130 getDerived().TransformType(ExceptionDecl->getTypeSourceInfo());
9131 if (!T)
9132 return StmtError();
9133
9134 Var = getDerived().RebuildExceptionDecl(
9135 ExceptionDecl, T, ExceptionDecl->getInnerLocStart(),
9136 ExceptionDecl->getLocation(), ExceptionDecl->getIdentifier());
9137 if (!Var || Var->isInvalidDecl())
9138 return StmtError();
9139 }
9140
9141 // Transform the actual exception handler.
9142 StmtResult Handler = getDerived().TransformStmt(S->getHandlerBlock());
9143 if (Handler.isInvalid())
9144 return StmtError();
9145
9146 if (!getDerived().AlwaysRebuild() && !Var &&
9147 Handler.get() == S->getHandlerBlock())
9148 return S;
9149
9150 return getDerived().RebuildCXXCatchStmt(S->getCatchLoc(), Var, Handler.get());
9151}
9152
9153template <typename Derived>
9154StmtResult TreeTransform<Derived>::TransformCXXTryStmt(CXXTryStmt *S) {
9155 // Transform the try block itself.
9156 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9157 if (TryBlock.isInvalid())
9158 return StmtError();
9159
9160 // Transform the handlers.
9161 bool HandlerChanged = false;
9162 SmallVector<Stmt *, 8> Handlers;
9163 for (unsigned I = 0, N = S->getNumHandlers(); I != N; ++I) {
9164 StmtResult Handler = getDerived().TransformCXXCatchStmt(S->getHandler(i: I));
9165 if (Handler.isInvalid())
9166 return StmtError();
9167
9168 HandlerChanged = HandlerChanged || Handler.get() != S->getHandler(i: I);
9169 Handlers.push_back(Handler.getAs<Stmt>());
9170 }
9171
9172 getSema().DiagnoseExceptionUse(S->getTryLoc(), /* IsTry= */ true);
9173
9174 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9175 !HandlerChanged)
9176 return S;
9177
9178 return getDerived().RebuildCXXTryStmt(S->getTryLoc(), TryBlock.get(),
9179 Handlers);
9180}
9181
9182template<typename Derived>
9183StmtResult
9184TreeTransform<Derived>::TransformCXXForRangeStmt(CXXForRangeStmt *S) {
9185 EnterExpressionEvaluationContext ForRangeInitContext(
9186 getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated,
9187 /*LambdaContextDecl=*/nullptr,
9188 Sema::ExpressionEvaluationContextRecord::EK_Other,
9189 getSema().getLangOpts().CPlusPlus23);
9190
9191 // P2718R0 - Lifetime extension in range-based for loops.
9192 if (getSema().getLangOpts().CPlusPlus23) {
9193 auto &LastRecord = getSema().currentEvaluationContext();
9194 LastRecord.InLifetimeExtendingContext = true;
9195 LastRecord.RebuildDefaultArgOrDefaultInit = true;
9196 }
9197 StmtResult Init =
9198 S->getInit() ? getDerived().TransformStmt(S->getInit()) : StmtResult();
9199 if (Init.isInvalid())
9200 return StmtError();
9201
9202 StmtResult Range = getDerived().TransformStmt(S->getRangeStmt());
9203 if (Range.isInvalid())
9204 return StmtError();
9205
9206 // Before c++23, ForRangeLifetimeExtendTemps should be empty.
9207 assert(getSema().getLangOpts().CPlusPlus23 ||
9208 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps.empty());
9209 auto ForRangeLifetimeExtendTemps =
9210 getSema().ExprEvalContexts.back().ForRangeLifetimeExtendTemps;
9211
9212 StmtResult Begin = getDerived().TransformStmt(S->getBeginStmt());
9213 if (Begin.isInvalid())
9214 return StmtError();
9215 StmtResult End = getDerived().TransformStmt(S->getEndStmt());
9216 if (End.isInvalid())
9217 return StmtError();
9218
9219 ExprResult Cond = getDerived().TransformExpr(S->getCond());
9220 if (Cond.isInvalid())
9221 return StmtError();
9222 if (Cond.get())
9223 Cond = SemaRef.CheckBooleanCondition(Loc: S->getColonLoc(), E: Cond.get());
9224 if (Cond.isInvalid())
9225 return StmtError();
9226 if (Cond.get())
9227 Cond = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Cond.get());
9228
9229 ExprResult Inc = getDerived().TransformExpr(S->getInc());
9230 if (Inc.isInvalid())
9231 return StmtError();
9232 if (Inc.get())
9233 Inc = SemaRef.MaybeCreateExprWithCleanups(SubExpr: Inc.get());
9234
9235 StmtResult LoopVar = getDerived().TransformStmt(S->getLoopVarStmt());
9236 if (LoopVar.isInvalid())
9237 return StmtError();
9238
9239 StmtResult NewStmt = S;
9240 if (getDerived().AlwaysRebuild() ||
9241 Init.get() != S->getInit() ||
9242 Range.get() != S->getRangeStmt() ||
9243 Begin.get() != S->getBeginStmt() ||
9244 End.get() != S->getEndStmt() ||
9245 Cond.get() != S->getCond() ||
9246 Inc.get() != S->getInc() ||
9247 LoopVar.get() != S->getLoopVarStmt()) {
9248 NewStmt = getDerived().RebuildCXXForRangeStmt(
9249 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9250 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9251 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9252 if (NewStmt.isInvalid() && LoopVar.get() != S->getLoopVarStmt()) {
9253 // Might not have attached any initializer to the loop variable.
9254 getSema().ActOnInitializerError(
9255 cast<DeclStmt>(LoopVar.get())->getSingleDecl());
9256 return StmtError();
9257 }
9258 }
9259
9260 // OpenACC Restricts a while-loop inside of certain construct/clause
9261 // combinations, so diagnose that here in OpenACC mode.
9262 SemaOpenACC::LoopInConstructRAII LCR{SemaRef.OpenACC()};
9263 SemaRef.OpenACC().ActOnRangeForStmtBegin(ForLoc: S->getBeginLoc(), OldRangeFor: S, RangeFor: NewStmt.get());
9264
9265 StmtResult Body = getDerived().TransformStmt(S->getBody());
9266 if (Body.isInvalid())
9267 return StmtError();
9268
9269 SemaRef.OpenACC().ActOnForStmtEnd(ForLoc: S->getBeginLoc(), Body);
9270
9271 // Body has changed but we didn't rebuild the for-range statement. Rebuild
9272 // it now so we have a new statement to attach the body to.
9273 if (Body.get() != S->getBody() && NewStmt.get() == S) {
9274 NewStmt = getDerived().RebuildCXXForRangeStmt(
9275 S->getForLoc(), S->getCoawaitLoc(), Init.get(), S->getColonLoc(),
9276 Range.get(), Begin.get(), End.get(), Cond.get(), Inc.get(),
9277 LoopVar.get(), S->getRParenLoc(), ForRangeLifetimeExtendTemps);
9278 if (NewStmt.isInvalid())
9279 return StmtError();
9280 }
9281
9282 if (NewStmt.get() == S)
9283 return S;
9284
9285 return FinishCXXForRangeStmt(ForRange: NewStmt.get(), Body: Body.get());
9286}
9287
9288template<typename Derived>
9289StmtResult
9290TreeTransform<Derived>::TransformMSDependentExistsStmt(
9291 MSDependentExistsStmt *S) {
9292 // Transform the nested-name-specifier, if any.
9293 NestedNameSpecifierLoc QualifierLoc;
9294 if (S->getQualifierLoc()) {
9295 QualifierLoc
9296 = getDerived().TransformNestedNameSpecifierLoc(S->getQualifierLoc());
9297 if (!QualifierLoc)
9298 return StmtError();
9299 }
9300
9301 // Transform the declaration name.
9302 DeclarationNameInfo NameInfo = S->getNameInfo();
9303 if (NameInfo.getName()) {
9304 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
9305 if (!NameInfo.getName())
9306 return StmtError();
9307 }
9308
9309 // Check whether anything changed.
9310 if (!getDerived().AlwaysRebuild() &&
9311 QualifierLoc == S->getQualifierLoc() &&
9312 NameInfo.getName() == S->getNameInfo().getName())
9313 return S;
9314
9315 // Determine whether this name exists, if we can.
9316 CXXScopeSpec SS;
9317 SS.Adopt(Other: QualifierLoc);
9318 bool Dependent = false;
9319 switch (getSema().CheckMicrosoftIfExistsSymbol(/*S=*/nullptr, SS, NameInfo)) {
9320 case IfExistsResult::Exists:
9321 if (S->isIfExists())
9322 break;
9323
9324 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9325
9326 case IfExistsResult::DoesNotExist:
9327 if (S->isIfNotExists())
9328 break;
9329
9330 return new (getSema().Context) NullStmt(S->getKeywordLoc());
9331
9332 case IfExistsResult::Dependent:
9333 Dependent = true;
9334 break;
9335
9336 case IfExistsResult::Error:
9337 return StmtError();
9338 }
9339
9340 // We need to continue with the instantiation, so do so now.
9341 StmtResult SubStmt = getDerived().TransformCompoundStmt(S->getSubStmt());
9342 if (SubStmt.isInvalid())
9343 return StmtError();
9344
9345 // If we have resolved the name, just transform to the substatement.
9346 if (!Dependent)
9347 return SubStmt;
9348
9349 // The name is still dependent, so build a dependent expression again.
9350 return getDerived().RebuildMSDependentExistsStmt(S->getKeywordLoc(),
9351 S->isIfExists(),
9352 QualifierLoc,
9353 NameInfo,
9354 SubStmt.get());
9355}
9356
9357template<typename Derived>
9358ExprResult
9359TreeTransform<Derived>::TransformMSPropertyRefExpr(MSPropertyRefExpr *E) {
9360 NestedNameSpecifierLoc QualifierLoc;
9361 if (E->getQualifierLoc()) {
9362 QualifierLoc
9363 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
9364 if (!QualifierLoc)
9365 return ExprError();
9366 }
9367
9368 MSPropertyDecl *PD = cast_or_null<MSPropertyDecl>(
9369 getDerived().TransformDecl(E->getMemberLoc(), E->getPropertyDecl()));
9370 if (!PD)
9371 return ExprError();
9372
9373 ExprResult Base = getDerived().TransformExpr(E->getBaseExpr());
9374 if (Base.isInvalid())
9375 return ExprError();
9376
9377 return new (SemaRef.getASTContext())
9378 MSPropertyRefExpr(Base.get(), PD, E->isArrow(),
9379 SemaRef.getASTContext().PseudoObjectTy, VK_LValue,
9380 QualifierLoc, E->getMemberLoc());
9381}
9382
9383template <typename Derived>
9384ExprResult TreeTransform<Derived>::TransformMSPropertySubscriptExpr(
9385 MSPropertySubscriptExpr *E) {
9386 auto BaseRes = getDerived().TransformExpr(E->getBase());
9387 if (BaseRes.isInvalid())
9388 return ExprError();
9389 auto IdxRes = getDerived().TransformExpr(E->getIdx());
9390 if (IdxRes.isInvalid())
9391 return ExprError();
9392
9393 if (!getDerived().AlwaysRebuild() &&
9394 BaseRes.get() == E->getBase() &&
9395 IdxRes.get() == E->getIdx())
9396 return E;
9397
9398 return getDerived().RebuildArraySubscriptExpr(
9399 BaseRes.get(), SourceLocation(), IdxRes.get(), E->getRBracketLoc());
9400}
9401
9402template <typename Derived>
9403StmtResult TreeTransform<Derived>::TransformSEHTryStmt(SEHTryStmt *S) {
9404 StmtResult TryBlock = getDerived().TransformCompoundStmt(S->getTryBlock());
9405 if (TryBlock.isInvalid())
9406 return StmtError();
9407
9408 StmtResult Handler = getDerived().TransformSEHHandler(S->getHandler());
9409 if (Handler.isInvalid())
9410 return StmtError();
9411
9412 if (!getDerived().AlwaysRebuild() && TryBlock.get() == S->getTryBlock() &&
9413 Handler.get() == S->getHandler())
9414 return S;
9415
9416 return getDerived().RebuildSEHTryStmt(S->getIsCXXTry(), S->getTryLoc(),
9417 TryBlock.get(), Handler.get());
9418}
9419
9420template <typename Derived>
9421StmtResult TreeTransform<Derived>::TransformSEHFinallyStmt(SEHFinallyStmt *S) {
9422 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9423 if (Block.isInvalid())
9424 return StmtError();
9425
9426 return getDerived().RebuildSEHFinallyStmt(S->getFinallyLoc(), Block.get());
9427}
9428
9429template <typename Derived>
9430StmtResult TreeTransform<Derived>::TransformSEHExceptStmt(SEHExceptStmt *S) {
9431 ExprResult FilterExpr = getDerived().TransformExpr(S->getFilterExpr());
9432 if (FilterExpr.isInvalid())
9433 return StmtError();
9434
9435 StmtResult Block = getDerived().TransformCompoundStmt(S->getBlock());
9436 if (Block.isInvalid())
9437 return StmtError();
9438
9439 return getDerived().RebuildSEHExceptStmt(S->getExceptLoc(), FilterExpr.get(),
9440 Block.get());
9441}
9442
9443template <typename Derived>
9444StmtResult TreeTransform<Derived>::TransformSEHHandler(Stmt *Handler) {
9445 if (isa<SEHFinallyStmt>(Handler))
9446 return getDerived().TransformSEHFinallyStmt(cast<SEHFinallyStmt>(Handler));
9447 else
9448 return getDerived().TransformSEHExceptStmt(cast<SEHExceptStmt>(Handler));
9449}
9450
9451template<typename Derived>
9452StmtResult
9453TreeTransform<Derived>::TransformSEHLeaveStmt(SEHLeaveStmt *S) {
9454 return S;
9455}
9456
9457//===----------------------------------------------------------------------===//
9458// OpenMP directive transformation
9459//===----------------------------------------------------------------------===//
9460
9461template <typename Derived>
9462StmtResult
9463TreeTransform<Derived>::TransformOMPCanonicalLoop(OMPCanonicalLoop *L) {
9464 // OMPCanonicalLoops are eliminated during transformation, since they will be
9465 // recomputed by semantic analysis of the associated OMPLoopBasedDirective
9466 // after transformation.
9467 return getDerived().TransformStmt(L->getLoopStmt());
9468}
9469
9470template <typename Derived>
9471StmtResult TreeTransform<Derived>::TransformOMPExecutableDirective(
9472 OMPExecutableDirective *D) {
9473
9474 // Transform the clauses
9475 llvm::SmallVector<OMPClause *, 16> TClauses;
9476 ArrayRef<OMPClause *> Clauses = D->clauses();
9477 TClauses.reserve(Clauses.size());
9478 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end();
9479 I != E; ++I) {
9480 if (*I) {
9481 getDerived().getSema().OpenMP().StartOpenMPClause((*I)->getClauseKind());
9482 OMPClause *Clause = getDerived().TransformOMPClause(*I);
9483 getDerived().getSema().OpenMP().EndOpenMPClause();
9484 if (Clause)
9485 TClauses.push_back(Clause);
9486 } else {
9487 TClauses.push_back(nullptr);
9488 }
9489 }
9490 StmtResult AssociatedStmt;
9491 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9492 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9493 D->getDirectiveKind(),
9494 /*CurScope=*/nullptr);
9495 StmtResult Body;
9496 {
9497 Sema::CompoundScopeRAII CompoundScope(getSema());
9498 Stmt *CS;
9499 if (D->getDirectiveKind() == OMPD_atomic ||
9500 D->getDirectiveKind() == OMPD_critical ||
9501 D->getDirectiveKind() == OMPD_section ||
9502 D->getDirectiveKind() == OMPD_master)
9503 CS = D->getAssociatedStmt();
9504 else
9505 CS = D->getRawStmt();
9506 Body = getDerived().TransformStmt(CS);
9507 if (Body.isUsable() && isOpenMPLoopDirective(DKind: D->getDirectiveKind()) &&
9508 getSema().getLangOpts().OpenMPIRBuilder)
9509 Body = getDerived().RebuildOMPCanonicalLoop(Body.get());
9510 }
9511 AssociatedStmt =
9512 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9513 if (AssociatedStmt.isInvalid()) {
9514 return StmtError();
9515 }
9516 }
9517 if (TClauses.size() != Clauses.size()) {
9518 return StmtError();
9519 }
9520
9521 // Transform directive name for 'omp critical' directive.
9522 DeclarationNameInfo DirName;
9523 if (D->getDirectiveKind() == OMPD_critical) {
9524 DirName = cast<OMPCriticalDirective>(D)->getDirectiveName();
9525 DirName = getDerived().TransformDeclarationNameInfo(DirName);
9526 }
9527 OpenMPDirectiveKind CancelRegion = OMPD_unknown;
9528 if (D->getDirectiveKind() == OMPD_cancellation_point) {
9529 CancelRegion = cast<OMPCancellationPointDirective>(D)->getCancelRegion();
9530 } else if (D->getDirectiveKind() == OMPD_cancel) {
9531 CancelRegion = cast<OMPCancelDirective>(D)->getCancelRegion();
9532 }
9533
9534 return getDerived().RebuildOMPExecutableDirective(
9535 D->getDirectiveKind(), DirName, CancelRegion, TClauses,
9536 AssociatedStmt.get(), D->getBeginLoc(), D->getEndLoc());
9537}
9538
9539/// This is mostly the same as above, but allows 'informational' class
9540/// directives when rebuilding the stmt. It still takes an
9541/// OMPExecutableDirective-type argument because we're reusing that as the
9542/// superclass for the 'assume' directive at present, instead of defining a
9543/// mostly-identical OMPInformationalDirective parent class.
9544template <typename Derived>
9545StmtResult TreeTransform<Derived>::TransformOMPInformationalDirective(
9546 OMPExecutableDirective *D) {
9547
9548 // Transform the clauses
9549 llvm::SmallVector<OMPClause *, 16> TClauses;
9550 ArrayRef<OMPClause *> Clauses = D->clauses();
9551 TClauses.reserve(Clauses.size());
9552 for (OMPClause *C : Clauses) {
9553 if (C) {
9554 getDerived().getSema().OpenMP().StartOpenMPClause(C->getClauseKind());
9555 OMPClause *Clause = getDerived().TransformOMPClause(C);
9556 getDerived().getSema().OpenMP().EndOpenMPClause();
9557 if (Clause)
9558 TClauses.push_back(Clause);
9559 } else {
9560 TClauses.push_back(nullptr);
9561 }
9562 }
9563 StmtResult AssociatedStmt;
9564 if (D->hasAssociatedStmt() && D->getAssociatedStmt()) {
9565 getDerived().getSema().OpenMP().ActOnOpenMPRegionStart(
9566 D->getDirectiveKind(),
9567 /*CurScope=*/nullptr);
9568 StmtResult Body;
9569 {
9570 Sema::CompoundScopeRAII CompoundScope(getSema());
9571 assert(D->getDirectiveKind() == OMPD_assume &&
9572 "Unexpected informational directive");
9573 Stmt *CS = D->getAssociatedStmt();
9574 Body = getDerived().TransformStmt(CS);
9575 }
9576 AssociatedStmt =
9577 getDerived().getSema().OpenMP().ActOnOpenMPRegionEnd(Body, TClauses);
9578 if (AssociatedStmt.isInvalid())
9579 return StmtError();
9580 }
9581 if (TClauses.size() != Clauses.size())
9582 return StmtError();
9583
9584 DeclarationNameInfo DirName;
9585
9586 return getDerived().RebuildOMPInformationalDirective(
9587 D->getDirectiveKind(), DirName, TClauses, AssociatedStmt.get(),
9588 D->getBeginLoc(), D->getEndLoc());
9589}
9590
9591template <typename Derived>
9592StmtResult
9593TreeTransform<Derived>::TransformOMPMetaDirective(OMPMetaDirective *D) {
9594 // TODO: Fix This
9595 unsigned OMPVersion = getDerived().getSema().getLangOpts().OpenMP;
9596 SemaRef.Diag(D->getBeginLoc(), diag::err_omp_instantiation_not_supported)
9597 << getOpenMPDirectiveName(D->getDirectiveKind(), OMPVersion);
9598 return StmtError();
9599}
9600
9601template <typename Derived>
9602StmtResult
9603TreeTransform<Derived>::TransformOMPParallelDirective(OMPParallelDirective *D) {
9604 DeclarationNameInfo DirName;
9605 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9606 OMPD_parallel, DirName, nullptr, D->getBeginLoc());
9607 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9608 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9609 return Res;
9610}
9611
9612template <typename Derived>
9613StmtResult
9614TreeTransform<Derived>::TransformOMPSimdDirective(OMPSimdDirective *D) {
9615 DeclarationNameInfo DirName;
9616 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9617 OMPD_simd, DirName, nullptr, D->getBeginLoc());
9618 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9619 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9620 return Res;
9621}
9622
9623template <typename Derived>
9624StmtResult
9625TreeTransform<Derived>::TransformOMPTileDirective(OMPTileDirective *D) {
9626 DeclarationNameInfo DirName;
9627 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9628 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9629 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9630 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9631 return Res;
9632}
9633
9634template <typename Derived>
9635StmtResult
9636TreeTransform<Derived>::TransformOMPStripeDirective(OMPStripeDirective *D) {
9637 DeclarationNameInfo DirName;
9638 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9639 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9640 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9641 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9642 return Res;
9643}
9644
9645template <typename Derived>
9646StmtResult
9647TreeTransform<Derived>::TransformOMPUnrollDirective(OMPUnrollDirective *D) {
9648 DeclarationNameInfo DirName;
9649 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9650 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9651 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9652 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9653 return Res;
9654}
9655
9656template <typename Derived>
9657StmtResult
9658TreeTransform<Derived>::TransformOMPReverseDirective(OMPReverseDirective *D) {
9659 DeclarationNameInfo DirName;
9660 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9661 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9662 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9663 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9664 return Res;
9665}
9666
9667template <typename Derived>
9668StmtResult TreeTransform<Derived>::TransformOMPInterchangeDirective(
9669 OMPInterchangeDirective *D) {
9670 DeclarationNameInfo DirName;
9671 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9672 D->getDirectiveKind(), DirName, nullptr, D->getBeginLoc());
9673 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9674 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9675 return Res;
9676}
9677
9678template <typename Derived>
9679StmtResult
9680TreeTransform<Derived>::TransformOMPForDirective(OMPForDirective *D) {
9681 DeclarationNameInfo DirName;
9682 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9683 OMPD_for, DirName, nullptr, D->getBeginLoc());
9684 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9685 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9686 return Res;
9687}
9688
9689template <typename Derived>
9690StmtResult
9691TreeTransform<Derived>::TransformOMPForSimdDirective(OMPForSimdDirective *D) {
9692 DeclarationNameInfo DirName;
9693 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9694 OMPD_for_simd, DirName, nullptr, D->getBeginLoc());
9695 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9696 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9697 return Res;
9698}
9699
9700template <typename Derived>
9701StmtResult
9702TreeTransform<Derived>::TransformOMPSectionsDirective(OMPSectionsDirective *D) {
9703 DeclarationNameInfo DirName;
9704 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9705 OMPD_sections, DirName, nullptr, D->getBeginLoc());
9706 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9707 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9708 return Res;
9709}
9710
9711template <typename Derived>
9712StmtResult
9713TreeTransform<Derived>::TransformOMPSectionDirective(OMPSectionDirective *D) {
9714 DeclarationNameInfo DirName;
9715 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9716 OMPD_section, DirName, nullptr, D->getBeginLoc());
9717 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9718 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9719 return Res;
9720}
9721
9722template <typename Derived>
9723StmtResult
9724TreeTransform<Derived>::TransformOMPScopeDirective(OMPScopeDirective *D) {
9725 DeclarationNameInfo DirName;
9726 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9727 OMPD_scope, DirName, nullptr, D->getBeginLoc());
9728 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9729 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9730 return Res;
9731}
9732
9733template <typename Derived>
9734StmtResult
9735TreeTransform<Derived>::TransformOMPSingleDirective(OMPSingleDirective *D) {
9736 DeclarationNameInfo DirName;
9737 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9738 OMPD_single, DirName, nullptr, D->getBeginLoc());
9739 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9740 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9741 return Res;
9742}
9743
9744template <typename Derived>
9745StmtResult
9746TreeTransform<Derived>::TransformOMPMasterDirective(OMPMasterDirective *D) {
9747 DeclarationNameInfo DirName;
9748 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9749 OMPD_master, DirName, nullptr, D->getBeginLoc());
9750 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9751 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9752 return Res;
9753}
9754
9755template <typename Derived>
9756StmtResult
9757TreeTransform<Derived>::TransformOMPCriticalDirective(OMPCriticalDirective *D) {
9758 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9759 OMPD_critical, D->getDirectiveName(), nullptr, D->getBeginLoc());
9760 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9761 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9762 return Res;
9763}
9764
9765template <typename Derived>
9766StmtResult TreeTransform<Derived>::TransformOMPParallelForDirective(
9767 OMPParallelForDirective *D) {
9768 DeclarationNameInfo DirName;
9769 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9770 OMPD_parallel_for, DirName, nullptr, D->getBeginLoc());
9771 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9772 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9773 return Res;
9774}
9775
9776template <typename Derived>
9777StmtResult TreeTransform<Derived>::TransformOMPParallelForSimdDirective(
9778 OMPParallelForSimdDirective *D) {
9779 DeclarationNameInfo DirName;
9780 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9781 OMPD_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
9782 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9783 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9784 return Res;
9785}
9786
9787template <typename Derived>
9788StmtResult TreeTransform<Derived>::TransformOMPParallelMasterDirective(
9789 OMPParallelMasterDirective *D) {
9790 DeclarationNameInfo DirName;
9791 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9792 OMPD_parallel_master, DirName, nullptr, D->getBeginLoc());
9793 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9794 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9795 return Res;
9796}
9797
9798template <typename Derived>
9799StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedDirective(
9800 OMPParallelMaskedDirective *D) {
9801 DeclarationNameInfo DirName;
9802 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9803 OMPD_parallel_masked, DirName, nullptr, D->getBeginLoc());
9804 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9805 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9806 return Res;
9807}
9808
9809template <typename Derived>
9810StmtResult TreeTransform<Derived>::TransformOMPParallelSectionsDirective(
9811 OMPParallelSectionsDirective *D) {
9812 DeclarationNameInfo DirName;
9813 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9814 OMPD_parallel_sections, DirName, nullptr, D->getBeginLoc());
9815 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9816 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9817 return Res;
9818}
9819
9820template <typename Derived>
9821StmtResult
9822TreeTransform<Derived>::TransformOMPTaskDirective(OMPTaskDirective *D) {
9823 DeclarationNameInfo DirName;
9824 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9825 OMPD_task, DirName, nullptr, D->getBeginLoc());
9826 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9827 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9828 return Res;
9829}
9830
9831template <typename Derived>
9832StmtResult TreeTransform<Derived>::TransformOMPTaskyieldDirective(
9833 OMPTaskyieldDirective *D) {
9834 DeclarationNameInfo DirName;
9835 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9836 OMPD_taskyield, DirName, nullptr, D->getBeginLoc());
9837 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9838 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9839 return Res;
9840}
9841
9842template <typename Derived>
9843StmtResult
9844TreeTransform<Derived>::TransformOMPBarrierDirective(OMPBarrierDirective *D) {
9845 DeclarationNameInfo DirName;
9846 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9847 OMPD_barrier, DirName, nullptr, D->getBeginLoc());
9848 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9849 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9850 return Res;
9851}
9852
9853template <typename Derived>
9854StmtResult
9855TreeTransform<Derived>::TransformOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
9856 DeclarationNameInfo DirName;
9857 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9858 OMPD_taskwait, DirName, nullptr, D->getBeginLoc());
9859 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9860 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9861 return Res;
9862}
9863
9864template <typename Derived>
9865StmtResult
9866TreeTransform<Derived>::TransformOMPAssumeDirective(OMPAssumeDirective *D) {
9867 DeclarationNameInfo DirName;
9868 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9869 OMPD_assume, DirName, nullptr, D->getBeginLoc());
9870 StmtResult Res = getDerived().TransformOMPInformationalDirective(D);
9871 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9872 return Res;
9873}
9874
9875template <typename Derived>
9876StmtResult
9877TreeTransform<Derived>::TransformOMPErrorDirective(OMPErrorDirective *D) {
9878 DeclarationNameInfo DirName;
9879 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9880 OMPD_error, DirName, nullptr, D->getBeginLoc());
9881 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9882 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9883 return Res;
9884}
9885
9886template <typename Derived>
9887StmtResult TreeTransform<Derived>::TransformOMPTaskgroupDirective(
9888 OMPTaskgroupDirective *D) {
9889 DeclarationNameInfo DirName;
9890 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9891 OMPD_taskgroup, DirName, nullptr, D->getBeginLoc());
9892 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9893 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9894 return Res;
9895}
9896
9897template <typename Derived>
9898StmtResult
9899TreeTransform<Derived>::TransformOMPFlushDirective(OMPFlushDirective *D) {
9900 DeclarationNameInfo DirName;
9901 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9902 OMPD_flush, DirName, nullptr, D->getBeginLoc());
9903 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9904 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9905 return Res;
9906}
9907
9908template <typename Derived>
9909StmtResult
9910TreeTransform<Derived>::TransformOMPDepobjDirective(OMPDepobjDirective *D) {
9911 DeclarationNameInfo DirName;
9912 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9913 OMPD_depobj, DirName, nullptr, D->getBeginLoc());
9914 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9915 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9916 return Res;
9917}
9918
9919template <typename Derived>
9920StmtResult
9921TreeTransform<Derived>::TransformOMPScanDirective(OMPScanDirective *D) {
9922 DeclarationNameInfo DirName;
9923 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9924 OMPD_scan, DirName, nullptr, D->getBeginLoc());
9925 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9926 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9927 return Res;
9928}
9929
9930template <typename Derived>
9931StmtResult
9932TreeTransform<Derived>::TransformOMPOrderedDirective(OMPOrderedDirective *D) {
9933 DeclarationNameInfo DirName;
9934 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9935 OMPD_ordered, DirName, nullptr, D->getBeginLoc());
9936 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9937 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9938 return Res;
9939}
9940
9941template <typename Derived>
9942StmtResult
9943TreeTransform<Derived>::TransformOMPAtomicDirective(OMPAtomicDirective *D) {
9944 DeclarationNameInfo DirName;
9945 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9946 OMPD_atomic, DirName, nullptr, D->getBeginLoc());
9947 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9948 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9949 return Res;
9950}
9951
9952template <typename Derived>
9953StmtResult
9954TreeTransform<Derived>::TransformOMPTargetDirective(OMPTargetDirective *D) {
9955 DeclarationNameInfo DirName;
9956 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9957 OMPD_target, DirName, nullptr, D->getBeginLoc());
9958 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9959 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9960 return Res;
9961}
9962
9963template <typename Derived>
9964StmtResult TreeTransform<Derived>::TransformOMPTargetDataDirective(
9965 OMPTargetDataDirective *D) {
9966 DeclarationNameInfo DirName;
9967 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9968 OMPD_target_data, DirName, nullptr, D->getBeginLoc());
9969 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9970 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9971 return Res;
9972}
9973
9974template <typename Derived>
9975StmtResult TreeTransform<Derived>::TransformOMPTargetEnterDataDirective(
9976 OMPTargetEnterDataDirective *D) {
9977 DeclarationNameInfo DirName;
9978 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9979 OMPD_target_enter_data, DirName, nullptr, D->getBeginLoc());
9980 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9981 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9982 return Res;
9983}
9984
9985template <typename Derived>
9986StmtResult TreeTransform<Derived>::TransformOMPTargetExitDataDirective(
9987 OMPTargetExitDataDirective *D) {
9988 DeclarationNameInfo DirName;
9989 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
9990 OMPD_target_exit_data, DirName, nullptr, D->getBeginLoc());
9991 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
9992 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
9993 return Res;
9994}
9995
9996template <typename Derived>
9997StmtResult TreeTransform<Derived>::TransformOMPTargetParallelDirective(
9998 OMPTargetParallelDirective *D) {
9999 DeclarationNameInfo DirName;
10000 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10001 OMPD_target_parallel, DirName, nullptr, D->getBeginLoc());
10002 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10003 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10004 return Res;
10005}
10006
10007template <typename Derived>
10008StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForDirective(
10009 OMPTargetParallelForDirective *D) {
10010 DeclarationNameInfo DirName;
10011 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10012 OMPD_target_parallel_for, DirName, nullptr, D->getBeginLoc());
10013 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10014 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10015 return Res;
10016}
10017
10018template <typename Derived>
10019StmtResult TreeTransform<Derived>::TransformOMPTargetUpdateDirective(
10020 OMPTargetUpdateDirective *D) {
10021 DeclarationNameInfo DirName;
10022 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10023 OMPD_target_update, DirName, nullptr, D->getBeginLoc());
10024 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10025 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10026 return Res;
10027}
10028
10029template <typename Derived>
10030StmtResult
10031TreeTransform<Derived>::TransformOMPTeamsDirective(OMPTeamsDirective *D) {
10032 DeclarationNameInfo DirName;
10033 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10034 OMPD_teams, DirName, nullptr, D->getBeginLoc());
10035 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10036 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10037 return Res;
10038}
10039
10040template <typename Derived>
10041StmtResult TreeTransform<Derived>::TransformOMPCancellationPointDirective(
10042 OMPCancellationPointDirective *D) {
10043 DeclarationNameInfo DirName;
10044 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10045 OMPD_cancellation_point, DirName, nullptr, D->getBeginLoc());
10046 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10047 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10048 return Res;
10049}
10050
10051template <typename Derived>
10052StmtResult
10053TreeTransform<Derived>::TransformOMPCancelDirective(OMPCancelDirective *D) {
10054 DeclarationNameInfo DirName;
10055 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10056 OMPD_cancel, DirName, nullptr, D->getBeginLoc());
10057 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10058 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10059 return Res;
10060}
10061
10062template <typename Derived>
10063StmtResult
10064TreeTransform<Derived>::TransformOMPTaskLoopDirective(OMPTaskLoopDirective *D) {
10065 DeclarationNameInfo DirName;
10066 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10067 OMPD_taskloop, DirName, nullptr, D->getBeginLoc());
10068 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10069 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10070 return Res;
10071}
10072
10073template <typename Derived>
10074StmtResult TreeTransform<Derived>::TransformOMPTaskLoopSimdDirective(
10075 OMPTaskLoopSimdDirective *D) {
10076 DeclarationNameInfo DirName;
10077 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10078 OMPD_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10079 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10080 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10081 return Res;
10082}
10083
10084template <typename Derived>
10085StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopDirective(
10086 OMPMasterTaskLoopDirective *D) {
10087 DeclarationNameInfo DirName;
10088 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10089 OMPD_master_taskloop, DirName, nullptr, D->getBeginLoc());
10090 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10091 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10092 return Res;
10093}
10094
10095template <typename Derived>
10096StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopDirective(
10097 OMPMaskedTaskLoopDirective *D) {
10098 DeclarationNameInfo DirName;
10099 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10100 OMPD_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10101 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10102 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10103 return Res;
10104}
10105
10106template <typename Derived>
10107StmtResult TreeTransform<Derived>::TransformOMPMasterTaskLoopSimdDirective(
10108 OMPMasterTaskLoopSimdDirective *D) {
10109 DeclarationNameInfo DirName;
10110 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10111 OMPD_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10112 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10113 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10114 return Res;
10115}
10116
10117template <typename Derived>
10118StmtResult TreeTransform<Derived>::TransformOMPMaskedTaskLoopSimdDirective(
10119 OMPMaskedTaskLoopSimdDirective *D) {
10120 DeclarationNameInfo DirName;
10121 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10122 OMPD_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10123 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10124 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10125 return Res;
10126}
10127
10128template <typename Derived>
10129StmtResult TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopDirective(
10130 OMPParallelMasterTaskLoopDirective *D) {
10131 DeclarationNameInfo DirName;
10132 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10133 OMPD_parallel_master_taskloop, DirName, nullptr, D->getBeginLoc());
10134 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10135 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10136 return Res;
10137}
10138
10139template <typename Derived>
10140StmtResult TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopDirective(
10141 OMPParallelMaskedTaskLoopDirective *D) {
10142 DeclarationNameInfo DirName;
10143 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10144 OMPD_parallel_masked_taskloop, DirName, nullptr, D->getBeginLoc());
10145 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10146 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10147 return Res;
10148}
10149
10150template <typename Derived>
10151StmtResult
10152TreeTransform<Derived>::TransformOMPParallelMasterTaskLoopSimdDirective(
10153 OMPParallelMasterTaskLoopSimdDirective *D) {
10154 DeclarationNameInfo DirName;
10155 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10156 OMPD_parallel_master_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10157 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10158 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10159 return Res;
10160}
10161
10162template <typename Derived>
10163StmtResult
10164TreeTransform<Derived>::TransformOMPParallelMaskedTaskLoopSimdDirective(
10165 OMPParallelMaskedTaskLoopSimdDirective *D) {
10166 DeclarationNameInfo DirName;
10167 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10168 OMPD_parallel_masked_taskloop_simd, DirName, nullptr, D->getBeginLoc());
10169 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10170 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10171 return Res;
10172}
10173
10174template <typename Derived>
10175StmtResult TreeTransform<Derived>::TransformOMPDistributeDirective(
10176 OMPDistributeDirective *D) {
10177 DeclarationNameInfo DirName;
10178 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10179 OMPD_distribute, DirName, nullptr, D->getBeginLoc());
10180 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10181 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10182 return Res;
10183}
10184
10185template <typename Derived>
10186StmtResult TreeTransform<Derived>::TransformOMPDistributeParallelForDirective(
10187 OMPDistributeParallelForDirective *D) {
10188 DeclarationNameInfo DirName;
10189 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10190 OMPD_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10191 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10192 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10193 return Res;
10194}
10195
10196template <typename Derived>
10197StmtResult
10198TreeTransform<Derived>::TransformOMPDistributeParallelForSimdDirective(
10199 OMPDistributeParallelForSimdDirective *D) {
10200 DeclarationNameInfo DirName;
10201 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10202 OMPD_distribute_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10203 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10204 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10205 return Res;
10206}
10207
10208template <typename Derived>
10209StmtResult TreeTransform<Derived>::TransformOMPDistributeSimdDirective(
10210 OMPDistributeSimdDirective *D) {
10211 DeclarationNameInfo DirName;
10212 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10213 OMPD_distribute_simd, DirName, nullptr, D->getBeginLoc());
10214 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10215 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10216 return Res;
10217}
10218
10219template <typename Derived>
10220StmtResult TreeTransform<Derived>::TransformOMPTargetParallelForSimdDirective(
10221 OMPTargetParallelForSimdDirective *D) {
10222 DeclarationNameInfo DirName;
10223 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10224 OMPD_target_parallel_for_simd, DirName, nullptr, D->getBeginLoc());
10225 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10226 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10227 return Res;
10228}
10229
10230template <typename Derived>
10231StmtResult TreeTransform<Derived>::TransformOMPTargetSimdDirective(
10232 OMPTargetSimdDirective *D) {
10233 DeclarationNameInfo DirName;
10234 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10235 OMPD_target_simd, DirName, nullptr, D->getBeginLoc());
10236 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10237 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10238 return Res;
10239}
10240
10241template <typename Derived>
10242StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeDirective(
10243 OMPTeamsDistributeDirective *D) {
10244 DeclarationNameInfo DirName;
10245 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10246 OMPD_teams_distribute, DirName, nullptr, D->getBeginLoc());
10247 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10248 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10249 return Res;
10250}
10251
10252template <typename Derived>
10253StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeSimdDirective(
10254 OMPTeamsDistributeSimdDirective *D) {
10255 DeclarationNameInfo DirName;
10256 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10257 OMPD_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10258 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10259 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10260 return Res;
10261}
10262
10263template <typename Derived>
10264StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForSimdDirective(
10265 OMPTeamsDistributeParallelForSimdDirective *D) {
10266 DeclarationNameInfo DirName;
10267 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10268 OMPD_teams_distribute_parallel_for_simd, DirName, nullptr,
10269 D->getBeginLoc());
10270 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10271 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10272 return Res;
10273}
10274
10275template <typename Derived>
10276StmtResult TreeTransform<Derived>::TransformOMPTeamsDistributeParallelForDirective(
10277 OMPTeamsDistributeParallelForDirective *D) {
10278 DeclarationNameInfo DirName;
10279 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10280 OMPD_teams_distribute_parallel_for, DirName, nullptr, D->getBeginLoc());
10281 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10282 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10283 return Res;
10284}
10285
10286template <typename Derived>
10287StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDirective(
10288 OMPTargetTeamsDirective *D) {
10289 DeclarationNameInfo DirName;
10290 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10291 OMPD_target_teams, DirName, nullptr, D->getBeginLoc());
10292 auto Res = getDerived().TransformOMPExecutableDirective(D);
10293 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10294 return Res;
10295}
10296
10297template <typename Derived>
10298StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsDistributeDirective(
10299 OMPTargetTeamsDistributeDirective *D) {
10300 DeclarationNameInfo DirName;
10301 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10302 OMPD_target_teams_distribute, DirName, nullptr, D->getBeginLoc());
10303 auto Res = getDerived().TransformOMPExecutableDirective(D);
10304 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10305 return Res;
10306}
10307
10308template <typename Derived>
10309StmtResult
10310TreeTransform<Derived>::TransformOMPTargetTeamsDistributeParallelForDirective(
10311 OMPTargetTeamsDistributeParallelForDirective *D) {
10312 DeclarationNameInfo DirName;
10313 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10314 OMPD_target_teams_distribute_parallel_for, DirName, nullptr,
10315 D->getBeginLoc());
10316 auto Res = getDerived().TransformOMPExecutableDirective(D);
10317 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10318 return Res;
10319}
10320
10321template <typename Derived>
10322StmtResult TreeTransform<Derived>::
10323 TransformOMPTargetTeamsDistributeParallelForSimdDirective(
10324 OMPTargetTeamsDistributeParallelForSimdDirective *D) {
10325 DeclarationNameInfo DirName;
10326 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10327 OMPD_target_teams_distribute_parallel_for_simd, DirName, nullptr,
10328 D->getBeginLoc());
10329 auto Res = getDerived().TransformOMPExecutableDirective(D);
10330 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10331 return Res;
10332}
10333
10334template <typename Derived>
10335StmtResult
10336TreeTransform<Derived>::TransformOMPTargetTeamsDistributeSimdDirective(
10337 OMPTargetTeamsDistributeSimdDirective *D) {
10338 DeclarationNameInfo DirName;
10339 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10340 OMPD_target_teams_distribute_simd, DirName, nullptr, D->getBeginLoc());
10341 auto Res = getDerived().TransformOMPExecutableDirective(D);
10342 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10343 return Res;
10344}
10345
10346template <typename Derived>
10347StmtResult
10348TreeTransform<Derived>::TransformOMPInteropDirective(OMPInteropDirective *D) {
10349 DeclarationNameInfo DirName;
10350 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10351 OMPD_interop, DirName, nullptr, D->getBeginLoc());
10352 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10353 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10354 return Res;
10355}
10356
10357template <typename Derived>
10358StmtResult
10359TreeTransform<Derived>::TransformOMPDispatchDirective(OMPDispatchDirective *D) {
10360 DeclarationNameInfo DirName;
10361 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10362 OMPD_dispatch, DirName, nullptr, D->getBeginLoc());
10363 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10364 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10365 return Res;
10366}
10367
10368template <typename Derived>
10369StmtResult
10370TreeTransform<Derived>::TransformOMPMaskedDirective(OMPMaskedDirective *D) {
10371 DeclarationNameInfo DirName;
10372 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10373 OMPD_masked, DirName, nullptr, D->getBeginLoc());
10374 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10375 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10376 return Res;
10377}
10378
10379template <typename Derived>
10380StmtResult TreeTransform<Derived>::TransformOMPGenericLoopDirective(
10381 OMPGenericLoopDirective *D) {
10382 DeclarationNameInfo DirName;
10383 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10384 OMPD_loop, DirName, nullptr, D->getBeginLoc());
10385 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10386 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10387 return Res;
10388}
10389
10390template <typename Derived>
10391StmtResult TreeTransform<Derived>::TransformOMPTeamsGenericLoopDirective(
10392 OMPTeamsGenericLoopDirective *D) {
10393 DeclarationNameInfo DirName;
10394 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10395 OMPD_teams_loop, DirName, nullptr, D->getBeginLoc());
10396 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10397 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10398 return Res;
10399}
10400
10401template <typename Derived>
10402StmtResult TreeTransform<Derived>::TransformOMPTargetTeamsGenericLoopDirective(
10403 OMPTargetTeamsGenericLoopDirective *D) {
10404 DeclarationNameInfo DirName;
10405 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10406 OMPD_target_teams_loop, DirName, nullptr, D->getBeginLoc());
10407 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10408 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10409 return Res;
10410}
10411
10412template <typename Derived>
10413StmtResult TreeTransform<Derived>::TransformOMPParallelGenericLoopDirective(
10414 OMPParallelGenericLoopDirective *D) {
10415 DeclarationNameInfo DirName;
10416 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10417 OMPD_parallel_loop, DirName, nullptr, D->getBeginLoc());
10418 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10419 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10420 return Res;
10421}
10422
10423template <typename Derived>
10424StmtResult
10425TreeTransform<Derived>::TransformOMPTargetParallelGenericLoopDirective(
10426 OMPTargetParallelGenericLoopDirective *D) {
10427 DeclarationNameInfo DirName;
10428 getDerived().getSema().OpenMP().StartOpenMPDSABlock(
10429 OMPD_target_parallel_loop, DirName, nullptr, D->getBeginLoc());
10430 StmtResult Res = getDerived().TransformOMPExecutableDirective(D);
10431 getDerived().getSema().OpenMP().EndOpenMPDSABlock(Res.get());
10432 return Res;
10433}
10434
10435//===----------------------------------------------------------------------===//
10436// OpenMP clause transformation
10437//===----------------------------------------------------------------------===//
10438template <typename Derived>
10439OMPClause *TreeTransform<Derived>::TransformOMPIfClause(OMPIfClause *C) {
10440 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10441 if (Cond.isInvalid())
10442 return nullptr;
10443 return getDerived().RebuildOMPIfClause(
10444 C->getNameModifier(), Cond.get(), C->getBeginLoc(), C->getLParenLoc(),
10445 C->getNameModifierLoc(), C->getColonLoc(), C->getEndLoc());
10446}
10447
10448template <typename Derived>
10449OMPClause *TreeTransform<Derived>::TransformOMPFinalClause(OMPFinalClause *C) {
10450 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10451 if (Cond.isInvalid())
10452 return nullptr;
10453 return getDerived().RebuildOMPFinalClause(Cond.get(), C->getBeginLoc(),
10454 C->getLParenLoc(), C->getEndLoc());
10455}
10456
10457template <typename Derived>
10458OMPClause *
10459TreeTransform<Derived>::TransformOMPNumThreadsClause(OMPNumThreadsClause *C) {
10460 ExprResult NumThreads = getDerived().TransformExpr(C->getNumThreads());
10461 if (NumThreads.isInvalid())
10462 return nullptr;
10463 return getDerived().RebuildOMPNumThreadsClause(
10464 NumThreads.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10465}
10466
10467template <typename Derived>
10468OMPClause *
10469TreeTransform<Derived>::TransformOMPSafelenClause(OMPSafelenClause *C) {
10470 ExprResult E = getDerived().TransformExpr(C->getSafelen());
10471 if (E.isInvalid())
10472 return nullptr;
10473 return getDerived().RebuildOMPSafelenClause(
10474 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10475}
10476
10477template <typename Derived>
10478OMPClause *
10479TreeTransform<Derived>::TransformOMPAllocatorClause(OMPAllocatorClause *C) {
10480 ExprResult E = getDerived().TransformExpr(C->getAllocator());
10481 if (E.isInvalid())
10482 return nullptr;
10483 return getDerived().RebuildOMPAllocatorClause(
10484 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10485}
10486
10487template <typename Derived>
10488OMPClause *
10489TreeTransform<Derived>::TransformOMPSimdlenClause(OMPSimdlenClause *C) {
10490 ExprResult E = getDerived().TransformExpr(C->getSimdlen());
10491 if (E.isInvalid())
10492 return nullptr;
10493 return getDerived().RebuildOMPSimdlenClause(
10494 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10495}
10496
10497template <typename Derived>
10498OMPClause *TreeTransform<Derived>::TransformOMPSizesClause(OMPSizesClause *C) {
10499 SmallVector<Expr *, 4> TransformedSizes;
10500 TransformedSizes.reserve(N: C->getNumSizes());
10501 bool Changed = false;
10502 for (Expr *E : C->getSizesRefs()) {
10503 if (!E) {
10504 TransformedSizes.push_back(Elt: nullptr);
10505 continue;
10506 }
10507
10508 ExprResult T = getDerived().TransformExpr(E);
10509 if (T.isInvalid())
10510 return nullptr;
10511 if (E != T.get())
10512 Changed = true;
10513 TransformedSizes.push_back(Elt: T.get());
10514 }
10515
10516 if (!Changed && !getDerived().AlwaysRebuild())
10517 return C;
10518 return RebuildOMPSizesClause(Sizes: TransformedSizes, StartLoc: C->getBeginLoc(),
10519 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10520}
10521
10522template <typename Derived>
10523OMPClause *
10524TreeTransform<Derived>::TransformOMPPermutationClause(OMPPermutationClause *C) {
10525 SmallVector<Expr *> TransformedArgs;
10526 TransformedArgs.reserve(C->getNumLoops());
10527 bool Changed = false;
10528 for (Expr *E : C->getArgsRefs()) {
10529 if (!E) {
10530 TransformedArgs.push_back(nullptr);
10531 continue;
10532 }
10533
10534 ExprResult T = getDerived().TransformExpr(E);
10535 if (T.isInvalid())
10536 return nullptr;
10537 if (E != T.get())
10538 Changed = true;
10539 TransformedArgs.push_back(T.get());
10540 }
10541
10542 if (!Changed && !getDerived().AlwaysRebuild())
10543 return C;
10544 return RebuildOMPPermutationClause(PermExprs: TransformedArgs, StartLoc: C->getBeginLoc(),
10545 LParenLoc: C->getLParenLoc(), EndLoc: C->getEndLoc());
10546}
10547
10548template <typename Derived>
10549OMPClause *TreeTransform<Derived>::TransformOMPFullClause(OMPFullClause *C) {
10550 if (!getDerived().AlwaysRebuild())
10551 return C;
10552 return RebuildOMPFullClause(StartLoc: C->getBeginLoc(), EndLoc: C->getEndLoc());
10553}
10554
10555template <typename Derived>
10556OMPClause *
10557TreeTransform<Derived>::TransformOMPPartialClause(OMPPartialClause *C) {
10558 ExprResult T = getDerived().TransformExpr(C->getFactor());
10559 if (T.isInvalid())
10560 return nullptr;
10561 Expr *Factor = T.get();
10562 bool Changed = Factor != C->getFactor();
10563
10564 if (!Changed && !getDerived().AlwaysRebuild())
10565 return C;
10566 return RebuildOMPPartialClause(Factor, StartLoc: C->getBeginLoc(), LParenLoc: C->getLParenLoc(),
10567 EndLoc: C->getEndLoc());
10568}
10569
10570template <typename Derived>
10571OMPClause *
10572TreeTransform<Derived>::TransformOMPCollapseClause(OMPCollapseClause *C) {
10573 ExprResult E = getDerived().TransformExpr(C->getNumForLoops());
10574 if (E.isInvalid())
10575 return nullptr;
10576 return getDerived().RebuildOMPCollapseClause(
10577 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10578}
10579
10580template <typename Derived>
10581OMPClause *
10582TreeTransform<Derived>::TransformOMPDefaultClause(OMPDefaultClause *C) {
10583 return getDerived().RebuildOMPDefaultClause(
10584 C->getDefaultKind(), C->getDefaultKindKwLoc(), C->getBeginLoc(),
10585 C->getLParenLoc(), C->getEndLoc());
10586}
10587
10588template <typename Derived>
10589OMPClause *
10590TreeTransform<Derived>::TransformOMPProcBindClause(OMPProcBindClause *C) {
10591 return getDerived().RebuildOMPProcBindClause(
10592 C->getProcBindKind(), C->getProcBindKindKwLoc(), C->getBeginLoc(),
10593 C->getLParenLoc(), C->getEndLoc());
10594}
10595
10596template <typename Derived>
10597OMPClause *
10598TreeTransform<Derived>::TransformOMPScheduleClause(OMPScheduleClause *C) {
10599 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
10600 if (E.isInvalid())
10601 return nullptr;
10602 return getDerived().RebuildOMPScheduleClause(
10603 C->getFirstScheduleModifier(), C->getSecondScheduleModifier(),
10604 C->getScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
10605 C->getFirstScheduleModifierLoc(), C->getSecondScheduleModifierLoc(),
10606 C->getScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
10607}
10608
10609template <typename Derived>
10610OMPClause *
10611TreeTransform<Derived>::TransformOMPOrderedClause(OMPOrderedClause *C) {
10612 ExprResult E;
10613 if (auto *Num = C->getNumForLoops()) {
10614 E = getDerived().TransformExpr(Num);
10615 if (E.isInvalid())
10616 return nullptr;
10617 }
10618 return getDerived().RebuildOMPOrderedClause(C->getBeginLoc(), C->getEndLoc(),
10619 C->getLParenLoc(), E.get());
10620}
10621
10622template <typename Derived>
10623OMPClause *
10624TreeTransform<Derived>::TransformOMPDetachClause(OMPDetachClause *C) {
10625 ExprResult E;
10626 if (Expr *Evt = C->getEventHandler()) {
10627 E = getDerived().TransformExpr(Evt);
10628 if (E.isInvalid())
10629 return nullptr;
10630 }
10631 return getDerived().RebuildOMPDetachClause(E.get(), C->getBeginLoc(),
10632 C->getLParenLoc(), C->getEndLoc());
10633}
10634
10635template <typename Derived>
10636OMPClause *
10637TreeTransform<Derived>::TransformOMPNowaitClause(OMPNowaitClause *C) {
10638 // No need to rebuild this clause, no template-dependent parameters.
10639 return C;
10640}
10641
10642template <typename Derived>
10643OMPClause *
10644TreeTransform<Derived>::TransformOMPUntiedClause(OMPUntiedClause *C) {
10645 // No need to rebuild this clause, no template-dependent parameters.
10646 return C;
10647}
10648
10649template <typename Derived>
10650OMPClause *
10651TreeTransform<Derived>::TransformOMPMergeableClause(OMPMergeableClause *C) {
10652 // No need to rebuild this clause, no template-dependent parameters.
10653 return C;
10654}
10655
10656template <typename Derived>
10657OMPClause *TreeTransform<Derived>::TransformOMPReadClause(OMPReadClause *C) {
10658 // No need to rebuild this clause, no template-dependent parameters.
10659 return C;
10660}
10661
10662template <typename Derived>
10663OMPClause *TreeTransform<Derived>::TransformOMPWriteClause(OMPWriteClause *C) {
10664 // No need to rebuild this clause, no template-dependent parameters.
10665 return C;
10666}
10667
10668template <typename Derived>
10669OMPClause *
10670TreeTransform<Derived>::TransformOMPUpdateClause(OMPUpdateClause *C) {
10671 // No need to rebuild this clause, no template-dependent parameters.
10672 return C;
10673}
10674
10675template <typename Derived>
10676OMPClause *
10677TreeTransform<Derived>::TransformOMPCaptureClause(OMPCaptureClause *C) {
10678 // No need to rebuild this clause, no template-dependent parameters.
10679 return C;
10680}
10681
10682template <typename Derived>
10683OMPClause *
10684TreeTransform<Derived>::TransformOMPCompareClause(OMPCompareClause *C) {
10685 // No need to rebuild this clause, no template-dependent parameters.
10686 return C;
10687}
10688
10689template <typename Derived>
10690OMPClause *TreeTransform<Derived>::TransformOMPFailClause(OMPFailClause *C) {
10691 // No need to rebuild this clause, no template-dependent parameters.
10692 return C;
10693}
10694
10695template <typename Derived>
10696OMPClause *
10697TreeTransform<Derived>::TransformOMPAbsentClause(OMPAbsentClause *C) {
10698 return C;
10699}
10700
10701template <typename Derived>
10702OMPClause *TreeTransform<Derived>::TransformOMPHoldsClause(OMPHoldsClause *C) {
10703 ExprResult E = getDerived().TransformExpr(C->getExpr());
10704 if (E.isInvalid())
10705 return nullptr;
10706 return getDerived().RebuildOMPHoldsClause(E.get(), C->getBeginLoc(),
10707 C->getLParenLoc(), C->getEndLoc());
10708}
10709
10710template <typename Derived>
10711OMPClause *
10712TreeTransform<Derived>::TransformOMPContainsClause(OMPContainsClause *C) {
10713 return C;
10714}
10715
10716template <typename Derived>
10717OMPClause *
10718TreeTransform<Derived>::TransformOMPNoOpenMPClause(OMPNoOpenMPClause *C) {
10719 return C;
10720}
10721template <typename Derived>
10722OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPRoutinesClause(
10723 OMPNoOpenMPRoutinesClause *C) {
10724 return C;
10725}
10726template <typename Derived>
10727OMPClause *TreeTransform<Derived>::TransformOMPNoOpenMPConstructsClause(
10728 OMPNoOpenMPConstructsClause *C) {
10729 return C;
10730}
10731template <typename Derived>
10732OMPClause *TreeTransform<Derived>::TransformOMPNoParallelismClause(
10733 OMPNoParallelismClause *C) {
10734 return C;
10735}
10736
10737template <typename Derived>
10738OMPClause *
10739TreeTransform<Derived>::TransformOMPSeqCstClause(OMPSeqCstClause *C) {
10740 // No need to rebuild this clause, no template-dependent parameters.
10741 return C;
10742}
10743
10744template <typename Derived>
10745OMPClause *
10746TreeTransform<Derived>::TransformOMPAcqRelClause(OMPAcqRelClause *C) {
10747 // No need to rebuild this clause, no template-dependent parameters.
10748 return C;
10749}
10750
10751template <typename Derived>
10752OMPClause *
10753TreeTransform<Derived>::TransformOMPAcquireClause(OMPAcquireClause *C) {
10754 // No need to rebuild this clause, no template-dependent parameters.
10755 return C;
10756}
10757
10758template <typename Derived>
10759OMPClause *
10760TreeTransform<Derived>::TransformOMPReleaseClause(OMPReleaseClause *C) {
10761 // No need to rebuild this clause, no template-dependent parameters.
10762 return C;
10763}
10764
10765template <typename Derived>
10766OMPClause *
10767TreeTransform<Derived>::TransformOMPRelaxedClause(OMPRelaxedClause *C) {
10768 // No need to rebuild this clause, no template-dependent parameters.
10769 return C;
10770}
10771
10772template <typename Derived>
10773OMPClause *TreeTransform<Derived>::TransformOMPWeakClause(OMPWeakClause *C) {
10774 // No need to rebuild this clause, no template-dependent parameters.
10775 return C;
10776}
10777
10778template <typename Derived>
10779OMPClause *
10780TreeTransform<Derived>::TransformOMPThreadsClause(OMPThreadsClause *C) {
10781 // No need to rebuild this clause, no template-dependent parameters.
10782 return C;
10783}
10784
10785template <typename Derived>
10786OMPClause *TreeTransform<Derived>::TransformOMPSIMDClause(OMPSIMDClause *C) {
10787 // No need to rebuild this clause, no template-dependent parameters.
10788 return C;
10789}
10790
10791template <typename Derived>
10792OMPClause *
10793TreeTransform<Derived>::TransformOMPNogroupClause(OMPNogroupClause *C) {
10794 // No need to rebuild this clause, no template-dependent parameters.
10795 return C;
10796}
10797
10798template <typename Derived>
10799OMPClause *TreeTransform<Derived>::TransformOMPInitClause(OMPInitClause *C) {
10800 ExprResult IVR = getDerived().TransformExpr(C->getInteropVar());
10801 if (IVR.isInvalid())
10802 return nullptr;
10803
10804 OMPInteropInfo InteropInfo(C->getIsTarget(), C->getIsTargetSync());
10805 InteropInfo.PreferTypes.reserve(N: C->varlist_size() - 1);
10806 for (Expr *E : llvm::drop_begin(C->varlist())) {
10807 ExprResult ER = getDerived().TransformExpr(cast<Expr>(E));
10808 if (ER.isInvalid())
10809 return nullptr;
10810 InteropInfo.PreferTypes.push_back(ER.get());
10811 }
10812 return getDerived().RebuildOMPInitClause(IVR.get(), InteropInfo,
10813 C->getBeginLoc(), C->getLParenLoc(),
10814 C->getVarLoc(), C->getEndLoc());
10815}
10816
10817template <typename Derived>
10818OMPClause *TreeTransform<Derived>::TransformOMPUseClause(OMPUseClause *C) {
10819 ExprResult ER = getDerived().TransformExpr(C->getInteropVar());
10820 if (ER.isInvalid())
10821 return nullptr;
10822 return getDerived().RebuildOMPUseClause(ER.get(), C->getBeginLoc(),
10823 C->getLParenLoc(), C->getVarLoc(),
10824 C->getEndLoc());
10825}
10826
10827template <typename Derived>
10828OMPClause *
10829TreeTransform<Derived>::TransformOMPDestroyClause(OMPDestroyClause *C) {
10830 ExprResult ER;
10831 if (Expr *IV = C->getInteropVar()) {
10832 ER = getDerived().TransformExpr(IV);
10833 if (ER.isInvalid())
10834 return nullptr;
10835 }
10836 return getDerived().RebuildOMPDestroyClause(ER.get(), C->getBeginLoc(),
10837 C->getLParenLoc(), C->getVarLoc(),
10838 C->getEndLoc());
10839}
10840
10841template <typename Derived>
10842OMPClause *
10843TreeTransform<Derived>::TransformOMPNovariantsClause(OMPNovariantsClause *C) {
10844 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10845 if (Cond.isInvalid())
10846 return nullptr;
10847 return getDerived().RebuildOMPNovariantsClause(
10848 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10849}
10850
10851template <typename Derived>
10852OMPClause *
10853TreeTransform<Derived>::TransformOMPNocontextClause(OMPNocontextClause *C) {
10854 ExprResult Cond = getDerived().TransformExpr(C->getCondition());
10855 if (Cond.isInvalid())
10856 return nullptr;
10857 return getDerived().RebuildOMPNocontextClause(
10858 Cond.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10859}
10860
10861template <typename Derived>
10862OMPClause *
10863TreeTransform<Derived>::TransformOMPFilterClause(OMPFilterClause *C) {
10864 ExprResult ThreadID = getDerived().TransformExpr(C->getThreadID());
10865 if (ThreadID.isInvalid())
10866 return nullptr;
10867 return getDerived().RebuildOMPFilterClause(ThreadID.get(), C->getBeginLoc(),
10868 C->getLParenLoc(), C->getEndLoc());
10869}
10870
10871template <typename Derived>
10872OMPClause *TreeTransform<Derived>::TransformOMPAlignClause(OMPAlignClause *C) {
10873 ExprResult E = getDerived().TransformExpr(C->getAlignment());
10874 if (E.isInvalid())
10875 return nullptr;
10876 return getDerived().RebuildOMPAlignClause(E.get(), C->getBeginLoc(),
10877 C->getLParenLoc(), C->getEndLoc());
10878}
10879
10880template <typename Derived>
10881OMPClause *TreeTransform<Derived>::TransformOMPUnifiedAddressClause(
10882 OMPUnifiedAddressClause *C) {
10883 llvm_unreachable("unified_address clause cannot appear in dependent context");
10884}
10885
10886template <typename Derived>
10887OMPClause *TreeTransform<Derived>::TransformOMPUnifiedSharedMemoryClause(
10888 OMPUnifiedSharedMemoryClause *C) {
10889 llvm_unreachable(
10890 "unified_shared_memory clause cannot appear in dependent context");
10891}
10892
10893template <typename Derived>
10894OMPClause *TreeTransform<Derived>::TransformOMPReverseOffloadClause(
10895 OMPReverseOffloadClause *C) {
10896 llvm_unreachable("reverse_offload clause cannot appear in dependent context");
10897}
10898
10899template <typename Derived>
10900OMPClause *TreeTransform<Derived>::TransformOMPDynamicAllocatorsClause(
10901 OMPDynamicAllocatorsClause *C) {
10902 llvm_unreachable(
10903 "dynamic_allocators clause cannot appear in dependent context");
10904}
10905
10906template <typename Derived>
10907OMPClause *TreeTransform<Derived>::TransformOMPAtomicDefaultMemOrderClause(
10908 OMPAtomicDefaultMemOrderClause *C) {
10909 llvm_unreachable(
10910 "atomic_default_mem_order clause cannot appear in dependent context");
10911}
10912
10913template <typename Derived>
10914OMPClause *
10915TreeTransform<Derived>::TransformOMPSelfMapsClause(OMPSelfMapsClause *C) {
10916 llvm_unreachable("self_maps clause cannot appear in dependent context");
10917}
10918
10919template <typename Derived>
10920OMPClause *TreeTransform<Derived>::TransformOMPAtClause(OMPAtClause *C) {
10921 return getDerived().RebuildOMPAtClause(C->getAtKind(), C->getAtKindKwLoc(),
10922 C->getBeginLoc(), C->getLParenLoc(),
10923 C->getEndLoc());
10924}
10925
10926template <typename Derived>
10927OMPClause *
10928TreeTransform<Derived>::TransformOMPSeverityClause(OMPSeverityClause *C) {
10929 return getDerived().RebuildOMPSeverityClause(
10930 C->getSeverityKind(), C->getSeverityKindKwLoc(), C->getBeginLoc(),
10931 C->getLParenLoc(), C->getEndLoc());
10932}
10933
10934template <typename Derived>
10935OMPClause *
10936TreeTransform<Derived>::TransformOMPMessageClause(OMPMessageClause *C) {
10937 ExprResult E = getDerived().TransformExpr(C->getMessageString());
10938 if (E.isInvalid())
10939 return nullptr;
10940 return getDerived().RebuildOMPMessageClause(
10941 C->getMessageString(), C->getBeginLoc(), C->getLParenLoc(),
10942 C->getEndLoc());
10943}
10944
10945template <typename Derived>
10946OMPClause *
10947TreeTransform<Derived>::TransformOMPPrivateClause(OMPPrivateClause *C) {
10948 llvm::SmallVector<Expr *, 16> Vars;
10949 Vars.reserve(C->varlist_size());
10950 for (auto *VE : C->varlist()) {
10951 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10952 if (EVar.isInvalid())
10953 return nullptr;
10954 Vars.push_back(EVar.get());
10955 }
10956 return getDerived().RebuildOMPPrivateClause(
10957 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10958}
10959
10960template <typename Derived>
10961OMPClause *TreeTransform<Derived>::TransformOMPFirstprivateClause(
10962 OMPFirstprivateClause *C) {
10963 llvm::SmallVector<Expr *, 16> Vars;
10964 Vars.reserve(C->varlist_size());
10965 for (auto *VE : C->varlist()) {
10966 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10967 if (EVar.isInvalid())
10968 return nullptr;
10969 Vars.push_back(EVar.get());
10970 }
10971 return getDerived().RebuildOMPFirstprivateClause(
10972 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
10973}
10974
10975template <typename Derived>
10976OMPClause *
10977TreeTransform<Derived>::TransformOMPLastprivateClause(OMPLastprivateClause *C) {
10978 llvm::SmallVector<Expr *, 16> Vars;
10979 Vars.reserve(C->varlist_size());
10980 for (auto *VE : C->varlist()) {
10981 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10982 if (EVar.isInvalid())
10983 return nullptr;
10984 Vars.push_back(EVar.get());
10985 }
10986 return getDerived().RebuildOMPLastprivateClause(
10987 Vars, C->getKind(), C->getKindLoc(), C->getColonLoc(), C->getBeginLoc(),
10988 C->getLParenLoc(), C->getEndLoc());
10989}
10990
10991template <typename Derived>
10992OMPClause *
10993TreeTransform<Derived>::TransformOMPSharedClause(OMPSharedClause *C) {
10994 llvm::SmallVector<Expr *, 16> Vars;
10995 Vars.reserve(C->varlist_size());
10996 for (auto *VE : C->varlist()) {
10997 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
10998 if (EVar.isInvalid())
10999 return nullptr;
11000 Vars.push_back(EVar.get());
11001 }
11002 return getDerived().RebuildOMPSharedClause(Vars, C->getBeginLoc(),
11003 C->getLParenLoc(), C->getEndLoc());
11004}
11005
11006template <typename Derived>
11007OMPClause *
11008TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
11009 llvm::SmallVector<Expr *, 16> Vars;
11010 Vars.reserve(C->varlist_size());
11011 for (auto *VE : C->varlist()) {
11012 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11013 if (EVar.isInvalid())
11014 return nullptr;
11015 Vars.push_back(EVar.get());
11016 }
11017 CXXScopeSpec ReductionIdScopeSpec;
11018 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11019
11020 DeclarationNameInfo NameInfo = C->getNameInfo();
11021 if (NameInfo.getName()) {
11022 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11023 if (!NameInfo.getName())
11024 return nullptr;
11025 }
11026 // Build a list of all UDR decls with the same names ranged by the Scopes.
11027 // The Scope boundary is a duplication of the previous decl.
11028 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11029 for (auto *E : C->reduction_ops()) {
11030 // Transform all the decls.
11031 if (E) {
11032 auto *ULE = cast<UnresolvedLookupExpr>(E);
11033 UnresolvedSet<8> Decls;
11034 for (auto *D : ULE->decls()) {
11035 NamedDecl *InstD =
11036 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11037 Decls.addDecl(InstD, InstD->getAccess());
11038 }
11039 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11040 SemaRef.Context, /*NamingClass=*/nullptr,
11041 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11042 /*ADL=*/true, Decls.begin(), Decls.end(),
11043 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11044 } else
11045 UnresolvedReductions.push_back(nullptr);
11046 }
11047 return getDerived().RebuildOMPReductionClause(
11048 Vars, C->getModifier(), C->getOriginalSharingModifier(), C->getBeginLoc(),
11049 C->getLParenLoc(), C->getModifierLoc(), C->getColonLoc(), C->getEndLoc(),
11050 ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11051}
11052
11053template <typename Derived>
11054OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
11055 OMPTaskReductionClause *C) {
11056 llvm::SmallVector<Expr *, 16> Vars;
11057 Vars.reserve(C->varlist_size());
11058 for (auto *VE : C->varlist()) {
11059 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11060 if (EVar.isInvalid())
11061 return nullptr;
11062 Vars.push_back(EVar.get());
11063 }
11064 CXXScopeSpec ReductionIdScopeSpec;
11065 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11066
11067 DeclarationNameInfo NameInfo = C->getNameInfo();
11068 if (NameInfo.getName()) {
11069 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11070 if (!NameInfo.getName())
11071 return nullptr;
11072 }
11073 // Build a list of all UDR decls with the same names ranged by the Scopes.
11074 // The Scope boundary is a duplication of the previous decl.
11075 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11076 for (auto *E : C->reduction_ops()) {
11077 // Transform all the decls.
11078 if (E) {
11079 auto *ULE = cast<UnresolvedLookupExpr>(E);
11080 UnresolvedSet<8> Decls;
11081 for (auto *D : ULE->decls()) {
11082 NamedDecl *InstD =
11083 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11084 Decls.addDecl(InstD, InstD->getAccess());
11085 }
11086 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11087 SemaRef.Context, /*NamingClass=*/nullptr,
11088 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11089 /*ADL=*/true, Decls.begin(), Decls.end(),
11090 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11091 } else
11092 UnresolvedReductions.push_back(nullptr);
11093 }
11094 return getDerived().RebuildOMPTaskReductionClause(
11095 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11096 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11097}
11098
11099template <typename Derived>
11100OMPClause *
11101TreeTransform<Derived>::TransformOMPInReductionClause(OMPInReductionClause *C) {
11102 llvm::SmallVector<Expr *, 16> Vars;
11103 Vars.reserve(C->varlist_size());
11104 for (auto *VE : C->varlist()) {
11105 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11106 if (EVar.isInvalid())
11107 return nullptr;
11108 Vars.push_back(EVar.get());
11109 }
11110 CXXScopeSpec ReductionIdScopeSpec;
11111 ReductionIdScopeSpec.Adopt(Other: C->getQualifierLoc());
11112
11113 DeclarationNameInfo NameInfo = C->getNameInfo();
11114 if (NameInfo.getName()) {
11115 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
11116 if (!NameInfo.getName())
11117 return nullptr;
11118 }
11119 // Build a list of all UDR decls with the same names ranged by the Scopes.
11120 // The Scope boundary is a duplication of the previous decl.
11121 llvm::SmallVector<Expr *, 16> UnresolvedReductions;
11122 for (auto *E : C->reduction_ops()) {
11123 // Transform all the decls.
11124 if (E) {
11125 auto *ULE = cast<UnresolvedLookupExpr>(E);
11126 UnresolvedSet<8> Decls;
11127 for (auto *D : ULE->decls()) {
11128 NamedDecl *InstD =
11129 cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
11130 Decls.addDecl(InstD, InstD->getAccess());
11131 }
11132 UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
11133 SemaRef.Context, /*NamingClass=*/nullptr,
11134 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
11135 /*ADL=*/true, Decls.begin(), Decls.end(),
11136 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11137 } else
11138 UnresolvedReductions.push_back(nullptr);
11139 }
11140 return getDerived().RebuildOMPInReductionClause(
11141 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(),
11142 C->getEndLoc(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
11143}
11144
11145template <typename Derived>
11146OMPClause *
11147TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
11148 llvm::SmallVector<Expr *, 16> Vars;
11149 Vars.reserve(C->varlist_size());
11150 for (auto *VE : C->varlist()) {
11151 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11152 if (EVar.isInvalid())
11153 return nullptr;
11154 Vars.push_back(EVar.get());
11155 }
11156 ExprResult Step = getDerived().TransformExpr(C->getStep());
11157 if (Step.isInvalid())
11158 return nullptr;
11159 return getDerived().RebuildOMPLinearClause(
11160 Vars, Step.get(), C->getBeginLoc(), C->getLParenLoc(), C->getModifier(),
11161 C->getModifierLoc(), C->getColonLoc(), C->getStepModifierLoc(),
11162 C->getEndLoc());
11163}
11164
11165template <typename Derived>
11166OMPClause *
11167TreeTransform<Derived>::TransformOMPAlignedClause(OMPAlignedClause *C) {
11168 llvm::SmallVector<Expr *, 16> Vars;
11169 Vars.reserve(C->varlist_size());
11170 for (auto *VE : C->varlist()) {
11171 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11172 if (EVar.isInvalid())
11173 return nullptr;
11174 Vars.push_back(EVar.get());
11175 }
11176 ExprResult Alignment = getDerived().TransformExpr(C->getAlignment());
11177 if (Alignment.isInvalid())
11178 return nullptr;
11179 return getDerived().RebuildOMPAlignedClause(
11180 Vars, Alignment.get(), C->getBeginLoc(), C->getLParenLoc(),
11181 C->getColonLoc(), C->getEndLoc());
11182}
11183
11184template <typename Derived>
11185OMPClause *
11186TreeTransform<Derived>::TransformOMPCopyinClause(OMPCopyinClause *C) {
11187 llvm::SmallVector<Expr *, 16> Vars;
11188 Vars.reserve(C->varlist_size());
11189 for (auto *VE : C->varlist()) {
11190 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11191 if (EVar.isInvalid())
11192 return nullptr;
11193 Vars.push_back(EVar.get());
11194 }
11195 return getDerived().RebuildOMPCopyinClause(Vars, C->getBeginLoc(),
11196 C->getLParenLoc(), C->getEndLoc());
11197}
11198
11199template <typename Derived>
11200OMPClause *
11201TreeTransform<Derived>::TransformOMPCopyprivateClause(OMPCopyprivateClause *C) {
11202 llvm::SmallVector<Expr *, 16> Vars;
11203 Vars.reserve(C->varlist_size());
11204 for (auto *VE : C->varlist()) {
11205 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11206 if (EVar.isInvalid())
11207 return nullptr;
11208 Vars.push_back(EVar.get());
11209 }
11210 return getDerived().RebuildOMPCopyprivateClause(
11211 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11212}
11213
11214template <typename Derived>
11215OMPClause *TreeTransform<Derived>::TransformOMPFlushClause(OMPFlushClause *C) {
11216 llvm::SmallVector<Expr *, 16> Vars;
11217 Vars.reserve(C->varlist_size());
11218 for (auto *VE : C->varlist()) {
11219 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11220 if (EVar.isInvalid())
11221 return nullptr;
11222 Vars.push_back(EVar.get());
11223 }
11224 return getDerived().RebuildOMPFlushClause(Vars, C->getBeginLoc(),
11225 C->getLParenLoc(), C->getEndLoc());
11226}
11227
11228template <typename Derived>
11229OMPClause *
11230TreeTransform<Derived>::TransformOMPDepobjClause(OMPDepobjClause *C) {
11231 ExprResult E = getDerived().TransformExpr(C->getDepobj());
11232 if (E.isInvalid())
11233 return nullptr;
11234 return getDerived().RebuildOMPDepobjClause(E.get(), C->getBeginLoc(),
11235 C->getLParenLoc(), C->getEndLoc());
11236}
11237
11238template <typename Derived>
11239OMPClause *
11240TreeTransform<Derived>::TransformOMPDependClause(OMPDependClause *C) {
11241 llvm::SmallVector<Expr *, 16> Vars;
11242 Expr *DepModifier = C->getModifier();
11243 if (DepModifier) {
11244 ExprResult DepModRes = getDerived().TransformExpr(DepModifier);
11245 if (DepModRes.isInvalid())
11246 return nullptr;
11247 DepModifier = DepModRes.get();
11248 }
11249 Vars.reserve(C->varlist_size());
11250 for (auto *VE : C->varlist()) {
11251 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11252 if (EVar.isInvalid())
11253 return nullptr;
11254 Vars.push_back(EVar.get());
11255 }
11256 return getDerived().RebuildOMPDependClause(
11257 {C->getDependencyKind(), C->getDependencyLoc(), C->getColonLoc(),
11258 C->getOmpAllMemoryLoc()},
11259 DepModifier, Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11260}
11261
11262template <typename Derived>
11263OMPClause *
11264TreeTransform<Derived>::TransformOMPDeviceClause(OMPDeviceClause *C) {
11265 ExprResult E = getDerived().TransformExpr(C->getDevice());
11266 if (E.isInvalid())
11267 return nullptr;
11268 return getDerived().RebuildOMPDeviceClause(
11269 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11270 C->getModifierLoc(), C->getEndLoc());
11271}
11272
11273template <typename Derived, class T>
11274bool transformOMPMappableExprListClause(
11275 TreeTransform<Derived> &TT, OMPMappableExprListClause<T> *C,
11276 llvm::SmallVectorImpl<Expr *> &Vars, CXXScopeSpec &MapperIdScopeSpec,
11277 DeclarationNameInfo &MapperIdInfo,
11278 llvm::SmallVectorImpl<Expr *> &UnresolvedMappers) {
11279 // Transform expressions in the list.
11280 Vars.reserve(N: C->varlist_size());
11281 for (auto *VE : C->varlist()) {
11282 ExprResult EVar = TT.getDerived().TransformExpr(cast<Expr>(VE));
11283 if (EVar.isInvalid())
11284 return true;
11285 Vars.push_back(Elt: EVar.get());
11286 }
11287 // Transform mapper scope specifier and identifier.
11288 NestedNameSpecifierLoc QualifierLoc;
11289 if (C->getMapperQualifierLoc()) {
11290 QualifierLoc = TT.getDerived().TransformNestedNameSpecifierLoc(
11291 C->getMapperQualifierLoc());
11292 if (!QualifierLoc)
11293 return true;
11294 }
11295 MapperIdScopeSpec.Adopt(Other: QualifierLoc);
11296 MapperIdInfo = C->getMapperIdInfo();
11297 if (MapperIdInfo.getName()) {
11298 MapperIdInfo = TT.getDerived().TransformDeclarationNameInfo(MapperIdInfo);
11299 if (!MapperIdInfo.getName())
11300 return true;
11301 }
11302 // Build a list of all candidate OMPDeclareMapperDecls, which is provided by
11303 // the previous user-defined mapper lookup in dependent environment.
11304 for (auto *E : C->mapperlists()) {
11305 // Transform all the decls.
11306 if (E) {
11307 auto *ULE = cast<UnresolvedLookupExpr>(E);
11308 UnresolvedSet<8> Decls;
11309 for (auto *D : ULE->decls()) {
11310 NamedDecl *InstD =
11311 cast<NamedDecl>(TT.getDerived().TransformDecl(E->getExprLoc(), D));
11312 Decls.addDecl(InstD, InstD->getAccess());
11313 }
11314 UnresolvedMappers.push_back(Elt: UnresolvedLookupExpr::Create(
11315 TT.getSema().Context, /*NamingClass=*/nullptr,
11316 MapperIdScopeSpec.getWithLocInContext(Context&: TT.getSema().Context),
11317 MapperIdInfo, /*ADL=*/true, Decls.begin(), Decls.end(),
11318 /*KnownDependent=*/false, /*KnownInstantiationDependent=*/false));
11319 } else {
11320 UnresolvedMappers.push_back(Elt: nullptr);
11321 }
11322 }
11323 return false;
11324}
11325
11326template <typename Derived>
11327OMPClause *TreeTransform<Derived>::TransformOMPMapClause(OMPMapClause *C) {
11328 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11329 llvm::SmallVector<Expr *, 16> Vars;
11330 Expr *IteratorModifier = C->getIteratorModifier();
11331 if (IteratorModifier) {
11332 ExprResult MapModRes = getDerived().TransformExpr(IteratorModifier);
11333 if (MapModRes.isInvalid())
11334 return nullptr;
11335 IteratorModifier = MapModRes.get();
11336 }
11337 CXXScopeSpec MapperIdScopeSpec;
11338 DeclarationNameInfo MapperIdInfo;
11339 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11340 if (transformOMPMappableExprListClause<Derived, OMPMapClause>(
11341 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11342 return nullptr;
11343 return getDerived().RebuildOMPMapClause(
11344 IteratorModifier, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
11345 MapperIdScopeSpec, MapperIdInfo, C->getMapType(), C->isImplicitMapType(),
11346 C->getMapLoc(), C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11347}
11348
11349template <typename Derived>
11350OMPClause *
11351TreeTransform<Derived>::TransformOMPAllocateClause(OMPAllocateClause *C) {
11352 Expr *Allocator = C->getAllocator();
11353 if (Allocator) {
11354 ExprResult AllocatorRes = getDerived().TransformExpr(Allocator);
11355 if (AllocatorRes.isInvalid())
11356 return nullptr;
11357 Allocator = AllocatorRes.get();
11358 }
11359 Expr *Alignment = C->getAlignment();
11360 if (Alignment) {
11361 ExprResult AlignmentRes = getDerived().TransformExpr(Alignment);
11362 if (AlignmentRes.isInvalid())
11363 return nullptr;
11364 Alignment = AlignmentRes.get();
11365 }
11366 llvm::SmallVector<Expr *, 16> Vars;
11367 Vars.reserve(C->varlist_size());
11368 for (auto *VE : C->varlist()) {
11369 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11370 if (EVar.isInvalid())
11371 return nullptr;
11372 Vars.push_back(EVar.get());
11373 }
11374 return getDerived().RebuildOMPAllocateClause(
11375 Allocator, Alignment, C->getFirstAllocateModifier(),
11376 C->getFirstAllocateModifierLoc(), C->getSecondAllocateModifier(),
11377 C->getSecondAllocateModifierLoc(), Vars, C->getBeginLoc(),
11378 C->getLParenLoc(), C->getColonLoc(), C->getEndLoc());
11379}
11380
11381template <typename Derived>
11382OMPClause *
11383TreeTransform<Derived>::TransformOMPNumTeamsClause(OMPNumTeamsClause *C) {
11384 llvm::SmallVector<Expr *, 3> Vars;
11385 Vars.reserve(C->varlist_size());
11386 for (auto *VE : C->varlist()) {
11387 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11388 if (EVar.isInvalid())
11389 return nullptr;
11390 Vars.push_back(EVar.get());
11391 }
11392 return getDerived().RebuildOMPNumTeamsClause(
11393 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11394}
11395
11396template <typename Derived>
11397OMPClause *
11398TreeTransform<Derived>::TransformOMPThreadLimitClause(OMPThreadLimitClause *C) {
11399 llvm::SmallVector<Expr *, 3> Vars;
11400 Vars.reserve(C->varlist_size());
11401 for (auto *VE : C->varlist()) {
11402 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11403 if (EVar.isInvalid())
11404 return nullptr;
11405 Vars.push_back(EVar.get());
11406 }
11407 return getDerived().RebuildOMPThreadLimitClause(
11408 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11409}
11410
11411template <typename Derived>
11412OMPClause *
11413TreeTransform<Derived>::TransformOMPPriorityClause(OMPPriorityClause *C) {
11414 ExprResult E = getDerived().TransformExpr(C->getPriority());
11415 if (E.isInvalid())
11416 return nullptr;
11417 return getDerived().RebuildOMPPriorityClause(
11418 E.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11419}
11420
11421template <typename Derived>
11422OMPClause *
11423TreeTransform<Derived>::TransformOMPGrainsizeClause(OMPGrainsizeClause *C) {
11424 ExprResult E = getDerived().TransformExpr(C->getGrainsize());
11425 if (E.isInvalid())
11426 return nullptr;
11427 return getDerived().RebuildOMPGrainsizeClause(
11428 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11429 C->getModifierLoc(), C->getEndLoc());
11430}
11431
11432template <typename Derived>
11433OMPClause *
11434TreeTransform<Derived>::TransformOMPNumTasksClause(OMPNumTasksClause *C) {
11435 ExprResult E = getDerived().TransformExpr(C->getNumTasks());
11436 if (E.isInvalid())
11437 return nullptr;
11438 return getDerived().RebuildOMPNumTasksClause(
11439 C->getModifier(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11440 C->getModifierLoc(), C->getEndLoc());
11441}
11442
11443template <typename Derived>
11444OMPClause *TreeTransform<Derived>::TransformOMPHintClause(OMPHintClause *C) {
11445 ExprResult E = getDerived().TransformExpr(C->getHint());
11446 if (E.isInvalid())
11447 return nullptr;
11448 return getDerived().RebuildOMPHintClause(E.get(), C->getBeginLoc(),
11449 C->getLParenLoc(), C->getEndLoc());
11450}
11451
11452template <typename Derived>
11453OMPClause *TreeTransform<Derived>::TransformOMPDistScheduleClause(
11454 OMPDistScheduleClause *C) {
11455 ExprResult E = getDerived().TransformExpr(C->getChunkSize());
11456 if (E.isInvalid())
11457 return nullptr;
11458 return getDerived().RebuildOMPDistScheduleClause(
11459 C->getDistScheduleKind(), E.get(), C->getBeginLoc(), C->getLParenLoc(),
11460 C->getDistScheduleKindLoc(), C->getCommaLoc(), C->getEndLoc());
11461}
11462
11463template <typename Derived>
11464OMPClause *
11465TreeTransform<Derived>::TransformOMPDefaultmapClause(OMPDefaultmapClause *C) {
11466 // Rebuild Defaultmap Clause since we need to invoke the checking of
11467 // defaultmap(none:variable-category) after template initialization.
11468 return getDerived().RebuildOMPDefaultmapClause(C->getDefaultmapModifier(),
11469 C->getDefaultmapKind(),
11470 C->getBeginLoc(),
11471 C->getLParenLoc(),
11472 C->getDefaultmapModifierLoc(),
11473 C->getDefaultmapKindLoc(),
11474 C->getEndLoc());
11475}
11476
11477template <typename Derived>
11478OMPClause *TreeTransform<Derived>::TransformOMPToClause(OMPToClause *C) {
11479 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11480 llvm::SmallVector<Expr *, 16> Vars;
11481 CXXScopeSpec MapperIdScopeSpec;
11482 DeclarationNameInfo MapperIdInfo;
11483 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11484 if (transformOMPMappableExprListClause<Derived, OMPToClause>(
11485 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11486 return nullptr;
11487 return getDerived().RebuildOMPToClause(
11488 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11489 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11490}
11491
11492template <typename Derived>
11493OMPClause *TreeTransform<Derived>::TransformOMPFromClause(OMPFromClause *C) {
11494 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11495 llvm::SmallVector<Expr *, 16> Vars;
11496 CXXScopeSpec MapperIdScopeSpec;
11497 DeclarationNameInfo MapperIdInfo;
11498 llvm::SmallVector<Expr *, 16> UnresolvedMappers;
11499 if (transformOMPMappableExprListClause<Derived, OMPFromClause>(
11500 *this, C, Vars, MapperIdScopeSpec, MapperIdInfo, UnresolvedMappers))
11501 return nullptr;
11502 return getDerived().RebuildOMPFromClause(
11503 C->getMotionModifiers(), C->getMotionModifiersLoc(), MapperIdScopeSpec,
11504 MapperIdInfo, C->getColonLoc(), Vars, Locs, UnresolvedMappers);
11505}
11506
11507template <typename Derived>
11508OMPClause *TreeTransform<Derived>::TransformOMPUseDevicePtrClause(
11509 OMPUseDevicePtrClause *C) {
11510 llvm::SmallVector<Expr *, 16> Vars;
11511 Vars.reserve(C->varlist_size());
11512 for (auto *VE : C->varlist()) {
11513 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11514 if (EVar.isInvalid())
11515 return nullptr;
11516 Vars.push_back(EVar.get());
11517 }
11518 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11519 return getDerived().RebuildOMPUseDevicePtrClause(Vars, Locs);
11520}
11521
11522template <typename Derived>
11523OMPClause *TreeTransform<Derived>::TransformOMPUseDeviceAddrClause(
11524 OMPUseDeviceAddrClause *C) {
11525 llvm::SmallVector<Expr *, 16> Vars;
11526 Vars.reserve(C->varlist_size());
11527 for (auto *VE : C->varlist()) {
11528 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11529 if (EVar.isInvalid())
11530 return nullptr;
11531 Vars.push_back(EVar.get());
11532 }
11533 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11534 return getDerived().RebuildOMPUseDeviceAddrClause(Vars, Locs);
11535}
11536
11537template <typename Derived>
11538OMPClause *
11539TreeTransform<Derived>::TransformOMPIsDevicePtrClause(OMPIsDevicePtrClause *C) {
11540 llvm::SmallVector<Expr *, 16> Vars;
11541 Vars.reserve(C->varlist_size());
11542 for (auto *VE : C->varlist()) {
11543 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11544 if (EVar.isInvalid())
11545 return nullptr;
11546 Vars.push_back(EVar.get());
11547 }
11548 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11549 return getDerived().RebuildOMPIsDevicePtrClause(Vars, Locs);
11550}
11551
11552template <typename Derived>
11553OMPClause *TreeTransform<Derived>::TransformOMPHasDeviceAddrClause(
11554 OMPHasDeviceAddrClause *C) {
11555 llvm::SmallVector<Expr *, 16> Vars;
11556 Vars.reserve(C->varlist_size());
11557 for (auto *VE : C->varlist()) {
11558 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11559 if (EVar.isInvalid())
11560 return nullptr;
11561 Vars.push_back(EVar.get());
11562 }
11563 OMPVarListLocTy Locs(C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11564 return getDerived().RebuildOMPHasDeviceAddrClause(Vars, Locs);
11565}
11566
11567template <typename Derived>
11568OMPClause *
11569TreeTransform<Derived>::TransformOMPNontemporalClause(OMPNontemporalClause *C) {
11570 llvm::SmallVector<Expr *, 16> Vars;
11571 Vars.reserve(C->varlist_size());
11572 for (auto *VE : C->varlist()) {
11573 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11574 if (EVar.isInvalid())
11575 return nullptr;
11576 Vars.push_back(EVar.get());
11577 }
11578 return getDerived().RebuildOMPNontemporalClause(
11579 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11580}
11581
11582template <typename Derived>
11583OMPClause *
11584TreeTransform<Derived>::TransformOMPInclusiveClause(OMPInclusiveClause *C) {
11585 llvm::SmallVector<Expr *, 16> Vars;
11586 Vars.reserve(C->varlist_size());
11587 for (auto *VE : C->varlist()) {
11588 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11589 if (EVar.isInvalid())
11590 return nullptr;
11591 Vars.push_back(EVar.get());
11592 }
11593 return getDerived().RebuildOMPInclusiveClause(
11594 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11595}
11596
11597template <typename Derived>
11598OMPClause *
11599TreeTransform<Derived>::TransformOMPExclusiveClause(OMPExclusiveClause *C) {
11600 llvm::SmallVector<Expr *, 16> Vars;
11601 Vars.reserve(C->varlist_size());
11602 for (auto *VE : C->varlist()) {
11603 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11604 if (EVar.isInvalid())
11605 return nullptr;
11606 Vars.push_back(EVar.get());
11607 }
11608 return getDerived().RebuildOMPExclusiveClause(
11609 Vars, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11610}
11611
11612template <typename Derived>
11613OMPClause *TreeTransform<Derived>::TransformOMPUsesAllocatorsClause(
11614 OMPUsesAllocatorsClause *C) {
11615 SmallVector<SemaOpenMP::UsesAllocatorsData, 16> Data;
11616 Data.reserve(C->getNumberOfAllocators());
11617 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
11618 OMPUsesAllocatorsClause::Data D = C->getAllocatorData(I);
11619 ExprResult Allocator = getDerived().TransformExpr(D.Allocator);
11620 if (Allocator.isInvalid())
11621 continue;
11622 ExprResult AllocatorTraits;
11623 if (Expr *AT = D.AllocatorTraits) {
11624 AllocatorTraits = getDerived().TransformExpr(AT);
11625 if (AllocatorTraits.isInvalid())
11626 continue;
11627 }
11628 SemaOpenMP::UsesAllocatorsData &NewD = Data.emplace_back();
11629 NewD.Allocator = Allocator.get();
11630 NewD.AllocatorTraits = AllocatorTraits.get();
11631 NewD.LParenLoc = D.LParenLoc;
11632 NewD.RParenLoc = D.RParenLoc;
11633 }
11634 return getDerived().RebuildOMPUsesAllocatorsClause(
11635 Data, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11636}
11637
11638template <typename Derived>
11639OMPClause *
11640TreeTransform<Derived>::TransformOMPAffinityClause(OMPAffinityClause *C) {
11641 SmallVector<Expr *, 4> Locators;
11642 Locators.reserve(N: C->varlist_size());
11643 ExprResult ModifierRes;
11644 if (Expr *Modifier = C->getModifier()) {
11645 ModifierRes = getDerived().TransformExpr(Modifier);
11646 if (ModifierRes.isInvalid())
11647 return nullptr;
11648 }
11649 for (Expr *E : C->varlist()) {
11650 ExprResult Locator = getDerived().TransformExpr(E);
11651 if (Locator.isInvalid())
11652 continue;
11653 Locators.push_back(Locator.get());
11654 }
11655 return getDerived().RebuildOMPAffinityClause(
11656 C->getBeginLoc(), C->getLParenLoc(), C->getColonLoc(), C->getEndLoc(),
11657 ModifierRes.get(), Locators);
11658}
11659
11660template <typename Derived>
11661OMPClause *TreeTransform<Derived>::TransformOMPOrderClause(OMPOrderClause *C) {
11662 return getDerived().RebuildOMPOrderClause(
11663 C->getKind(), C->getKindKwLoc(), C->getBeginLoc(), C->getLParenLoc(),
11664 C->getEndLoc(), C->getModifier(), C->getModifierKwLoc());
11665}
11666
11667template <typename Derived>
11668OMPClause *TreeTransform<Derived>::TransformOMPBindClause(OMPBindClause *C) {
11669 return getDerived().RebuildOMPBindClause(
11670 C->getBindKind(), C->getBindKindLoc(), C->getBeginLoc(),
11671 C->getLParenLoc(), C->getEndLoc());
11672}
11673
11674template <typename Derived>
11675OMPClause *TreeTransform<Derived>::TransformOMPXDynCGroupMemClause(
11676 OMPXDynCGroupMemClause *C) {
11677 ExprResult Size = getDerived().TransformExpr(C->getSize());
11678 if (Size.isInvalid())
11679 return nullptr;
11680 return getDerived().RebuildOMPXDynCGroupMemClause(
11681 Size.get(), C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11682}
11683
11684template <typename Derived>
11685OMPClause *
11686TreeTransform<Derived>::TransformOMPDoacrossClause(OMPDoacrossClause *C) {
11687 llvm::SmallVector<Expr *, 16> Vars;
11688 Vars.reserve(C->varlist_size());
11689 for (auto *VE : C->varlist()) {
11690 ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
11691 if (EVar.isInvalid())
11692 return nullptr;
11693 Vars.push_back(EVar.get());
11694 }
11695 return getDerived().RebuildOMPDoacrossClause(
11696 C->getDependenceType(), C->getDependenceLoc(), C->getColonLoc(), Vars,
11697 C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11698}
11699
11700template <typename Derived>
11701OMPClause *
11702TreeTransform<Derived>::TransformOMPXAttributeClause(OMPXAttributeClause *C) {
11703 SmallVector<const Attr *> NewAttrs;
11704 for (auto *A : C->getAttrs())
11705 NewAttrs.push_back(getDerived().TransformAttr(A));
11706 return getDerived().RebuildOMPXAttributeClause(
11707 NewAttrs, C->getBeginLoc(), C->getLParenLoc(), C->getEndLoc());
11708}
11709
11710template <typename Derived>
11711OMPClause *TreeTransform<Derived>::TransformOMPXBareClause(OMPXBareClause *C) {
11712 return getDerived().RebuildOMPXBareClause(C->getBeginLoc(), C->getEndLoc());
11713}
11714
11715//===----------------------------------------------------------------------===//
11716// OpenACC transformation
11717//===----------------------------------------------------------------------===//
11718namespace {
11719template <typename Derived>
11720class OpenACCClauseTransform final
11721 : public OpenACCClauseVisitor<OpenACCClauseTransform<Derived>> {
11722 TreeTransform<Derived> &Self;
11723 ArrayRef<const OpenACCClause *> ExistingClauses;
11724 SemaOpenACC::OpenACCParsedClause &ParsedClause;
11725 OpenACCClause *NewClause = nullptr;
11726
11727 llvm::SmallVector<Expr *> VisitVarList(ArrayRef<Expr *> VarList) {
11728 llvm::SmallVector<Expr *> InstantiatedVarList;
11729 for (Expr *CurVar : VarList) {
11730 ExprResult Res = Self.TransformExpr(CurVar);
11731
11732 if (!Res.isUsable())
11733 continue;
11734
11735 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11736 ParsedClause.getClauseKind(),
11737 Res.get());
11738
11739 if (Res.isUsable())
11740 InstantiatedVarList.push_back(Res.get());
11741 }
11742
11743 return InstantiatedVarList;
11744 }
11745
11746public:
11747 OpenACCClauseTransform(TreeTransform<Derived> &Self,
11748 ArrayRef<const OpenACCClause *> ExistingClauses,
11749 SemaOpenACC::OpenACCParsedClause &PC)
11750 : Self(Self), ExistingClauses(ExistingClauses), ParsedClause(PC) {}
11751
11752 OpenACCClause *CreatedClause() const { return NewClause; }
11753
11754#define VISIT_CLAUSE(CLAUSE_NAME) \
11755 void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause);
11756#include "clang/Basic/OpenACCClauses.def"
11757};
11758
11759template <typename Derived>
11760void OpenACCClauseTransform<Derived>::VisitDefaultClause(
11761 const OpenACCDefaultClause &C) {
11762 ParsedClause.setDefaultDetails(C.getDefaultClauseKind());
11763
11764 NewClause = OpenACCDefaultClause::Create(
11765 C: Self.getSema().getASTContext(), K: ParsedClause.getDefaultClauseKind(),
11766 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11767 EndLoc: ParsedClause.getEndLoc());
11768}
11769
11770template <typename Derived>
11771void OpenACCClauseTransform<Derived>::VisitIfClause(const OpenACCIfClause &C) {
11772 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11773 assert(Cond && "If constructed with invalid Condition");
11774 Sema::ConditionResult Res = Self.TransformCondition(
11775 Cond->getExprLoc(), /*Var=*/nullptr, Cond, Sema::ConditionKind::Boolean);
11776
11777 if (Res.isInvalid() || !Res.get().second)
11778 return;
11779
11780 ParsedClause.setConditionDetails(Res.get().second);
11781
11782 NewClause = OpenACCIfClause::Create(
11783 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11784 LParenLoc: ParsedClause.getLParenLoc(), ConditionExpr: ParsedClause.getConditionExpr(),
11785 EndLoc: ParsedClause.getEndLoc());
11786}
11787
11788template <typename Derived>
11789void OpenACCClauseTransform<Derived>::VisitSelfClause(
11790 const OpenACCSelfClause &C) {
11791
11792 // If this is an 'update' 'self' clause, this is actually a var list instead.
11793 if (ParsedClause.getDirectiveKind() == OpenACCDirectiveKind::Update) {
11794 llvm::SmallVector<Expr *> InstantiatedVarList;
11795 for (Expr *CurVar : C.getVarList()) {
11796 ExprResult Res = Self.TransformExpr(CurVar);
11797
11798 if (!Res.isUsable())
11799 continue;
11800
11801 Res = Self.getSema().OpenACC().ActOnVar(ParsedClause.getDirectiveKind(),
11802 ParsedClause.getClauseKind(),
11803 Res.get());
11804
11805 if (Res.isUsable())
11806 InstantiatedVarList.push_back(Res.get());
11807 }
11808
11809 ParsedClause.setVarListDetails(InstantiatedVarList,
11810 OpenACCModifierKind::Invalid);
11811
11812 NewClause = OpenACCSelfClause::Create(
11813 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11814 ParsedClause.getLParenLoc(), ParsedClause.getVarList(),
11815 ParsedClause.getEndLoc());
11816 } else {
11817
11818 if (C.hasConditionExpr()) {
11819 Expr *Cond = const_cast<Expr *>(C.getConditionExpr());
11820 Sema::ConditionResult Res =
11821 Self.TransformCondition(Cond->getExprLoc(), /*Var=*/nullptr, Cond,
11822 Sema::ConditionKind::Boolean);
11823
11824 if (Res.isInvalid() || !Res.get().second)
11825 return;
11826
11827 ParsedClause.setConditionDetails(Res.get().second);
11828 }
11829
11830 NewClause = OpenACCSelfClause::Create(
11831 Self.getSema().getASTContext(), ParsedClause.getBeginLoc(),
11832 ParsedClause.getLParenLoc(), ParsedClause.getConditionExpr(),
11833 ParsedClause.getEndLoc());
11834 }
11835}
11836
11837template <typename Derived>
11838void OpenACCClauseTransform<Derived>::VisitNumGangsClause(
11839 const OpenACCNumGangsClause &C) {
11840 llvm::SmallVector<Expr *> InstantiatedIntExprs;
11841
11842 for (Expr *CurIntExpr : C.getIntExprs()) {
11843 ExprResult Res = Self.TransformExpr(CurIntExpr);
11844
11845 if (!Res.isUsable())
11846 return;
11847
11848 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
11849 C.getClauseKind(),
11850 C.getBeginLoc(), Res.get());
11851 if (!Res.isUsable())
11852 return;
11853
11854 InstantiatedIntExprs.push_back(Res.get());
11855 }
11856
11857 ParsedClause.setIntExprDetails(InstantiatedIntExprs);
11858 NewClause = OpenACCNumGangsClause::Create(
11859 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11860 LParenLoc: ParsedClause.getLParenLoc(), IntExprs: ParsedClause.getIntExprs(),
11861 EndLoc: ParsedClause.getEndLoc());
11862}
11863
11864template <typename Derived>
11865void OpenACCClauseTransform<Derived>::VisitPrivateClause(
11866 const OpenACCPrivateClause &C) {
11867 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11868 OpenACCModifierKind::Invalid);
11869
11870 NewClause = OpenACCPrivateClause::Create(
11871 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11872 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11873 EndLoc: ParsedClause.getEndLoc());
11874}
11875
11876template <typename Derived>
11877void OpenACCClauseTransform<Derived>::VisitHostClause(
11878 const OpenACCHostClause &C) {
11879 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11880 OpenACCModifierKind::Invalid);
11881
11882 NewClause = OpenACCHostClause::Create(
11883 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11884 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11885 EndLoc: ParsedClause.getEndLoc());
11886}
11887
11888template <typename Derived>
11889void OpenACCClauseTransform<Derived>::VisitDeviceClause(
11890 const OpenACCDeviceClause &C) {
11891 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11892 OpenACCModifierKind::Invalid);
11893
11894 NewClause = OpenACCDeviceClause::Create(
11895 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11896 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11897 EndLoc: ParsedClause.getEndLoc());
11898}
11899
11900template <typename Derived>
11901void OpenACCClauseTransform<Derived>::VisitFirstPrivateClause(
11902 const OpenACCFirstPrivateClause &C) {
11903 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11904 OpenACCModifierKind::Invalid);
11905
11906 NewClause = OpenACCFirstPrivateClause::Create(
11907 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11908 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11909 EndLoc: ParsedClause.getEndLoc());
11910}
11911
11912template <typename Derived>
11913void OpenACCClauseTransform<Derived>::VisitNoCreateClause(
11914 const OpenACCNoCreateClause &C) {
11915 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11916 OpenACCModifierKind::Invalid);
11917
11918 NewClause = OpenACCNoCreateClause::Create(
11919 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11920 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11921 EndLoc: ParsedClause.getEndLoc());
11922}
11923
11924template <typename Derived>
11925void OpenACCClauseTransform<Derived>::VisitPresentClause(
11926 const OpenACCPresentClause &C) {
11927 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11928 OpenACCModifierKind::Invalid);
11929
11930 NewClause = OpenACCPresentClause::Create(
11931 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
11932 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
11933 EndLoc: ParsedClause.getEndLoc());
11934}
11935
11936template <typename Derived>
11937void OpenACCClauseTransform<Derived>::VisitCopyClause(
11938 const OpenACCCopyClause &C) {
11939 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11940 C.getModifierList());
11941
11942 NewClause = OpenACCCopyClause::Create(
11943 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11944 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11945 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11946 EndLoc: ParsedClause.getEndLoc());
11947}
11948
11949template <typename Derived>
11950void OpenACCClauseTransform<Derived>::VisitLinkClause(
11951 const OpenACCLinkClause &C) {
11952 llvm_unreachable("link clause not valid unless a decl transform");
11953}
11954
11955template <typename Derived>
11956void OpenACCClauseTransform<Derived>::VisitDeviceResidentClause(
11957 const OpenACCDeviceResidentClause &C) {
11958 llvm_unreachable("device_resident clause not valid unless a decl transform");
11959}
11960template <typename Derived>
11961void OpenACCClauseTransform<Derived>::VisitNoHostClause(
11962 const OpenACCNoHostClause &C) {
11963 llvm_unreachable("nohost clause not valid unless a decl transform");
11964}
11965template <typename Derived>
11966void OpenACCClauseTransform<Derived>::VisitBindClause(
11967 const OpenACCBindClause &C) {
11968 llvm_unreachable("bind clause not valid unless a decl transform");
11969}
11970
11971template <typename Derived>
11972void OpenACCClauseTransform<Derived>::VisitCopyInClause(
11973 const OpenACCCopyInClause &C) {
11974 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11975 C.getModifierList());
11976
11977 NewClause = OpenACCCopyInClause::Create(
11978 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11979 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11980 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11981 EndLoc: ParsedClause.getEndLoc());
11982}
11983
11984template <typename Derived>
11985void OpenACCClauseTransform<Derived>::VisitCopyOutClause(
11986 const OpenACCCopyOutClause &C) {
11987 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
11988 C.getModifierList());
11989
11990 NewClause = OpenACCCopyOutClause::Create(
11991 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
11992 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
11993 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
11994 EndLoc: ParsedClause.getEndLoc());
11995}
11996
11997template <typename Derived>
11998void OpenACCClauseTransform<Derived>::VisitCreateClause(
11999 const OpenACCCreateClause &C) {
12000 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12001 C.getModifierList());
12002
12003 NewClause = OpenACCCreateClause::Create(
12004 C: Self.getSema().getASTContext(), Spelling: ParsedClause.getClauseKind(),
12005 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12006 Mods: ParsedClause.getModifierList(), VarList: ParsedClause.getVarList(),
12007 EndLoc: ParsedClause.getEndLoc());
12008}
12009template <typename Derived>
12010void OpenACCClauseTransform<Derived>::VisitAttachClause(
12011 const OpenACCAttachClause &C) {
12012 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12013
12014 // Ensure each var is a pointer type.
12015 llvm::erase_if(VarList, [&](Expr *E) {
12016 return Self.getSema().OpenACC().CheckVarIsPointerType(
12017 OpenACCClauseKind::Attach, E);
12018 });
12019
12020 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12021 NewClause = OpenACCAttachClause::Create(
12022 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12023 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12024 EndLoc: ParsedClause.getEndLoc());
12025}
12026
12027template <typename Derived>
12028void OpenACCClauseTransform<Derived>::VisitDetachClause(
12029 const OpenACCDetachClause &C) {
12030 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12031
12032 // Ensure each var is a pointer type.
12033 llvm::erase_if(VarList, [&](Expr *E) {
12034 return Self.getSema().OpenACC().CheckVarIsPointerType(
12035 OpenACCClauseKind::Detach, E);
12036 });
12037
12038 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12039 NewClause = OpenACCDetachClause::Create(
12040 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12041 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12042 EndLoc: ParsedClause.getEndLoc());
12043}
12044
12045template <typename Derived>
12046void OpenACCClauseTransform<Derived>::VisitDeleteClause(
12047 const OpenACCDeleteClause &C) {
12048 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12049 OpenACCModifierKind::Invalid);
12050 NewClause = OpenACCDeleteClause::Create(
12051 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12052 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12053 EndLoc: ParsedClause.getEndLoc());
12054}
12055
12056template <typename Derived>
12057void OpenACCClauseTransform<Derived>::VisitUseDeviceClause(
12058 const OpenACCUseDeviceClause &C) {
12059 ParsedClause.setVarListDetails(VisitVarList(C.getVarList()),
12060 OpenACCModifierKind::Invalid);
12061 NewClause = OpenACCUseDeviceClause::Create(
12062 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12063 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12064 EndLoc: ParsedClause.getEndLoc());
12065}
12066
12067template <typename Derived>
12068void OpenACCClauseTransform<Derived>::VisitDevicePtrClause(
12069 const OpenACCDevicePtrClause &C) {
12070 llvm::SmallVector<Expr *> VarList = VisitVarList(C.getVarList());
12071
12072 // Ensure each var is a pointer type.
12073 llvm::erase_if(VarList, [&](Expr *E) {
12074 return Self.getSema().OpenACC().CheckVarIsPointerType(
12075 OpenACCClauseKind::DevicePtr, E);
12076 });
12077
12078 ParsedClause.setVarListDetails(VarList, OpenACCModifierKind::Invalid);
12079 NewClause = OpenACCDevicePtrClause::Create(
12080 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12081 LParenLoc: ParsedClause.getLParenLoc(), VarList: ParsedClause.getVarList(),
12082 EndLoc: ParsedClause.getEndLoc());
12083}
12084
12085template <typename Derived>
12086void OpenACCClauseTransform<Derived>::VisitNumWorkersClause(
12087 const OpenACCNumWorkersClause &C) {
12088 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12089 assert(IntExpr && "num_workers clause constructed with invalid int expr");
12090
12091 ExprResult Res = Self.TransformExpr(IntExpr);
12092 if (!Res.isUsable())
12093 return;
12094
12095 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12096 C.getClauseKind(),
12097 C.getBeginLoc(), Res.get());
12098 if (!Res.isUsable())
12099 return;
12100
12101 ParsedClause.setIntExprDetails(Res.get());
12102 NewClause = OpenACCNumWorkersClause::Create(
12103 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12104 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12105 EndLoc: ParsedClause.getEndLoc());
12106}
12107
12108template <typename Derived>
12109void OpenACCClauseTransform<Derived>::VisitDeviceNumClause (
12110 const OpenACCDeviceNumClause &C) {
12111 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12112 assert(IntExpr && "device_num clause constructed with invalid int expr");
12113
12114 ExprResult Res = Self.TransformExpr(IntExpr);
12115 if (!Res.isUsable())
12116 return;
12117
12118 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12119 C.getClauseKind(),
12120 C.getBeginLoc(), Res.get());
12121 if (!Res.isUsable())
12122 return;
12123
12124 ParsedClause.setIntExprDetails(Res.get());
12125 NewClause = OpenACCDeviceNumClause::Create(
12126 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12127 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12128 EndLoc: ParsedClause.getEndLoc());
12129}
12130
12131template <typename Derived>
12132void OpenACCClauseTransform<Derived>::VisitDefaultAsyncClause(
12133 const OpenACCDefaultAsyncClause &C) {
12134 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12135 assert(IntExpr && "default_async clause constructed with invalid int expr");
12136
12137 ExprResult Res = Self.TransformExpr(IntExpr);
12138 if (!Res.isUsable())
12139 return;
12140
12141 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12142 C.getClauseKind(),
12143 C.getBeginLoc(), Res.get());
12144 if (!Res.isUsable())
12145 return;
12146
12147 ParsedClause.setIntExprDetails(Res.get());
12148 NewClause = OpenACCDefaultAsyncClause::Create(
12149 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12150 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12151 EndLoc: ParsedClause.getEndLoc());
12152}
12153
12154template <typename Derived>
12155void OpenACCClauseTransform<Derived>::VisitVectorLengthClause(
12156 const OpenACCVectorLengthClause &C) {
12157 Expr *IntExpr = const_cast<Expr *>(C.getIntExpr());
12158 assert(IntExpr && "vector_length clause constructed with invalid int expr");
12159
12160 ExprResult Res = Self.TransformExpr(IntExpr);
12161 if (!Res.isUsable())
12162 return;
12163
12164 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12165 C.getClauseKind(),
12166 C.getBeginLoc(), Res.get());
12167 if (!Res.isUsable())
12168 return;
12169
12170 ParsedClause.setIntExprDetails(Res.get());
12171 NewClause = OpenACCVectorLengthClause::Create(
12172 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12173 LParenLoc: ParsedClause.getLParenLoc(), IntExpr: ParsedClause.getIntExprs()[0],
12174 EndLoc: ParsedClause.getEndLoc());
12175}
12176
12177template <typename Derived>
12178void OpenACCClauseTransform<Derived>::VisitAsyncClause(
12179 const OpenACCAsyncClause &C) {
12180 if (C.hasIntExpr()) {
12181 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12182 if (!Res.isUsable())
12183 return;
12184
12185 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12186 C.getClauseKind(),
12187 C.getBeginLoc(), Res.get());
12188 if (!Res.isUsable())
12189 return;
12190 ParsedClause.setIntExprDetails(Res.get());
12191 }
12192
12193 NewClause = OpenACCAsyncClause::Create(
12194 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12195 LParenLoc: ParsedClause.getLParenLoc(),
12196 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12197 : nullptr,
12198 EndLoc: ParsedClause.getEndLoc());
12199}
12200
12201template <typename Derived>
12202void OpenACCClauseTransform<Derived>::VisitWorkerClause(
12203 const OpenACCWorkerClause &C) {
12204 if (C.hasIntExpr()) {
12205 // restrictions on this expression are all "does it exist in certain
12206 // situations" that are not possible to be dependent, so the only check we
12207 // have is that it transforms, and is an int expression.
12208 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12209 if (!Res.isUsable())
12210 return;
12211
12212 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12213 C.getClauseKind(),
12214 C.getBeginLoc(), Res.get());
12215 if (!Res.isUsable())
12216 return;
12217 ParsedClause.setIntExprDetails(Res.get());
12218 }
12219
12220 NewClause = OpenACCWorkerClause::Create(
12221 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12222 LParenLoc: ParsedClause.getLParenLoc(),
12223 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12224 : nullptr,
12225 EndLoc: ParsedClause.getEndLoc());
12226}
12227
12228template <typename Derived>
12229void OpenACCClauseTransform<Derived>::VisitVectorClause(
12230 const OpenACCVectorClause &C) {
12231 if (C.hasIntExpr()) {
12232 // restrictions on this expression are all "does it exist in certain
12233 // situations" that are not possible to be dependent, so the only check we
12234 // have is that it transforms, and is an int expression.
12235 ExprResult Res = Self.TransformExpr(const_cast<Expr *>(C.getIntExpr()));
12236 if (!Res.isUsable())
12237 return;
12238
12239 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12240 C.getClauseKind(),
12241 C.getBeginLoc(), Res.get());
12242 if (!Res.isUsable())
12243 return;
12244 ParsedClause.setIntExprDetails(Res.get());
12245 }
12246
12247 NewClause = OpenACCVectorClause::Create(
12248 Ctx: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12249 LParenLoc: ParsedClause.getLParenLoc(),
12250 IntExpr: ParsedClause.getNumIntExprs() != 0 ? ParsedClause.getIntExprs()[0]
12251 : nullptr,
12252 EndLoc: ParsedClause.getEndLoc());
12253}
12254
12255template <typename Derived>
12256void OpenACCClauseTransform<Derived>::VisitWaitClause(
12257 const OpenACCWaitClause &C) {
12258 if (C.hasExprs()) {
12259 Expr *DevNumExpr = nullptr;
12260 llvm::SmallVector<Expr *> InstantiatedQueueIdExprs;
12261
12262 // Instantiate devnum expr if it exists.
12263 if (C.getDevNumExpr()) {
12264 ExprResult Res = Self.TransformExpr(C.getDevNumExpr());
12265 if (!Res.isUsable())
12266 return;
12267 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12268 C.getClauseKind(),
12269 C.getBeginLoc(), Res.get());
12270 if (!Res.isUsable())
12271 return;
12272
12273 DevNumExpr = Res.get();
12274 }
12275
12276 // Instantiate queue ids.
12277 for (Expr *CurQueueIdExpr : C.getQueueIdExprs()) {
12278 ExprResult Res = Self.TransformExpr(CurQueueIdExpr);
12279 if (!Res.isUsable())
12280 return;
12281 Res = Self.getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Invalid,
12282 C.getClauseKind(),
12283 C.getBeginLoc(), Res.get());
12284 if (!Res.isUsable())
12285 return;
12286
12287 InstantiatedQueueIdExprs.push_back(Res.get());
12288 }
12289
12290 ParsedClause.setWaitDetails(DevNum: DevNumExpr, QueuesLoc: C.getQueuesLoc(),
12291 IntExprs: std::move(InstantiatedQueueIdExprs));
12292 }
12293
12294 NewClause = OpenACCWaitClause::Create(
12295 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12296 LParenLoc: ParsedClause.getLParenLoc(), DevNumExpr: ParsedClause.getDevNumExpr(),
12297 QueuesLoc: ParsedClause.getQueuesLoc(), QueueIdExprs: ParsedClause.getQueueIdExprs(),
12298 EndLoc: ParsedClause.getEndLoc());
12299}
12300
12301template <typename Derived>
12302void OpenACCClauseTransform<Derived>::VisitDeviceTypeClause(
12303 const OpenACCDeviceTypeClause &C) {
12304 // Nothing to transform here, just create a new version of 'C'.
12305 NewClause = OpenACCDeviceTypeClause::Create(
12306 C: Self.getSema().getASTContext(), K: C.getClauseKind(),
12307 BeginLoc: ParsedClause.getBeginLoc(), LParenLoc: ParsedClause.getLParenLoc(),
12308 Archs: C.getArchitectures(), EndLoc: ParsedClause.getEndLoc());
12309}
12310
12311template <typename Derived>
12312void OpenACCClauseTransform<Derived>::VisitAutoClause(
12313 const OpenACCAutoClause &C) {
12314 // Nothing to do, so just create a new node.
12315 NewClause = OpenACCAutoClause::Create(Ctx: Self.getSema().getASTContext(),
12316 BeginLoc: ParsedClause.getBeginLoc(),
12317 EndLoc: ParsedClause.getEndLoc());
12318}
12319
12320template <typename Derived>
12321void OpenACCClauseTransform<Derived>::VisitIndependentClause(
12322 const OpenACCIndependentClause &C) {
12323 NewClause = OpenACCIndependentClause::Create(Ctx: Self.getSema().getASTContext(),
12324 BeginLoc: ParsedClause.getBeginLoc(),
12325 EndLoc: ParsedClause.getEndLoc());
12326}
12327
12328template <typename Derived>
12329void OpenACCClauseTransform<Derived>::VisitSeqClause(
12330 const OpenACCSeqClause &C) {
12331 NewClause = OpenACCSeqClause::Create(Ctx: Self.getSema().getASTContext(),
12332 BeginLoc: ParsedClause.getBeginLoc(),
12333 EndLoc: ParsedClause.getEndLoc());
12334}
12335template <typename Derived>
12336void OpenACCClauseTransform<Derived>::VisitFinalizeClause(
12337 const OpenACCFinalizeClause &C) {
12338 NewClause = OpenACCFinalizeClause::Create(Ctx: Self.getSema().getASTContext(),
12339 BeginLoc: ParsedClause.getBeginLoc(),
12340 EndLoc: ParsedClause.getEndLoc());
12341}
12342
12343template <typename Derived>
12344void OpenACCClauseTransform<Derived>::VisitIfPresentClause(
12345 const OpenACCIfPresentClause &C) {
12346 NewClause = OpenACCIfPresentClause::Create(Ctx: Self.getSema().getASTContext(),
12347 BeginLoc: ParsedClause.getBeginLoc(),
12348 EndLoc: ParsedClause.getEndLoc());
12349}
12350
12351template <typename Derived>
12352void OpenACCClauseTransform<Derived>::VisitReductionClause(
12353 const OpenACCReductionClause &C) {
12354 SmallVector<Expr *> TransformedVars = VisitVarList(C.getVarList());
12355 SmallVector<Expr *> ValidVars;
12356
12357 for (Expr *Var : TransformedVars) {
12358 ExprResult Res = Self.getSema().OpenACC().CheckReductionVar(
12359 ParsedClause.getDirectiveKind(), C.getReductionOp(), Var);
12360 if (Res.isUsable())
12361 ValidVars.push_back(Res.get());
12362 }
12363
12364 NewClause = Self.getSema().OpenACC().CheckReductionClause(
12365 ExistingClauses, ParsedClause.getDirectiveKind(),
12366 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12367 C.getReductionOp(), ValidVars, ParsedClause.getEndLoc());
12368}
12369
12370template <typename Derived>
12371void OpenACCClauseTransform<Derived>::VisitCollapseClause(
12372 const OpenACCCollapseClause &C) {
12373 Expr *LoopCount = const_cast<Expr *>(C.getLoopCount());
12374 assert(LoopCount && "collapse clause constructed with invalid loop count");
12375
12376 ExprResult NewLoopCount = Self.TransformExpr(LoopCount);
12377
12378 NewLoopCount = Self.getSema().OpenACC().ActOnIntExpr(
12379 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12380 NewLoopCount.get()->getBeginLoc(), NewLoopCount.get());
12381
12382 NewLoopCount =
12383 Self.getSema().OpenACC().CheckCollapseLoopCount(NewLoopCount.get());
12384
12385 ParsedClause.setCollapseDetails(IsForce: C.hasForce(), LoopCount: NewLoopCount.get());
12386 NewClause = OpenACCCollapseClause::Create(
12387 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12388 LParenLoc: ParsedClause.getLParenLoc(), HasForce: ParsedClause.isForce(),
12389 LoopCount: ParsedClause.getLoopCount(), EndLoc: ParsedClause.getEndLoc());
12390}
12391
12392template <typename Derived>
12393void OpenACCClauseTransform<Derived>::VisitTileClause(
12394 const OpenACCTileClause &C) {
12395
12396 llvm::SmallVector<Expr *> TransformedExprs;
12397
12398 for (Expr *E : C.getSizeExprs()) {
12399 ExprResult NewSizeExpr = Self.TransformExpr(E);
12400
12401 if (!NewSizeExpr.isUsable())
12402 return;
12403
12404 NewSizeExpr = Self.getSema().OpenACC().ActOnIntExpr(
12405 OpenACCDirectiveKind::Invalid, ParsedClause.getClauseKind(),
12406 NewSizeExpr.get()->getBeginLoc(), NewSizeExpr.get());
12407
12408 NewSizeExpr = Self.getSema().OpenACC().CheckTileSizeExpr(NewSizeExpr.get());
12409
12410 if (!NewSizeExpr.isUsable())
12411 return;
12412 TransformedExprs.push_back(NewSizeExpr.get());
12413 }
12414
12415 ParsedClause.setIntExprDetails(TransformedExprs);
12416 NewClause = OpenACCTileClause::Create(
12417 C: Self.getSema().getASTContext(), BeginLoc: ParsedClause.getBeginLoc(),
12418 LParenLoc: ParsedClause.getLParenLoc(), SizeExprs: ParsedClause.getIntExprs(),
12419 EndLoc: ParsedClause.getEndLoc());
12420}
12421template <typename Derived>
12422void OpenACCClauseTransform<Derived>::VisitGangClause(
12423 const OpenACCGangClause &C) {
12424 llvm::SmallVector<OpenACCGangKind> TransformedGangKinds;
12425 llvm::SmallVector<Expr *> TransformedIntExprs;
12426
12427 for (unsigned I = 0; I < C.getNumExprs(); ++I) {
12428 ExprResult ER = Self.TransformExpr(const_cast<Expr *>(C.getExpr(I).second));
12429 if (!ER.isUsable())
12430 continue;
12431
12432 ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses,
12433 ParsedClause.getDirectiveKind(),
12434 C.getExpr(I).first, ER.get());
12435 if (!ER.isUsable())
12436 continue;
12437 TransformedGangKinds.push_back(C.getExpr(I).first);
12438 TransformedIntExprs.push_back(ER.get());
12439 }
12440
12441 NewClause = Self.getSema().OpenACC().CheckGangClause(
12442 ParsedClause.getDirectiveKind(), ExistingClauses,
12443 ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(),
12444 TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc());
12445}
12446} // namespace
12447template <typename Derived>
12448OpenACCClause *TreeTransform<Derived>::TransformOpenACCClause(
12449 ArrayRef<const OpenACCClause *> ExistingClauses,
12450 OpenACCDirectiveKind DirKind, const OpenACCClause *OldClause) {
12451
12452 SemaOpenACC::OpenACCParsedClause ParsedClause(
12453 DirKind, OldClause->getClauseKind(), OldClause->getBeginLoc());
12454 ParsedClause.setEndLoc(OldClause->getEndLoc());
12455
12456 if (const auto *WithParms = dyn_cast<OpenACCClauseWithParams>(OldClause))
12457 ParsedClause.setLParenLoc(WithParms->getLParenLoc());
12458
12459 OpenACCClauseTransform<Derived> Transform{*this, ExistingClauses,
12460 ParsedClause};
12461 Transform.Visit(OldClause);
12462
12463 return Transform.CreatedClause();
12464}
12465
12466template <typename Derived>
12467llvm::SmallVector<OpenACCClause *>
12468TreeTransform<Derived>::TransformOpenACCClauseList(
12469 OpenACCDirectiveKind DirKind, ArrayRef<const OpenACCClause *> OldClauses) {
12470 llvm::SmallVector<OpenACCClause *> TransformedClauses;
12471 for (const auto *Clause : OldClauses) {
12472 if (OpenACCClause *TransformedClause = getDerived().TransformOpenACCClause(
12473 TransformedClauses, DirKind, Clause))
12474 TransformedClauses.push_back(TransformedClause);
12475 }
12476 return TransformedClauses;
12477}
12478
12479template <typename Derived>
12480StmtResult TreeTransform<Derived>::TransformOpenACCComputeConstruct(
12481 OpenACCComputeConstruct *C) {
12482 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12483
12484 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12485 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12486 C->clauses());
12487
12488 if (getSema().OpenACC().ActOnStartStmtDirective(
12489 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12490 return StmtError();
12491
12492 // Transform Structured Block.
12493 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12494 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12495 C->clauses(), TransformedClauses);
12496 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12497 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12498 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12499
12500 return getDerived().RebuildOpenACCComputeConstruct(
12501 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12502 C->getEndLoc(), TransformedClauses, StrBlock);
12503}
12504
12505template <typename Derived>
12506StmtResult
12507TreeTransform<Derived>::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) {
12508
12509 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12510
12511 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12512 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12513 C->clauses());
12514
12515 if (getSema().OpenACC().ActOnStartStmtDirective(
12516 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12517 return StmtError();
12518
12519 // Transform Loop.
12520 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12521 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12522 C->clauses(), TransformedClauses);
12523 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12524 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12525 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12526
12527 return getDerived().RebuildOpenACCLoopConstruct(
12528 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12529 TransformedClauses, Loop);
12530}
12531
12532template <typename Derived>
12533StmtResult TreeTransform<Derived>::TransformOpenACCCombinedConstruct(
12534 OpenACCCombinedConstruct *C) {
12535 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12536
12537 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12538 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12539 C->clauses());
12540
12541 if (getSema().OpenACC().ActOnStartStmtDirective(
12542 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12543 return StmtError();
12544
12545 // Transform Loop.
12546 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12547 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12548 C->clauses(), TransformedClauses);
12549 StmtResult Loop = getDerived().TransformStmt(C->getLoop());
12550 Loop = getSema().OpenACC().ActOnAssociatedStmt(
12551 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, Loop);
12552
12553 return getDerived().RebuildOpenACCCombinedConstruct(
12554 C->getDirectiveKind(), C->getBeginLoc(), C->getDirectiveLoc(),
12555 C->getEndLoc(), TransformedClauses, Loop);
12556}
12557
12558template <typename Derived>
12559StmtResult
12560TreeTransform<Derived>::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) {
12561 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12562
12563 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12564 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12565 C->clauses());
12566 if (getSema().OpenACC().ActOnStartStmtDirective(
12567 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12568 return StmtError();
12569
12570 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12571 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12572 C->clauses(), TransformedClauses);
12573 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12574 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12575 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12576
12577 return getDerived().RebuildOpenACCDataConstruct(
12578 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12579 TransformedClauses, StrBlock);
12580}
12581
12582template <typename Derived>
12583StmtResult TreeTransform<Derived>::TransformOpenACCEnterDataConstruct(
12584 OpenACCEnterDataConstruct *C) {
12585 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12586
12587 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12588 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12589 C->clauses());
12590 if (getSema().OpenACC().ActOnStartStmtDirective(
12591 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12592 return StmtError();
12593
12594 return getDerived().RebuildOpenACCEnterDataConstruct(
12595 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12596 TransformedClauses);
12597}
12598
12599template <typename Derived>
12600StmtResult TreeTransform<Derived>::TransformOpenACCExitDataConstruct(
12601 OpenACCExitDataConstruct *C) {
12602 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12603
12604 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12605 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12606 C->clauses());
12607 if (getSema().OpenACC().ActOnStartStmtDirective(
12608 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12609 return StmtError();
12610
12611 return getDerived().RebuildOpenACCExitDataConstruct(
12612 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12613 TransformedClauses);
12614}
12615
12616template <typename Derived>
12617StmtResult TreeTransform<Derived>::TransformOpenACCHostDataConstruct(
12618 OpenACCHostDataConstruct *C) {
12619 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12620
12621 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12622 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12623 C->clauses());
12624 if (getSema().OpenACC().ActOnStartStmtDirective(
12625 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12626 return StmtError();
12627
12628 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12629 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(),
12630 C->clauses(), TransformedClauses);
12631 StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock());
12632 StrBlock = getSema().OpenACC().ActOnAssociatedStmt(
12633 C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock);
12634
12635 return getDerived().RebuildOpenACCHostDataConstruct(
12636 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12637 TransformedClauses, StrBlock);
12638}
12639
12640template <typename Derived>
12641StmtResult
12642TreeTransform<Derived>::TransformOpenACCInitConstruct(OpenACCInitConstruct *C) {
12643 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12644
12645 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12646 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12647 C->clauses());
12648 if (getSema().OpenACC().ActOnStartStmtDirective(
12649 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12650 return StmtError();
12651
12652 return getDerived().RebuildOpenACCInitConstruct(
12653 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12654 TransformedClauses);
12655}
12656
12657template <typename Derived>
12658StmtResult TreeTransform<Derived>::TransformOpenACCShutdownConstruct(
12659 OpenACCShutdownConstruct *C) {
12660 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12661
12662 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12663 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12664 C->clauses());
12665 if (getSema().OpenACC().ActOnStartStmtDirective(
12666 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12667 return StmtError();
12668
12669 return getDerived().RebuildOpenACCShutdownConstruct(
12670 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12671 TransformedClauses);
12672}
12673template <typename Derived>
12674StmtResult
12675TreeTransform<Derived>::TransformOpenACCSetConstruct(OpenACCSetConstruct *C) {
12676 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12677
12678 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12679 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12680 C->clauses());
12681 if (getSema().OpenACC().ActOnStartStmtDirective(
12682 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12683 return StmtError();
12684
12685 return getDerived().RebuildOpenACCSetConstruct(
12686 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12687 TransformedClauses);
12688}
12689
12690template <typename Derived>
12691StmtResult TreeTransform<Derived>::TransformOpenACCUpdateConstruct(
12692 OpenACCUpdateConstruct *C) {
12693 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12694
12695 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12696 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12697 C->clauses());
12698 if (getSema().OpenACC().ActOnStartStmtDirective(
12699 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12700 return StmtError();
12701
12702 return getDerived().RebuildOpenACCUpdateConstruct(
12703 C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(),
12704 TransformedClauses);
12705}
12706
12707template <typename Derived>
12708StmtResult
12709TreeTransform<Derived>::TransformOpenACCWaitConstruct(OpenACCWaitConstruct *C) {
12710 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12711
12712 ExprResult DevNumExpr;
12713 if (C->hasDevNumExpr()) {
12714 DevNumExpr = getDerived().TransformExpr(C->getDevNumExpr());
12715
12716 if (DevNumExpr.isUsable())
12717 DevNumExpr = getSema().OpenACC().ActOnIntExpr(
12718 OpenACCDirectiveKind::Wait, OpenACCClauseKind::Invalid,
12719 C->getBeginLoc(), DevNumExpr.get());
12720 }
12721
12722 llvm::SmallVector<Expr *> QueueIdExprs;
12723
12724 for (Expr *QE : C->getQueueIdExprs()) {
12725 assert(QE && "Null queue id expr?");
12726 ExprResult NewEQ = getDerived().TransformExpr(QE);
12727
12728 if (!NewEQ.isUsable())
12729 break;
12730 NewEQ = getSema().OpenACC().ActOnIntExpr(OpenACCDirectiveKind::Wait,
12731 OpenACCClauseKind::Invalid,
12732 C->getBeginLoc(), NewEQ.get());
12733 if (NewEQ.isUsable())
12734 QueueIdExprs.push_back(NewEQ.get());
12735 }
12736
12737 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12738 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12739 C->clauses());
12740
12741 if (getSema().OpenACC().ActOnStartStmtDirective(
12742 C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses))
12743 return StmtError();
12744
12745 return getDerived().RebuildOpenACCWaitConstruct(
12746 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12747 DevNumExpr.isUsable() ? DevNumExpr.get() : nullptr, C->getQueuesLoc(),
12748 QueueIdExprs, C->getRParenLoc(), C->getEndLoc(), TransformedClauses);
12749}
12750template <typename Derived>
12751StmtResult TreeTransform<Derived>::TransformOpenACCCacheConstruct(
12752 OpenACCCacheConstruct *C) {
12753 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12754
12755 llvm::SmallVector<Expr *> TransformedVarList;
12756 for (Expr *Var : C->getVarList()) {
12757 assert(Var && "Null var listexpr?");
12758
12759 ExprResult NewVar = getDerived().TransformExpr(Var);
12760
12761 if (!NewVar.isUsable())
12762 break;
12763
12764 NewVar = getSema().OpenACC().ActOnVar(
12765 C->getDirectiveKind(), OpenACCClauseKind::Invalid, NewVar.get());
12766 if (!NewVar.isUsable())
12767 break;
12768
12769 TransformedVarList.push_back(NewVar.get());
12770 }
12771
12772 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12773 C->getBeginLoc(), {}))
12774 return StmtError();
12775
12776 return getDerived().RebuildOpenACCCacheConstruct(
12777 C->getBeginLoc(), C->getDirectiveLoc(), C->getLParenLoc(),
12778 C->getReadOnlyLoc(), TransformedVarList, C->getRParenLoc(),
12779 C->getEndLoc());
12780}
12781
12782template <typename Derived>
12783StmtResult TreeTransform<Derived>::TransformOpenACCAtomicConstruct(
12784 OpenACCAtomicConstruct *C) {
12785 getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc());
12786
12787 llvm::SmallVector<OpenACCClause *> TransformedClauses =
12788 getDerived().TransformOpenACCClauseList(C->getDirectiveKind(),
12789 C->clauses());
12790
12791 if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(),
12792 C->getBeginLoc(), {}))
12793 return StmtError();
12794
12795 // Transform Associated Stmt.
12796 SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(
12797 getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), {}, {});
12798
12799 StmtResult AssocStmt = getDerived().TransformStmt(C->getAssociatedStmt());
12800 AssocStmt = getSema().OpenACC().ActOnAssociatedStmt(
12801 C->getBeginLoc(), C->getDirectiveKind(), C->getAtomicKind(), {},
12802 AssocStmt);
12803
12804 return getDerived().RebuildOpenACCAtomicConstruct(
12805 C->getBeginLoc(), C->getDirectiveLoc(), C->getAtomicKind(),
12806 C->getEndLoc(), TransformedClauses, AssocStmt);
12807}
12808
12809template <typename Derived>
12810ExprResult TreeTransform<Derived>::TransformOpenACCAsteriskSizeExpr(
12811 OpenACCAsteriskSizeExpr *E) {
12812 if (getDerived().AlwaysRebuild())
12813 return getDerived().RebuildOpenACCAsteriskSizeExpr(E->getLocation());
12814 // Nothing can ever change, so there is never anything to transform.
12815 return E;
12816}
12817
12818//===----------------------------------------------------------------------===//
12819// Expression transformation
12820//===----------------------------------------------------------------------===//
12821template<typename Derived>
12822ExprResult
12823TreeTransform<Derived>::TransformConstantExpr(ConstantExpr *E) {
12824 return TransformExpr(E: E->getSubExpr());
12825}
12826
12827template <typename Derived>
12828ExprResult TreeTransform<Derived>::TransformSYCLUniqueStableNameExpr(
12829 SYCLUniqueStableNameExpr *E) {
12830 if (!E->isTypeDependent())
12831 return E;
12832
12833 TypeSourceInfo *NewT = getDerived().TransformType(E->getTypeSourceInfo());
12834
12835 if (!NewT)
12836 return ExprError();
12837
12838 if (!getDerived().AlwaysRebuild() && E->getTypeSourceInfo() == NewT)
12839 return E;
12840
12841 return getDerived().RebuildSYCLUniqueStableNameExpr(
12842 E->getLocation(), E->getLParenLocation(), E->getRParenLocation(), NewT);
12843}
12844
12845template<typename Derived>
12846ExprResult
12847TreeTransform<Derived>::TransformPredefinedExpr(PredefinedExpr *E) {
12848 if (!E->isTypeDependent())
12849 return E;
12850
12851 return getDerived().RebuildPredefinedExpr(E->getLocation(),
12852 E->getIdentKind());
12853}
12854
12855template<typename Derived>
12856ExprResult
12857TreeTransform<Derived>::TransformDeclRefExpr(DeclRefExpr *E) {
12858 NestedNameSpecifierLoc QualifierLoc;
12859 if (E->getQualifierLoc()) {
12860 QualifierLoc
12861 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
12862 if (!QualifierLoc)
12863 return ExprError();
12864 }
12865
12866 ValueDecl *ND
12867 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
12868 E->getDecl()));
12869 if (!ND || ND->isInvalidDecl())
12870 return ExprError();
12871
12872 NamedDecl *Found = ND;
12873 if (E->getFoundDecl() != E->getDecl()) {
12874 Found = cast_or_null<NamedDecl>(
12875 getDerived().TransformDecl(E->getLocation(), E->getFoundDecl()));
12876 if (!Found)
12877 return ExprError();
12878 }
12879
12880 DeclarationNameInfo NameInfo = E->getNameInfo();
12881 if (NameInfo.getName()) {
12882 NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
12883 if (!NameInfo.getName())
12884 return ExprError();
12885 }
12886
12887 if (!getDerived().AlwaysRebuild() &&
12888 !E->isCapturedByCopyInLambdaWithExplicitObjectParameter() &&
12889 QualifierLoc == E->getQualifierLoc() && ND == E->getDecl() &&
12890 Found == E->getFoundDecl() &&
12891 NameInfo.getName() == E->getDecl()->getDeclName() &&
12892 !E->hasExplicitTemplateArgs()) {
12893
12894 // Mark it referenced in the new context regardless.
12895 // FIXME: this is a bit instantiation-specific.
12896 SemaRef.MarkDeclRefReferenced(E);
12897
12898 return E;
12899 }
12900
12901 TemplateArgumentListInfo TransArgs, *TemplateArgs = nullptr;
12902 if (E->hasExplicitTemplateArgs()) {
12903 TemplateArgs = &TransArgs;
12904 TransArgs.setLAngleLoc(E->getLAngleLoc());
12905 TransArgs.setRAngleLoc(E->getRAngleLoc());
12906 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
12907 E->getNumTemplateArgs(),
12908 TransArgs))
12909 return ExprError();
12910 }
12911
12912 return getDerived().RebuildDeclRefExpr(QualifierLoc, ND, NameInfo,
12913 Found, TemplateArgs);
12914}
12915
12916template<typename Derived>
12917ExprResult
12918TreeTransform<Derived>::TransformIntegerLiteral(IntegerLiteral *E) {
12919 return E;
12920}
12921
12922template <typename Derived>
12923ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
12924 FixedPointLiteral *E) {
12925 return E;
12926}
12927
12928template<typename Derived>
12929ExprResult
12930TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
12931 return E;
12932}
12933
12934template<typename Derived>
12935ExprResult
12936TreeTransform<Derived>::TransformImaginaryLiteral(ImaginaryLiteral *E) {
12937 return E;
12938}
12939
12940template<typename Derived>
12941ExprResult
12942TreeTransform<Derived>::TransformStringLiteral(StringLiteral *E) {
12943 return E;
12944}
12945
12946template<typename Derived>
12947ExprResult
12948TreeTransform<Derived>::TransformCharacterLiteral(CharacterLiteral *E) {
12949 return E;
12950}
12951
12952template<typename Derived>
12953ExprResult
12954TreeTransform<Derived>::TransformUserDefinedLiteral(UserDefinedLiteral *E) {
12955 return getDerived().TransformCallExpr(E);
12956}
12957
12958template<typename Derived>
12959ExprResult
12960TreeTransform<Derived>::TransformGenericSelectionExpr(GenericSelectionExpr *E) {
12961 ExprResult ControllingExpr;
12962 TypeSourceInfo *ControllingType = nullptr;
12963 if (E->isExprPredicate())
12964 ControllingExpr = getDerived().TransformExpr(E->getControllingExpr());
12965 else
12966 ControllingType = getDerived().TransformType(E->getControllingType());
12967
12968 if (ControllingExpr.isInvalid() && !ControllingType)
12969 return ExprError();
12970
12971 SmallVector<Expr *, 4> AssocExprs;
12972 SmallVector<TypeSourceInfo *, 4> AssocTypes;
12973 for (const GenericSelectionExpr::Association Assoc : E->associations()) {
12974 TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
12975 if (TSI) {
12976 TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
12977 if (!AssocType)
12978 return ExprError();
12979 AssocTypes.push_back(AssocType);
12980 } else {
12981 AssocTypes.push_back(nullptr);
12982 }
12983
12984 ExprResult AssocExpr =
12985 getDerived().TransformExpr(Assoc.getAssociationExpr());
12986 if (AssocExpr.isInvalid())
12987 return ExprError();
12988 AssocExprs.push_back(AssocExpr.get());
12989 }
12990
12991 if (!ControllingType)
12992 return getDerived().RebuildGenericSelectionExpr(E->getGenericLoc(),
12993 E->getDefaultLoc(),
12994 E->getRParenLoc(),
12995 ControllingExpr.get(),
12996 AssocTypes,
12997 AssocExprs);
12998 return getDerived().RebuildGenericSelectionExpr(
12999 E->getGenericLoc(), E->getDefaultLoc(), E->getRParenLoc(),
13000 ControllingType, AssocTypes, AssocExprs);
13001}
13002
13003template<typename Derived>
13004ExprResult
13005TreeTransform<Derived>::TransformParenExpr(ParenExpr *E) {
13006 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13007 if (SubExpr.isInvalid())
13008 return ExprError();
13009
13010 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13011 return E;
13012
13013 return getDerived().RebuildParenExpr(SubExpr.get(), E->getLParen(),
13014 E->getRParen());
13015}
13016
13017/// The operand of a unary address-of operator has special rules: it's
13018/// allowed to refer to a non-static member of a class even if there's no 'this'
13019/// object available.
13020template<typename Derived>
13021ExprResult
13022TreeTransform<Derived>::TransformAddressOfOperand(Expr *E) {
13023 if (DependentScopeDeclRefExpr *DRE = dyn_cast<DependentScopeDeclRefExpr>(E))
13024 return getDerived().TransformDependentScopeDeclRefExpr(
13025 DRE, /*IsAddressOfOperand=*/true, nullptr);
13026 else if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(E))
13027 return getDerived().TransformUnresolvedLookupExpr(
13028 ULE, /*IsAddressOfOperand=*/true);
13029 else
13030 return getDerived().TransformExpr(E);
13031}
13032
13033template<typename Derived>
13034ExprResult
13035TreeTransform<Derived>::TransformUnaryOperator(UnaryOperator *E) {
13036 ExprResult SubExpr;
13037 if (E->getOpcode() == UO_AddrOf)
13038 SubExpr = TransformAddressOfOperand(E: E->getSubExpr());
13039 else
13040 SubExpr = TransformExpr(E: E->getSubExpr());
13041 if (SubExpr.isInvalid())
13042 return ExprError();
13043
13044 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getSubExpr())
13045 return E;
13046
13047 return getDerived().RebuildUnaryOperator(E->getOperatorLoc(),
13048 E->getOpcode(),
13049 SubExpr.get());
13050}
13051
13052template<typename Derived>
13053ExprResult
13054TreeTransform<Derived>::TransformOffsetOfExpr(OffsetOfExpr *E) {
13055 // Transform the type.
13056 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeSourceInfo());
13057 if (!Type)
13058 return ExprError();
13059
13060 // Transform all of the components into components similar to what the
13061 // parser uses.
13062 // FIXME: It would be slightly more efficient in the non-dependent case to
13063 // just map FieldDecls, rather than requiring the rebuilder to look for
13064 // the fields again. However, __builtin_offsetof is rare enough in
13065 // template code that we don't care.
13066 bool ExprChanged = false;
13067 typedef Sema::OffsetOfComponent Component;
13068 SmallVector<Component, 4> Components;
13069 for (unsigned I = 0, N = E->getNumComponents(); I != N; ++I) {
13070 const OffsetOfNode &ON = E->getComponent(Idx: I);
13071 Component Comp;
13072 Comp.isBrackets = true;
13073 Comp.LocStart = ON.getSourceRange().getBegin();
13074 Comp.LocEnd = ON.getSourceRange().getEnd();
13075 switch (ON.getKind()) {
13076 case OffsetOfNode::Array: {
13077 Expr *FromIndex = E->getIndexExpr(Idx: ON.getArrayExprIndex());
13078 ExprResult Index = getDerived().TransformExpr(FromIndex);
13079 if (Index.isInvalid())
13080 return ExprError();
13081
13082 ExprChanged = ExprChanged || Index.get() != FromIndex;
13083 Comp.isBrackets = true;
13084 Comp.U.E = Index.get();
13085 break;
13086 }
13087
13088 case OffsetOfNode::Field:
13089 case OffsetOfNode::Identifier:
13090 Comp.isBrackets = false;
13091 Comp.U.IdentInfo = ON.getFieldName();
13092 if (!Comp.U.IdentInfo)
13093 continue;
13094
13095 break;
13096
13097 case OffsetOfNode::Base:
13098 // Will be recomputed during the rebuild.
13099 continue;
13100 }
13101
13102 Components.push_back(Comp);
13103 }
13104
13105 // If nothing changed, retain the existing expression.
13106 if (!getDerived().AlwaysRebuild() &&
13107 Type == E->getTypeSourceInfo() &&
13108 !ExprChanged)
13109 return E;
13110
13111 // Build a new offsetof expression.
13112 return getDerived().RebuildOffsetOfExpr(E->getOperatorLoc(), Type,
13113 Components, E->getRParenLoc());
13114}
13115
13116template<typename Derived>
13117ExprResult
13118TreeTransform<Derived>::TransformOpaqueValueExpr(OpaqueValueExpr *E) {
13119 assert((!E->getSourceExpr() || getDerived().AlreadyTransformed(E->getType())) &&
13120 "opaque value expression requires transformation");
13121 return E;
13122}
13123
13124template<typename Derived>
13125ExprResult
13126TreeTransform<Derived>::TransformTypoExpr(TypoExpr *E) {
13127 return E;
13128}
13129
13130template <typename Derived>
13131ExprResult TreeTransform<Derived>::TransformRecoveryExpr(RecoveryExpr *E) {
13132 llvm::SmallVector<Expr *, 8> Children;
13133 bool Changed = false;
13134 for (Expr *C : E->subExpressions()) {
13135 ExprResult NewC = getDerived().TransformExpr(C);
13136 if (NewC.isInvalid())
13137 return ExprError();
13138 Children.push_back(NewC.get());
13139
13140 Changed |= NewC.get() != C;
13141 }
13142 if (!getDerived().AlwaysRebuild() && !Changed)
13143 return E;
13144 return getDerived().RebuildRecoveryExpr(E->getBeginLoc(), E->getEndLoc(),
13145 Children, E->getType());
13146}
13147
13148template<typename Derived>
13149ExprResult
13150TreeTransform<Derived>::TransformPseudoObjectExpr(PseudoObjectExpr *E) {
13151 // Rebuild the syntactic form. The original syntactic form has
13152 // opaque-value expressions in it, so strip those away and rebuild
13153 // the result. This is a really awful way of doing this, but the
13154 // better solution (rebuilding the semantic expressions and
13155 // rebinding OVEs as necessary) doesn't work; we'd need
13156 // TreeTransform to not strip away implicit conversions.
13157 Expr *newSyntacticForm = SemaRef.PseudoObject().recreateSyntacticForm(E);
13158 ExprResult result = getDerived().TransformExpr(newSyntacticForm);
13159 if (result.isInvalid()) return ExprError();
13160
13161 // If that gives us a pseudo-object result back, the pseudo-object
13162 // expression must have been an lvalue-to-rvalue conversion which we
13163 // should reapply.
13164 if (result.get()->hasPlaceholderType(K: BuiltinType::PseudoObject))
13165 result = SemaRef.PseudoObject().checkRValue(E: result.get());
13166
13167 return result;
13168}
13169
13170template<typename Derived>
13171ExprResult
13172TreeTransform<Derived>::TransformUnaryExprOrTypeTraitExpr(
13173 UnaryExprOrTypeTraitExpr *E) {
13174 if (E->isArgumentType()) {
13175 TypeSourceInfo *OldT = E->getArgumentTypeInfo();
13176
13177 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13178 if (!NewT)
13179 return ExprError();
13180
13181 if (!getDerived().AlwaysRebuild() && OldT == NewT)
13182 return E;
13183
13184 return getDerived().RebuildUnaryExprOrTypeTrait(NewT, E->getOperatorLoc(),
13185 E->getKind(),
13186 E->getSourceRange());
13187 }
13188
13189 // C++0x [expr.sizeof]p1:
13190 // The operand is either an expression, which is an unevaluated operand
13191 // [...]
13192 EnterExpressionEvaluationContext Unevaluated(
13193 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
13194 Sema::ReuseLambdaContextDecl);
13195
13196 // Try to recover if we have something like sizeof(T::X) where X is a type.
13197 // Notably, there must be *exactly* one set of parens if X is a type.
13198 TypeSourceInfo *RecoveryTSI = nullptr;
13199 ExprResult SubExpr;
13200 auto *PE = dyn_cast<ParenExpr>(E->getArgumentExpr());
13201 if (auto *DRE =
13202 PE ? dyn_cast<DependentScopeDeclRefExpr>(PE->getSubExpr()) : nullptr)
13203 SubExpr = getDerived().TransformParenDependentScopeDeclRefExpr(
13204 PE, DRE, false, &RecoveryTSI);
13205 else
13206 SubExpr = getDerived().TransformExpr(E->getArgumentExpr());
13207
13208 if (RecoveryTSI) {
13209 return getDerived().RebuildUnaryExprOrTypeTrait(
13210 RecoveryTSI, E->getOperatorLoc(), E->getKind(), E->getSourceRange());
13211 } else if (SubExpr.isInvalid())
13212 return ExprError();
13213
13214 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getArgumentExpr())
13215 return E;
13216
13217 return getDerived().RebuildUnaryExprOrTypeTrait(SubExpr.get(),
13218 E->getOperatorLoc(),
13219 E->getKind(),
13220 E->getSourceRange());
13221}
13222
13223template<typename Derived>
13224ExprResult
13225TreeTransform<Derived>::TransformArraySubscriptExpr(ArraySubscriptExpr *E) {
13226 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13227 if (LHS.isInvalid())
13228 return ExprError();
13229
13230 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13231 if (RHS.isInvalid())
13232 return ExprError();
13233
13234
13235 if (!getDerived().AlwaysRebuild() &&
13236 LHS.get() == E->getLHS() &&
13237 RHS.get() == E->getRHS())
13238 return E;
13239
13240 return getDerived().RebuildArraySubscriptExpr(
13241 LHS.get(),
13242 /*FIXME:*/ E->getLHS()->getBeginLoc(), RHS.get(), E->getRBracketLoc());
13243}
13244
13245template <typename Derived>
13246ExprResult
13247TreeTransform<Derived>::TransformMatrixSubscriptExpr(MatrixSubscriptExpr *E) {
13248 ExprResult Base = getDerived().TransformExpr(E->getBase());
13249 if (Base.isInvalid())
13250 return ExprError();
13251
13252 ExprResult RowIdx = getDerived().TransformExpr(E->getRowIdx());
13253 if (RowIdx.isInvalid())
13254 return ExprError();
13255
13256 ExprResult ColumnIdx = getDerived().TransformExpr(E->getColumnIdx());
13257 if (ColumnIdx.isInvalid())
13258 return ExprError();
13259
13260 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13261 RowIdx.get() == E->getRowIdx() && ColumnIdx.get() == E->getColumnIdx())
13262 return E;
13263
13264 return getDerived().RebuildMatrixSubscriptExpr(
13265 Base.get(), RowIdx.get(), ColumnIdx.get(), E->getRBracketLoc());
13266}
13267
13268template <typename Derived>
13269ExprResult
13270TreeTransform<Derived>::TransformArraySectionExpr(ArraySectionExpr *E) {
13271 ExprResult Base = getDerived().TransformExpr(E->getBase());
13272 if (Base.isInvalid())
13273 return ExprError();
13274
13275 ExprResult LowerBound;
13276 if (E->getLowerBound()) {
13277 LowerBound = getDerived().TransformExpr(E->getLowerBound());
13278 if (LowerBound.isInvalid())
13279 return ExprError();
13280 }
13281
13282 ExprResult Length;
13283 if (E->getLength()) {
13284 Length = getDerived().TransformExpr(E->getLength());
13285 if (Length.isInvalid())
13286 return ExprError();
13287 }
13288
13289 ExprResult Stride;
13290 if (E->isOMPArraySection()) {
13291 if (Expr *Str = E->getStride()) {
13292 Stride = getDerived().TransformExpr(Str);
13293 if (Stride.isInvalid())
13294 return ExprError();
13295 }
13296 }
13297
13298 if (!getDerived().AlwaysRebuild() && Base.get() == E->getBase() &&
13299 LowerBound.get() == E->getLowerBound() &&
13300 Length.get() == E->getLength() &&
13301 (E->isOpenACCArraySection() || Stride.get() == E->getStride()))
13302 return E;
13303
13304 return getDerived().RebuildArraySectionExpr(
13305 E->isOMPArraySection(), Base.get(), E->getBase()->getEndLoc(),
13306 LowerBound.get(), E->getColonLocFirst(),
13307 E->isOMPArraySection() ? E->getColonLocSecond() : SourceLocation{},
13308 Length.get(), Stride.get(), E->getRBracketLoc());
13309}
13310
13311template <typename Derived>
13312ExprResult
13313TreeTransform<Derived>::TransformOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
13314 ExprResult Base = getDerived().TransformExpr(E->getBase());
13315 if (Base.isInvalid())
13316 return ExprError();
13317
13318 SmallVector<Expr *, 4> Dims;
13319 bool ErrorFound = false;
13320 for (Expr *Dim : E->getDimensions()) {
13321 ExprResult DimRes = getDerived().TransformExpr(Dim);
13322 if (DimRes.isInvalid()) {
13323 ErrorFound = true;
13324 continue;
13325 }
13326 Dims.push_back(Elt: DimRes.get());
13327 }
13328
13329 if (ErrorFound)
13330 return ExprError();
13331 return getDerived().RebuildOMPArrayShapingExpr(Base.get(), E->getLParenLoc(),
13332 E->getRParenLoc(), Dims,
13333 E->getBracketsRanges());
13334}
13335
13336template <typename Derived>
13337ExprResult
13338TreeTransform<Derived>::TransformOMPIteratorExpr(OMPIteratorExpr *E) {
13339 unsigned NumIterators = E->numOfIterators();
13340 SmallVector<SemaOpenMP::OMPIteratorData, 4> Data(NumIterators);
13341
13342 bool ErrorFound = false;
13343 bool NeedToRebuild = getDerived().AlwaysRebuild();
13344 for (unsigned I = 0; I < NumIterators; ++I) {
13345 auto *D = cast<VarDecl>(E->getIteratorDecl(I));
13346 Data[I].DeclIdent = D->getIdentifier();
13347 Data[I].DeclIdentLoc = D->getLocation();
13348 if (D->getLocation() == D->getBeginLoc()) {
13349 assert(SemaRef.Context.hasSameType(D->getType(), SemaRef.Context.IntTy) &&
13350 "Implicit type must be int.");
13351 } else {
13352 TypeSourceInfo *TSI = getDerived().TransformType(D->getTypeSourceInfo());
13353 QualType DeclTy = getDerived().TransformType(D->getType());
13354 Data[I].Type = SemaRef.CreateParsedType(T: DeclTy, TInfo: TSI);
13355 }
13356 OMPIteratorExpr::IteratorRange Range = E->getIteratorRange(I);
13357 ExprResult Begin = getDerived().TransformExpr(Range.Begin);
13358 ExprResult End = getDerived().TransformExpr(Range.End);
13359 ExprResult Step = getDerived().TransformExpr(Range.Step);
13360 ErrorFound = ErrorFound ||
13361 !(!D->getTypeSourceInfo() || (Data[I].Type.getAsOpaquePtr() &&
13362 !Data[I].Type.get().isNull())) ||
13363 Begin.isInvalid() || End.isInvalid() || Step.isInvalid();
13364 if (ErrorFound)
13365 continue;
13366 Data[I].Range.Begin = Begin.get();
13367 Data[I].Range.End = End.get();
13368 Data[I].Range.Step = Step.get();
13369 Data[I].AssignLoc = E->getAssignLoc(I);
13370 Data[I].ColonLoc = E->getColonLoc(I);
13371 Data[I].SecColonLoc = E->getSecondColonLoc(I);
13372 NeedToRebuild =
13373 NeedToRebuild ||
13374 (D->getTypeSourceInfo() && Data[I].Type.get().getTypePtrOrNull() !=
13375 D->getType().getTypePtrOrNull()) ||
13376 Range.Begin != Data[I].Range.Begin || Range.End != Data[I].Range.End ||
13377 Range.Step != Data[I].Range.Step;
13378 }
13379 if (ErrorFound)
13380 return ExprError();
13381 if (!NeedToRebuild)
13382 return E;
13383
13384 ExprResult Res = getDerived().RebuildOMPIteratorExpr(
13385 E->getIteratorKwLoc(), E->getLParenLoc(), E->getRParenLoc(), Data);
13386 if (!Res.isUsable())
13387 return Res;
13388 auto *IE = cast<OMPIteratorExpr>(Res.get());
13389 for (unsigned I = 0; I < NumIterators; ++I)
13390 getDerived().transformedLocalDecl(E->getIteratorDecl(I),
13391 IE->getIteratorDecl(I));
13392 return Res;
13393}
13394
13395template<typename Derived>
13396ExprResult
13397TreeTransform<Derived>::TransformCallExpr(CallExpr *E) {
13398 // Transform the callee.
13399 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
13400 if (Callee.isInvalid())
13401 return ExprError();
13402
13403 // Transform arguments.
13404 bool ArgChanged = false;
13405 SmallVector<Expr*, 8> Args;
13406 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
13407 &ArgChanged))
13408 return ExprError();
13409
13410 if (!getDerived().AlwaysRebuild() &&
13411 Callee.get() == E->getCallee() &&
13412 !ArgChanged)
13413 return SemaRef.MaybeBindToTemporary(E);
13414
13415 // FIXME: Wrong source location information for the '('.
13416 SourceLocation FakeLParenLoc
13417 = ((Expr *)Callee.get())->getSourceRange().getBegin();
13418
13419 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13420 if (E->hasStoredFPFeatures()) {
13421 FPOptionsOverride NewOverrides = E->getFPFeatures();
13422 getSema().CurFPFeatures =
13423 NewOverrides.applyOverrides(getSema().getLangOpts());
13424 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13425 }
13426
13427 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
13428 Args,
13429 E->getRParenLoc());
13430}
13431
13432template<typename Derived>
13433ExprResult
13434TreeTransform<Derived>::TransformMemberExpr(MemberExpr *E) {
13435 ExprResult Base = getDerived().TransformExpr(E->getBase());
13436 if (Base.isInvalid())
13437 return ExprError();
13438
13439 NestedNameSpecifierLoc QualifierLoc;
13440 if (E->hasQualifier()) {
13441 QualifierLoc
13442 = getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
13443
13444 if (!QualifierLoc)
13445 return ExprError();
13446 }
13447 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
13448
13449 ValueDecl *Member
13450 = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
13451 E->getMemberDecl()));
13452 if (!Member)
13453 return ExprError();
13454
13455 NamedDecl *FoundDecl = E->getFoundDecl();
13456 if (FoundDecl == E->getMemberDecl()) {
13457 FoundDecl = Member;
13458 } else {
13459 FoundDecl = cast_or_null<NamedDecl>(
13460 getDerived().TransformDecl(E->getMemberLoc(), FoundDecl));
13461 if (!FoundDecl)
13462 return ExprError();
13463 }
13464
13465 if (!getDerived().AlwaysRebuild() &&
13466 Base.get() == E->getBase() &&
13467 QualifierLoc == E->getQualifierLoc() &&
13468 Member == E->getMemberDecl() &&
13469 FoundDecl == E->getFoundDecl() &&
13470 !E->hasExplicitTemplateArgs()) {
13471
13472 // Skip for member expression of (this->f), rebuilt thisi->f is needed
13473 // for Openmp where the field need to be privatizized in the case.
13474 if (!(isa<CXXThisExpr>(E->getBase()) &&
13475 getSema().OpenMP().isOpenMPRebuildMemberExpr(
13476 cast<ValueDecl>(Member)))) {
13477 // Mark it referenced in the new context regardless.
13478 // FIXME: this is a bit instantiation-specific.
13479 SemaRef.MarkMemberReferenced(E);
13480 return E;
13481 }
13482 }
13483
13484 TemplateArgumentListInfo TransArgs;
13485 if (E->hasExplicitTemplateArgs()) {
13486 TransArgs.setLAngleLoc(E->getLAngleLoc());
13487 TransArgs.setRAngleLoc(E->getRAngleLoc());
13488 if (getDerived().TransformTemplateArguments(E->getTemplateArgs(),
13489 E->getNumTemplateArgs(),
13490 TransArgs))
13491 return ExprError();
13492 }
13493
13494 // FIXME: Bogus source location for the operator
13495 SourceLocation FakeOperatorLoc =
13496 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getSourceRange().getEnd());
13497
13498 // FIXME: to do this check properly, we will need to preserve the
13499 // first-qualifier-in-scope here, just in case we had a dependent
13500 // base (and therefore couldn't do the check) and a
13501 // nested-name-qualifier (and therefore could do the lookup).
13502 NamedDecl *FirstQualifierInScope = nullptr;
13503 DeclarationNameInfo MemberNameInfo = E->getMemberNameInfo();
13504 if (MemberNameInfo.getName()) {
13505 MemberNameInfo = getDerived().TransformDeclarationNameInfo(MemberNameInfo);
13506 if (!MemberNameInfo.getName())
13507 return ExprError();
13508 }
13509
13510 return getDerived().RebuildMemberExpr(Base.get(), FakeOperatorLoc,
13511 E->isArrow(),
13512 QualifierLoc,
13513 TemplateKWLoc,
13514 MemberNameInfo,
13515 Member,
13516 FoundDecl,
13517 (E->hasExplicitTemplateArgs()
13518 ? &TransArgs : nullptr),
13519 FirstQualifierInScope);
13520}
13521
13522template<typename Derived>
13523ExprResult
13524TreeTransform<Derived>::TransformBinaryOperator(BinaryOperator *E) {
13525 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13526 if (LHS.isInvalid())
13527 return ExprError();
13528
13529 ExprResult RHS =
13530 getDerived().TransformInitializer(E->getRHS(), /*NotCopyInit=*/false);
13531 if (RHS.isInvalid())
13532 return ExprError();
13533
13534 if (!getDerived().AlwaysRebuild() &&
13535 LHS.get() == E->getLHS() &&
13536 RHS.get() == E->getRHS())
13537 return E;
13538
13539 if (E->isCompoundAssignmentOp())
13540 // FPFeatures has already been established from trailing storage
13541 return getDerived().RebuildBinaryOperator(
13542 E->getOperatorLoc(), E->getOpcode(), LHS.get(), RHS.get());
13543 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13544 FPOptionsOverride NewOverrides(E->getFPFeatures());
13545 getSema().CurFPFeatures =
13546 NewOverrides.applyOverrides(getSema().getLangOpts());
13547 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13548 return getDerived().RebuildBinaryOperator(E->getOperatorLoc(), E->getOpcode(),
13549 LHS.get(), RHS.get());
13550}
13551
13552template <typename Derived>
13553ExprResult TreeTransform<Derived>::TransformCXXRewrittenBinaryOperator(
13554 CXXRewrittenBinaryOperator *E) {
13555 CXXRewrittenBinaryOperator::DecomposedForm Decomp = E->getDecomposedForm();
13556
13557 ExprResult LHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.LHS));
13558 if (LHS.isInvalid())
13559 return ExprError();
13560
13561 ExprResult RHS = getDerived().TransformExpr(const_cast<Expr*>(Decomp.RHS));
13562 if (RHS.isInvalid())
13563 return ExprError();
13564
13565 // Extract the already-resolved callee declarations so that we can restrict
13566 // ourselves to using them as the unqualified lookup results when rebuilding.
13567 UnresolvedSet<2> UnqualLookups;
13568 bool ChangedAnyLookups = false;
13569 Expr *PossibleBinOps[] = {E->getSemanticForm(),
13570 const_cast<Expr *>(Decomp.InnerBinOp)};
13571 for (Expr *PossibleBinOp : PossibleBinOps) {
13572 auto *Op = dyn_cast<CXXOperatorCallExpr>(PossibleBinOp->IgnoreImplicit());
13573 if (!Op)
13574 continue;
13575 auto *Callee = dyn_cast<DeclRefExpr>(Op->getCallee()->IgnoreImplicit());
13576 if (!Callee || isa<CXXMethodDecl>(Callee->getDecl()))
13577 continue;
13578
13579 // Transform the callee in case we built a call to a local extern
13580 // declaration.
13581 NamedDecl *Found = cast_or_null<NamedDecl>(getDerived().TransformDecl(
13582 E->getOperatorLoc(), Callee->getFoundDecl()));
13583 if (!Found)
13584 return ExprError();
13585 if (Found != Callee->getFoundDecl())
13586 ChangedAnyLookups = true;
13587 UnqualLookups.addDecl(Found);
13588 }
13589
13590 if (!getDerived().AlwaysRebuild() && !ChangedAnyLookups &&
13591 LHS.get() == Decomp.LHS && RHS.get() == Decomp.RHS) {
13592 // Mark all functions used in the rewrite as referenced. Note that when
13593 // a < b is rewritten to (a <=> b) < 0, both the <=> and the < might be
13594 // function calls, and/or there might be a user-defined conversion sequence
13595 // applied to the operands of the <.
13596 // FIXME: this is a bit instantiation-specific.
13597 const Expr *StopAt[] = {Decomp.LHS, Decomp.RHS};
13598 SemaRef.MarkDeclarationsReferencedInExpr(E, false, StopAt);
13599 return E;
13600 }
13601
13602 return getDerived().RebuildCXXRewrittenBinaryOperator(
13603 E->getOperatorLoc(), Decomp.Opcode, UnqualLookups, LHS.get(), RHS.get());
13604}
13605
13606template<typename Derived>
13607ExprResult
13608TreeTransform<Derived>::TransformCompoundAssignOperator(
13609 CompoundAssignOperator *E) {
13610 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
13611 FPOptionsOverride NewOverrides(E->getFPFeatures());
13612 getSema().CurFPFeatures =
13613 NewOverrides.applyOverrides(getSema().getLangOpts());
13614 getSema().FpPragmaStack.CurrentValue = NewOverrides;
13615 return getDerived().TransformBinaryOperator(E);
13616}
13617
13618template<typename Derived>
13619ExprResult TreeTransform<Derived>::
13620TransformBinaryConditionalOperator(BinaryConditionalOperator *e) {
13621 // Just rebuild the common and RHS expressions and see whether we
13622 // get any changes.
13623
13624 ExprResult commonExpr = getDerived().TransformExpr(e->getCommon());
13625 if (commonExpr.isInvalid())
13626 return ExprError();
13627
13628 ExprResult rhs = getDerived().TransformExpr(e->getFalseExpr());
13629 if (rhs.isInvalid())
13630 return ExprError();
13631
13632 if (!getDerived().AlwaysRebuild() &&
13633 commonExpr.get() == e->getCommon() &&
13634 rhs.get() == e->getFalseExpr())
13635 return e;
13636
13637 return getDerived().RebuildConditionalOperator(commonExpr.get(),
13638 e->getQuestionLoc(),
13639 nullptr,
13640 e->getColonLoc(),
13641 rhs.get());
13642}
13643
13644template<typename Derived>
13645ExprResult
13646TreeTransform<Derived>::TransformConditionalOperator(ConditionalOperator *E) {
13647 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13648 if (Cond.isInvalid())
13649 return ExprError();
13650
13651 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13652 if (LHS.isInvalid())
13653 return ExprError();
13654
13655 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13656 if (RHS.isInvalid())
13657 return ExprError();
13658
13659 if (!getDerived().AlwaysRebuild() &&
13660 Cond.get() == E->getCond() &&
13661 LHS.get() == E->getLHS() &&
13662 RHS.get() == E->getRHS())
13663 return E;
13664
13665 return getDerived().RebuildConditionalOperator(Cond.get(),
13666 E->getQuestionLoc(),
13667 LHS.get(),
13668 E->getColonLoc(),
13669 RHS.get());
13670}
13671
13672template<typename Derived>
13673ExprResult
13674TreeTransform<Derived>::TransformImplicitCastExpr(ImplicitCastExpr *E) {
13675 // Implicit casts are eliminated during transformation, since they
13676 // will be recomputed by semantic analysis after transformation.
13677 return getDerived().TransformExpr(E->getSubExprAsWritten());
13678}
13679
13680template<typename Derived>
13681ExprResult
13682TreeTransform<Derived>::TransformCStyleCastExpr(CStyleCastExpr *E) {
13683 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
13684 if (!Type)
13685 return ExprError();
13686
13687 ExprResult SubExpr
13688 = getDerived().TransformExpr(E->getSubExprAsWritten());
13689 if (SubExpr.isInvalid())
13690 return ExprError();
13691
13692 if (!getDerived().AlwaysRebuild() &&
13693 Type == E->getTypeInfoAsWritten() &&
13694 SubExpr.get() == E->getSubExpr())
13695 return E;
13696
13697 return getDerived().RebuildCStyleCastExpr(E->getLParenLoc(),
13698 Type,
13699 E->getRParenLoc(),
13700 SubExpr.get());
13701}
13702
13703template<typename Derived>
13704ExprResult
13705TreeTransform<Derived>::TransformCompoundLiteralExpr(CompoundLiteralExpr *E) {
13706 TypeSourceInfo *OldT = E->getTypeSourceInfo();
13707 TypeSourceInfo *NewT = getDerived().TransformType(OldT);
13708 if (!NewT)
13709 return ExprError();
13710
13711 ExprResult Init = getDerived().TransformExpr(E->getInitializer());
13712 if (Init.isInvalid())
13713 return ExprError();
13714
13715 if (!getDerived().AlwaysRebuild() &&
13716 OldT == NewT &&
13717 Init.get() == E->getInitializer())
13718 return SemaRef.MaybeBindToTemporary(E);
13719
13720 // Note: the expression type doesn't necessarily match the
13721 // type-as-written, but that's okay, because it should always be
13722 // derivable from the initializer.
13723
13724 return getDerived().RebuildCompoundLiteralExpr(
13725 E->getLParenLoc(), NewT,
13726 /*FIXME:*/ E->getInitializer()->getEndLoc(), Init.get());
13727}
13728
13729template<typename Derived>
13730ExprResult
13731TreeTransform<Derived>::TransformExtVectorElementExpr(ExtVectorElementExpr *E) {
13732 ExprResult Base = getDerived().TransformExpr(E->getBase());
13733 if (Base.isInvalid())
13734 return ExprError();
13735
13736 if (!getDerived().AlwaysRebuild() &&
13737 Base.get() == E->getBase())
13738 return E;
13739
13740 // FIXME: Bad source location
13741 SourceLocation FakeOperatorLoc =
13742 SemaRef.getLocForEndOfToken(Loc: E->getBase()->getEndLoc());
13743 return getDerived().RebuildExtVectorElementExpr(
13744 Base.get(), FakeOperatorLoc, E->isArrow(), E->getAccessorLoc(),
13745 E->getAccessor());
13746}
13747
13748template<typename Derived>
13749ExprResult
13750TreeTransform<Derived>::TransformInitListExpr(InitListExpr *E) {
13751 if (InitListExpr *Syntactic = E->getSyntacticForm())
13752 E = Syntactic;
13753
13754 bool InitChanged = false;
13755
13756 EnterExpressionEvaluationContext Context(
13757 getSema(), EnterExpressionEvaluationContext::InitList);
13758
13759 SmallVector<Expr*, 4> Inits;
13760 if (getDerived().TransformExprs(E->getInits(), E->getNumInits(), false,
13761 Inits, &InitChanged))
13762 return ExprError();
13763
13764 if (!getDerived().AlwaysRebuild() && !InitChanged) {
13765 // FIXME: Attempt to reuse the existing syntactic form of the InitListExpr
13766 // in some cases. We can't reuse it in general, because the syntactic and
13767 // semantic forms are linked, and we can't know that semantic form will
13768 // match even if the syntactic form does.
13769 }
13770
13771 return getDerived().RebuildInitList(E->getLBraceLoc(), Inits,
13772 E->getRBraceLoc());
13773}
13774
13775template<typename Derived>
13776ExprResult
13777TreeTransform<Derived>::TransformDesignatedInitExpr(DesignatedInitExpr *E) {
13778 Designation Desig;
13779
13780 // transform the initializer value
13781 ExprResult Init = getDerived().TransformExpr(E->getInit());
13782 if (Init.isInvalid())
13783 return ExprError();
13784
13785 // transform the designators.
13786 SmallVector<Expr*, 4> ArrayExprs;
13787 bool ExprChanged = false;
13788 for (const DesignatedInitExpr::Designator &D : E->designators()) {
13789 if (D.isFieldDesignator()) {
13790 if (D.getFieldDecl()) {
13791 FieldDecl *Field = cast_or_null<FieldDecl>(
13792 getDerived().TransformDecl(D.getFieldLoc(), D.getFieldDecl()));
13793 if (Field != D.getFieldDecl())
13794 // Rebuild the expression when the transformed FieldDecl is
13795 // different to the already assigned FieldDecl.
13796 ExprChanged = true;
13797 if (Field->isAnonymousStructOrUnion())
13798 continue;
13799 } else {
13800 // Ensure that the designator expression is rebuilt when there isn't
13801 // a resolved FieldDecl in the designator as we don't want to assign
13802 // a FieldDecl to a pattern designator that will be instantiated again.
13803 ExprChanged = true;
13804 }
13805 Desig.AddDesignator(Designator::CreateFieldDesignator(
13806 D.getFieldName(), D.getDotLoc(), D.getFieldLoc()));
13807 continue;
13808 }
13809
13810 if (D.isArrayDesignator()) {
13811 ExprResult Index = getDerived().TransformExpr(E->getArrayIndex(D));
13812 if (Index.isInvalid())
13813 return ExprError();
13814
13815 Desig.AddDesignator(
13816 Designator::CreateArrayDesignator(Index.get(), D.getLBracketLoc()));
13817
13818 ExprChanged = ExprChanged || Index.get() != E->getArrayIndex(D);
13819 ArrayExprs.push_back(Index.get());
13820 continue;
13821 }
13822
13823 assert(D.isArrayRangeDesignator() && "New kind of designator?");
13824 ExprResult Start
13825 = getDerived().TransformExpr(E->getArrayRangeStart(D));
13826 if (Start.isInvalid())
13827 return ExprError();
13828
13829 ExprResult End = getDerived().TransformExpr(E->getArrayRangeEnd(D));
13830 if (End.isInvalid())
13831 return ExprError();
13832
13833 Desig.AddDesignator(Designator::CreateArrayRangeDesignator(
13834 Start.get(), End.get(), D.getLBracketLoc(), D.getEllipsisLoc()));
13835
13836 ExprChanged = ExprChanged || Start.get() != E->getArrayRangeStart(D) ||
13837 End.get() != E->getArrayRangeEnd(D);
13838
13839 ArrayExprs.push_back(Start.get());
13840 ArrayExprs.push_back(End.get());
13841 }
13842
13843 if (!getDerived().AlwaysRebuild() &&
13844 Init.get() == E->getInit() &&
13845 !ExprChanged)
13846 return E;
13847
13848 return getDerived().RebuildDesignatedInitExpr(Desig, ArrayExprs,
13849 E->getEqualOrColonLoc(),
13850 E->usesGNUSyntax(), Init.get());
13851}
13852
13853// Seems that if TransformInitListExpr() only works on the syntactic form of an
13854// InitListExpr, then a DesignatedInitUpdateExpr is not encountered.
13855template<typename Derived>
13856ExprResult
13857TreeTransform<Derived>::TransformDesignatedInitUpdateExpr(
13858 DesignatedInitUpdateExpr *E) {
13859 llvm_unreachable("Unexpected DesignatedInitUpdateExpr in syntactic form of "
13860 "initializer");
13861 return ExprError();
13862}
13863
13864template<typename Derived>
13865ExprResult
13866TreeTransform<Derived>::TransformNoInitExpr(
13867 NoInitExpr *E) {
13868 llvm_unreachable("Unexpected NoInitExpr in syntactic form of initializer");
13869 return ExprError();
13870}
13871
13872template<typename Derived>
13873ExprResult
13874TreeTransform<Derived>::TransformArrayInitLoopExpr(ArrayInitLoopExpr *E) {
13875 llvm_unreachable("Unexpected ArrayInitLoopExpr outside of initializer");
13876 return ExprError();
13877}
13878
13879template<typename Derived>
13880ExprResult
13881TreeTransform<Derived>::TransformArrayInitIndexExpr(ArrayInitIndexExpr *E) {
13882 llvm_unreachable("Unexpected ArrayInitIndexExpr outside of initializer");
13883 return ExprError();
13884}
13885
13886template<typename Derived>
13887ExprResult
13888TreeTransform<Derived>::TransformImplicitValueInitExpr(
13889 ImplicitValueInitExpr *E) {
13890 TemporaryBase Rebase(*this, E->getBeginLoc(), DeclarationName());
13891
13892 // FIXME: Will we ever have proper type location here? Will we actually
13893 // need to transform the type?
13894 QualType T = getDerived().TransformType(E->getType());
13895 if (T.isNull())
13896 return ExprError();
13897
13898 if (!getDerived().AlwaysRebuild() &&
13899 T == E->getType())
13900 return E;
13901
13902 return getDerived().RebuildImplicitValueInitExpr(T);
13903}
13904
13905template<typename Derived>
13906ExprResult
13907TreeTransform<Derived>::TransformVAArgExpr(VAArgExpr *E) {
13908 TypeSourceInfo *TInfo = getDerived().TransformType(E->getWrittenTypeInfo());
13909 if (!TInfo)
13910 return ExprError();
13911
13912 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
13913 if (SubExpr.isInvalid())
13914 return ExprError();
13915
13916 if (!getDerived().AlwaysRebuild() &&
13917 TInfo == E->getWrittenTypeInfo() &&
13918 SubExpr.get() == E->getSubExpr())
13919 return E;
13920
13921 return getDerived().RebuildVAArgExpr(E->getBuiltinLoc(), SubExpr.get(),
13922 TInfo, E->getRParenLoc());
13923}
13924
13925template<typename Derived>
13926ExprResult
13927TreeTransform<Derived>::TransformParenListExpr(ParenListExpr *E) {
13928 bool ArgumentChanged = false;
13929 SmallVector<Expr*, 4> Inits;
13930 if (TransformExprs(Inputs: E->getExprs(), NumInputs: E->getNumExprs(), IsCall: true, Outputs&: Inits,
13931 ArgChanged: &ArgumentChanged))
13932 return ExprError();
13933
13934 return getDerived().RebuildParenListExpr(E->getLParenLoc(),
13935 Inits,
13936 E->getRParenLoc());
13937}
13938
13939/// Transform an address-of-label expression.
13940///
13941/// By default, the transformation of an address-of-label expression always
13942/// rebuilds the expression, so that the label identifier can be resolved to
13943/// the corresponding label statement by semantic analysis.
13944template<typename Derived>
13945ExprResult
13946TreeTransform<Derived>::TransformAddrLabelExpr(AddrLabelExpr *E) {
13947 Decl *LD = getDerived().TransformDecl(E->getLabel()->getLocation(),
13948 E->getLabel());
13949 if (!LD)
13950 return ExprError();
13951
13952 return getDerived().RebuildAddrLabelExpr(E->getAmpAmpLoc(), E->getLabelLoc(),
13953 cast<LabelDecl>(LD));
13954}
13955
13956template<typename Derived>
13957ExprResult
13958TreeTransform<Derived>::TransformStmtExpr(StmtExpr *E) {
13959 SemaRef.ActOnStartStmtExpr();
13960 StmtResult SubStmt
13961 = getDerived().TransformCompoundStmt(E->getSubStmt(), true);
13962 if (SubStmt.isInvalid()) {
13963 SemaRef.ActOnStmtExprError();
13964 return ExprError();
13965 }
13966
13967 unsigned OldDepth = E->getTemplateDepth();
13968 unsigned NewDepth = getDerived().TransformTemplateDepth(OldDepth);
13969
13970 if (!getDerived().AlwaysRebuild() && OldDepth == NewDepth &&
13971 SubStmt.get() == E->getSubStmt()) {
13972 // Calling this an 'error' is unintuitive, but it does the right thing.
13973 SemaRef.ActOnStmtExprError();
13974 return SemaRef.MaybeBindToTemporary(E);
13975 }
13976
13977 return getDerived().RebuildStmtExpr(E->getLParenLoc(), SubStmt.get(),
13978 E->getRParenLoc(), NewDepth);
13979}
13980
13981template<typename Derived>
13982ExprResult
13983TreeTransform<Derived>::TransformChooseExpr(ChooseExpr *E) {
13984 ExprResult Cond = getDerived().TransformExpr(E->getCond());
13985 if (Cond.isInvalid())
13986 return ExprError();
13987
13988 ExprResult LHS = getDerived().TransformExpr(E->getLHS());
13989 if (LHS.isInvalid())
13990 return ExprError();
13991
13992 ExprResult RHS = getDerived().TransformExpr(E->getRHS());
13993 if (RHS.isInvalid())
13994 return ExprError();
13995
13996 if (!getDerived().AlwaysRebuild() &&
13997 Cond.get() == E->getCond() &&
13998 LHS.get() == E->getLHS() &&
13999 RHS.get() == E->getRHS())
14000 return E;
14001
14002 return getDerived().RebuildChooseExpr(E->getBuiltinLoc(),
14003 Cond.get(), LHS.get(), RHS.get(),
14004 E->getRParenLoc());
14005}
14006
14007template<typename Derived>
14008ExprResult
14009TreeTransform<Derived>::TransformGNUNullExpr(GNUNullExpr *E) {
14010 return E;
14011}
14012
14013template<typename Derived>
14014ExprResult
14015TreeTransform<Derived>::TransformCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
14016 switch (E->getOperator()) {
14017 case OO_New:
14018 case OO_Delete:
14019 case OO_Array_New:
14020 case OO_Array_Delete:
14021 llvm_unreachable("new and delete operators cannot use CXXOperatorCallExpr");
14022
14023 case OO_Subscript:
14024 case OO_Call: {
14025 // This is a call to an object's operator().
14026 assert(E->getNumArgs() >= 1 && "Object call is missing arguments");
14027
14028 // Transform the object itself.
14029 ExprResult Object = getDerived().TransformExpr(E->getArg(0));
14030 if (Object.isInvalid())
14031 return ExprError();
14032
14033 // FIXME: Poor location information
14034 SourceLocation FakeLParenLoc = SemaRef.getLocForEndOfToken(
14035 Loc: static_cast<Expr *>(Object.get())->getEndLoc());
14036
14037 // Transform the call arguments.
14038 SmallVector<Expr*, 8> Args;
14039 if (getDerived().TransformExprs(E->getArgs() + 1, E->getNumArgs() - 1, true,
14040 Args))
14041 return ExprError();
14042
14043 if (E->getOperator() == OO_Subscript)
14044 return getDerived().RebuildCxxSubscriptExpr(Object.get(), FakeLParenLoc,
14045 Args, E->getEndLoc());
14046
14047 return getDerived().RebuildCallExpr(Object.get(), FakeLParenLoc, Args,
14048 E->getEndLoc());
14049 }
14050
14051#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemberOnly) \
14052 case OO_##Name: \
14053 break;
14054
14055#define OVERLOADED_OPERATOR_MULTI(Name,Spelling,Unary,Binary,MemberOnly)
14056#include "clang/Basic/OperatorKinds.def"
14057
14058 case OO_Conditional:
14059 llvm_unreachable("conditional operator is not actually overloadable");
14060
14061 case OO_None:
14062 case NUM_OVERLOADED_OPERATORS:
14063 llvm_unreachable("not an overloaded operator?");
14064 }
14065
14066 ExprResult First;
14067 if (E->getNumArgs() == 1 && E->getOperator() == OO_Amp)
14068 First = getDerived().TransformAddressOfOperand(E->getArg(0));
14069 else
14070 First = getDerived().TransformExpr(E->getArg(0));
14071 if (First.isInvalid())
14072 return ExprError();
14073
14074 ExprResult Second;
14075 if (E->getNumArgs() == 2) {
14076 Second =
14077 getDerived().TransformInitializer(E->getArg(1), /*NotCopyInit=*/false);
14078 if (Second.isInvalid())
14079 return ExprError();
14080 }
14081
14082 Sema::FPFeaturesStateRAII FPFeaturesState(getSema());
14083 FPOptionsOverride NewOverrides(E->getFPFeatures());
14084 getSema().CurFPFeatures =
14085 NewOverrides.applyOverrides(getSema().getLangOpts());
14086 getSema().FpPragmaStack.CurrentValue = NewOverrides;
14087
14088 Expr *Callee = E->getCallee();
14089 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(Callee)) {
14090 LookupResult R(SemaRef, ULE->getName(), ULE->getNameLoc(),
14091 Sema::LookupOrdinaryName);
14092 if (getDerived().TransformOverloadExprDecls(ULE, ULE->requiresADL(), R))
14093 return ExprError();
14094
14095 return getDerived().RebuildCXXOperatorCallExpr(
14096 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14097 ULE->requiresADL(), R.asUnresolvedSet(), First.get(), Second.get());
14098 }
14099
14100 UnresolvedSet<1> Functions;
14101 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
14102 Callee = ICE->getSubExprAsWritten();
14103 NamedDecl *DR = cast<DeclRefExpr>(Callee)->getDecl();
14104 ValueDecl *VD = cast_or_null<ValueDecl>(
14105 getDerived().TransformDecl(DR->getLocation(), DR));
14106 if (!VD)
14107 return ExprError();
14108
14109 if (!isa<CXXMethodDecl>(VD))
14110 Functions.addDecl(VD);
14111
14112 return getDerived().RebuildCXXOperatorCallExpr(
14113 E->getOperator(), E->getOperatorLoc(), Callee->getBeginLoc(),
14114 /*RequiresADL=*/false, Functions, First.get(), Second.get());
14115}
14116
14117template<typename Derived>
14118ExprResult
14119TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) {
14120 return getDerived().TransformCallExpr(E);
14121}
14122
14123template <typename Derived>
14124ExprResult TreeTransform<Derived>::TransformSourceLocExpr(SourceLocExpr *E) {
14125 bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(Kind: E->getIdentKind()) &&
14126 getSema().CurContext != E->getParentContext();
14127
14128 if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc)
14129 return E;
14130
14131 return getDerived().RebuildSourceLocExpr(E->getIdentKind(), E->getType(),
14132 E->getBeginLoc(), E->getEndLoc(),
14133 getSema().CurContext);
14134}
14135
14136template <typename Derived>
14137ExprResult TreeTransform<Derived>::TransformEmbedExpr(EmbedExpr *E) {
14138 return E;
14139}
14140
14141template<typename Derived>
14142ExprResult
14143TreeTransform<Derived>::TransformCUDAKernelCallExpr(CUDAKernelCallExpr *E) {
14144 // Transform the callee.
14145 ExprResult Callee = getDerived().TransformExpr(E->getCallee());
14146 if (Callee.isInvalid())
14147 return ExprError();
14148
14149 // Transform exec config.
14150 ExprResult EC = getDerived().TransformCallExpr(E->getConfig());
14151 if (EC.isInvalid())
14152 return ExprError();
14153
14154 // Transform arguments.
14155 bool ArgChanged = false;
14156 SmallVector<Expr*, 8> Args;
14157 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
14158 &ArgChanged))
14159 return ExprError();
14160
14161 if (!getDerived().AlwaysRebuild() &&
14162 Callee.get() == E->getCallee() &&
14163 !ArgChanged)
14164 return SemaRef.MaybeBindToTemporary(E);
14165
14166 // FIXME: Wrong source location information for the '('.
14167 SourceLocation FakeLParenLoc
14168 = ((Expr *)Callee.get())->getSourceRange().getBegin();
14169 return getDerived().RebuildCallExpr(Callee.get(), FakeLParenLoc,
14170 Args,
14171 E->getRParenLoc(), EC.get());
14172}
14173
14174template<typename Derived>
14175ExprResult
14176TreeTransform<Derived>::TransformCXXNamedCastExpr(CXXNamedCastExpr *E) {
14177 TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
14178 if (!Type)
14179 return ExprError();
14180
14181 ExprResult SubExpr
14182 = getDerived().TransformExpr(E->getSubExprAsWritten());
14183 if (SubExpr.isInvalid())
14184 return ExprError();
14185
14186 if (!getDerived().AlwaysRebuild() &&
14187 Type == E->getTypeInfoAsWritten() &&
14188 SubExpr.get() == E->getSubExpr())
14189 return E;
14190 return getDerived().RebuildCXXNamedCastExpr(
14191 E->getOperatorLoc(), E->getStmtClass(), E->getAngleBrackets().getBegin(),
14192 Type, E->getAngleBrackets().getEnd(),
14193 // FIXME. this should be '(' location
14194 E->getAngleBrackets().getEnd(), SubExpr.get(), E->getRParenLoc());
14195}
14196
14197template<typename Derived>
14198ExprResult
14199TreeTransform<Derived>::TransformBuiltinBitCastExpr(BuiltinBitCastExpr *BCE) {
14200 TypeSourceInfo *TSI =
14201 getDerived().TransformType(BCE->getTypeInfoAsWritten());
14202 if (!TSI)
14203 return ExprError();
14204
14205 ExprResult Sub = getDerived().TransformExpr(BCE->getSubExpr());
14206 if (Sub.isInvalid())
14207 return ExprError();
14208
14209 return getDerived().RebuildBuiltinBitCastExpr(BCE->getBeginLoc(), TSI,
14210 Sub.get(), BCE->getEndLoc());
14211}
14212
14213template<typename Derived>
14214ExprResult
14215TreeTransform<Derived>::TransformCXXStaticCastExpr(CXXStaticCastExpr *E) {
14216 return getDerived().TransformCXXNamedCastExpr(E);
14217}
14218
14219template<typename Derived>
14220ExprResult
14221TreeTransform<Derived>::TransformCXXDynamicCastExpr(CXXDynamicCastExpr *E) {
14222 return getDerived().TransformCXXNamedCastExpr(E);
14223}
14224
14225template<typename Derived>
14226ExprResult
14227TreeTransform<Derived>::TransformCXXReinterpretCastExpr(
14228 CXXReinterpretCastExpr *E) {
14229 return getDerived().TransformCXXNamedCastExpr(E);
14230}
14231
14232template<typename Derived>
14233ExprResult
14234TreeTransform<Derived>::TransformCXXConstCastExpr(CXXConstCastExpr *E) {
14235 return getDerived().TransformCXXNamedCastExpr(E);
14236}
14237
14238template<typename Derived>
14239ExprResult
14240TreeTransform<Derived>::TransformCXXAddrspaceCastExpr(CXXAddrspaceCastExpr *E) {
14241 return getDerived().TransformCXXNamedCastExpr(E);
14242}
14243
14244template<typename Derived>
14245ExprResult
14246TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
14247 CXXFunctionalCastExpr *E) {
14248 TypeSourceInfo *Type =
14249 getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
14250 if (!Type)
14251 return ExprError();
14252
14253 ExprResult SubExpr
14254 = getDerived().TransformExpr(E->getSubExprAsWritten());
14255 if (SubExpr.isInvalid())
14256 return ExprError();
14257
14258 if (!getDerived().AlwaysRebuild() &&
14259 Type == E->getTypeInfoAsWritten() &&
14260 SubExpr.get() == E->getSubExpr())
14261 return E;
14262
14263 return getDerived().RebuildCXXFunctionalCastExpr(Type,
14264 E->getLParenLoc(),
14265 SubExpr.get(),
14266 E->getRParenLoc(),
14267 E->isListInitialization());
14268}
14269
14270template<typename Derived>
14271ExprResult
14272TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
14273 if (E->isTypeOperand()) {
14274 TypeSourceInfo *TInfo
14275 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14276 if (!TInfo)
14277 return ExprError();
14278
14279 if (!getDerived().AlwaysRebuild() &&
14280 TInfo == E->getTypeOperandSourceInfo())
14281 return E;
14282
14283 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14284 TInfo, E->getEndLoc());
14285 }
14286
14287 // Typeid's operand is an unevaluated context, unless it's a polymorphic
14288 // type. We must not unilaterally enter unevaluated context here, as then
14289 // semantic processing can re-transform an already transformed operand.
14290 Expr *Op = E->getExprOperand();
14291 auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
14292 if (E->isGLValue())
14293 if (auto *RecordT = Op->getType()->getAs<RecordType>())
14294 if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
14295 EvalCtx = SemaRef.ExprEvalContexts.back().Context;
14296
14297 EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
14298 Sema::ReuseLambdaContextDecl);
14299
14300 ExprResult SubExpr = getDerived().TransformExpr(Op);
14301 if (SubExpr.isInvalid())
14302 return ExprError();
14303
14304 if (!getDerived().AlwaysRebuild() &&
14305 SubExpr.get() == E->getExprOperand())
14306 return E;
14307
14308 return getDerived().RebuildCXXTypeidExpr(E->getType(), E->getBeginLoc(),
14309 SubExpr.get(), E->getEndLoc());
14310}
14311
14312template<typename Derived>
14313ExprResult
14314TreeTransform<Derived>::TransformCXXUuidofExpr(CXXUuidofExpr *E) {
14315 if (E->isTypeOperand()) {
14316 TypeSourceInfo *TInfo
14317 = getDerived().TransformType(E->getTypeOperandSourceInfo());
14318 if (!TInfo)
14319 return ExprError();
14320
14321 if (!getDerived().AlwaysRebuild() &&
14322 TInfo == E->getTypeOperandSourceInfo())
14323 return E;
14324
14325 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14326 TInfo, E->getEndLoc());
14327 }
14328
14329 EnterExpressionEvaluationContext Unevaluated(
14330 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
14331
14332 ExprResult SubExpr = getDerived().TransformExpr(E->getExprOperand());
14333 if (SubExpr.isInvalid())
14334 return ExprError();
14335
14336 if (!getDerived().AlwaysRebuild() &&
14337 SubExpr.get() == E->getExprOperand())
14338 return E;
14339
14340 return getDerived().RebuildCXXUuidofExpr(E->getType(), E->getBeginLoc(),
14341 SubExpr.get(), E->getEndLoc());
14342}
14343
14344template<typename Derived>
14345ExprResult
14346TreeTransform<Derived>::TransformCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) {
14347 return E;
14348}
14349
14350template<typename Derived>
14351ExprResult
14352TreeTransform<Derived>::TransformCXXNullPtrLiteralExpr(
14353 CXXNullPtrLiteralExpr *E) {
14354 return E;
14355}
14356
14357template<typename Derived>
14358ExprResult
14359TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
14360
14361 // In lambdas, the qualifiers of the type depends of where in
14362 // the call operator `this` appear, and we do not have a good way to
14363 // rebuild this information, so we transform the type.
14364 //
14365 // In other contexts, the type of `this` may be overrided
14366 // for type deduction, so we need to recompute it.
14367 //
14368 // Always recompute the type if we're in the body of a lambda, and
14369 // 'this' is dependent on a lambda's explicit object parameter.
14370 QualType T = [&]() {
14371 auto &S = getSema();
14372 if (E->isCapturedByCopyInLambdaWithExplicitObjectParameter())
14373 return S.getCurrentThisType();
14374 if (S.getCurLambda())
14375 return getDerived().TransformType(E->getType());
14376 return S.getCurrentThisType();
14377 }();
14378
14379 if (!getDerived().AlwaysRebuild() && T == E->getType()) {
14380 // Mark it referenced in the new context regardless.
14381 // FIXME: this is a bit instantiation-specific.
14382 getSema().MarkThisReferenced(E);
14383 return E;
14384 }
14385
14386 return getDerived().RebuildCXXThisExpr(E->getBeginLoc(), T, E->isImplicit());
14387}
14388
14389template<typename Derived>
14390ExprResult
14391TreeTransform<Derived>::TransformCXXThrowExpr(CXXThrowExpr *E) {
14392 ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
14393 if (SubExpr.isInvalid())
14394 return ExprError();
14395
14396 getSema().DiagnoseExceptionUse(E->getThrowLoc(), /* IsTry= */ false);
14397
14398 if (!getDerived().AlwaysRebuild() &&
14399 SubExpr.get() == E->getSubExpr())
14400 return E;
14401
14402 return getDerived().RebuildCXXThrowExpr(E->getThrowLoc(), SubExpr.get(),
14403 E->isThrownVariableInScope());
14404}
14405
14406template<typename Derived>
14407ExprResult
14408TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
14409 ParmVarDecl *Param = cast_or_null<ParmVarDecl>(
14410 getDerived().TransformDecl(E->getBeginLoc(), E->getParam()));
14411 if (!Param)
14412 return ExprError();
14413
14414 ExprResult InitRes;
14415 if (E->hasRewrittenInit()) {
14416 InitRes = getDerived().TransformExpr(E->getRewrittenExpr());
14417 if (InitRes.isInvalid())
14418 return ExprError();
14419 }
14420
14421 if (!getDerived().AlwaysRebuild() && Param == E->getParam() &&
14422 E->getUsedContext() == SemaRef.CurContext &&
14423 InitRes.get() == E->getRewrittenExpr())
14424 return E;
14425
14426 return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param,
14427 InitRes.get());
14428}
14429
14430template<typename Derived>
14431ExprResult
14432TreeTransform<Derived>::TransformCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
14433 FieldDecl *Field = cast_or_null<FieldDecl>(
14434 getDerived().TransformDecl(E->getBeginLoc(), E->getField()));
14435 if (!Field)
14436 return ExprError();
14437
14438 if (!getDerived().AlwaysRebuild() && Field == E->getField() &&
14439 E->getUsedContext() == SemaRef.CurContext)
14440 return E;
14441
14442 return getDerived().RebuildCXXDefaultInitExpr(E->getExprLoc(), Field);
14443}
14444
14445template<typename Derived>
14446ExprResult
14447TreeTransform<Derived>::TransformCXXScalarValueInitExpr(
14448 CXXScalarValueInitExpr *E) {
14449 TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
14450 if (!T)
14451 return ExprError();
14452
14453 if (!getDerived().AlwaysRebuild() &&
14454 T == E->getTypeSourceInfo())
14455 return E;
14456
14457 return getDerived().RebuildCXXScalarValueInitExpr(T,
14458 /*FIXME:*/T->getTypeLoc().getEndLoc(),
14459 E->getRParenLoc());
14460}
14461
14462template<typename Derived>
14463ExprResult
14464TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
14465 // Transform the type that we're allocating
14466 TypeSourceInfo *AllocTypeInfo =
14467 getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
14468 if (!AllocTypeInfo)
14469 return ExprError();
14470
14471 // Transform the size of the array we're allocating (if any).
14472 std::optional<Expr *> ArraySize;
14473 if (E->isArray()) {
14474 ExprResult NewArraySize;
14475 if (std::optional<Expr *> OldArraySize = E->getArraySize()) {
14476 NewArraySize = getDerived().TransformExpr(*OldArraySize);
14477 if (NewArraySize.isInvalid())
14478 return ExprError();
14479 }
14480 ArraySize = NewArraySize.get();
14481 }
14482
14483 // Transform the placement arguments (if any).
14484 bool ArgumentChanged = false;
14485 SmallVector<Expr*, 8> PlacementArgs;
14486 if (getDerived().TransformExprs(E->getPlacementArgs(),
14487 E->getNumPlacementArgs(), true,
14488 PlacementArgs, &ArgumentChanged))
14489 return ExprError();
14490
14491 // Transform the initializer (if any).
14492 Expr *OldInit = E->getInitializer();
14493 ExprResult NewInit;
14494 if (OldInit)
14495 NewInit = getDerived().TransformInitializer(OldInit, true);
14496 if (NewInit.isInvalid())
14497 return ExprError();
14498
14499 // Transform new operator and delete operator.
14500 FunctionDecl *OperatorNew = nullptr;
14501 if (E->getOperatorNew()) {
14502 OperatorNew = cast_or_null<FunctionDecl>(
14503 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorNew()));
14504 if (!OperatorNew)
14505 return ExprError();
14506 }
14507
14508 FunctionDecl *OperatorDelete = nullptr;
14509 if (E->getOperatorDelete()) {
14510 OperatorDelete = cast_or_null<FunctionDecl>(
14511 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14512 if (!OperatorDelete)
14513 return ExprError();
14514 }
14515
14516 if (!getDerived().AlwaysRebuild() &&
14517 AllocTypeInfo == E->getAllocatedTypeSourceInfo() &&
14518 ArraySize == E->getArraySize() &&
14519 NewInit.get() == OldInit &&
14520 OperatorNew == E->getOperatorNew() &&
14521 OperatorDelete == E->getOperatorDelete() &&
14522 !ArgumentChanged) {
14523 // Mark any declarations we need as referenced.
14524 // FIXME: instantiation-specific.
14525 if (OperatorNew)
14526 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorNew);
14527 if (OperatorDelete)
14528 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14529
14530 if (E->isArray() && !E->getAllocatedType()->isDependentType()) {
14531 QualType ElementType
14532 = SemaRef.Context.getBaseElementType(QT: E->getAllocatedType());
14533 if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
14534 CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
14535 if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Class: Record)) {
14536 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
14537 }
14538 }
14539 }
14540
14541 return E;
14542 }
14543
14544 QualType AllocType = AllocTypeInfo->getType();
14545 if (!ArraySize) {
14546 // If no array size was specified, but the new expression was
14547 // instantiated with an array type (e.g., "new T" where T is
14548 // instantiated with "int[4]"), extract the outer bound from the
14549 // array type as our array size. We do this with constant and
14550 // dependently-sized array types.
14551 const ArrayType *ArrayT = SemaRef.Context.getAsArrayType(T: AllocType);
14552 if (!ArrayT) {
14553 // Do nothing
14554 } else if (const ConstantArrayType *ConsArrayT
14555 = dyn_cast<ConstantArrayType>(ArrayT)) {
14556 ArraySize = IntegerLiteral::Create(C: SemaRef.Context, V: ConsArrayT->getSize(),
14557 type: SemaRef.Context.getSizeType(),
14558 /*FIXME:*/ l: E->getBeginLoc());
14559 AllocType = ConsArrayT->getElementType();
14560 } else if (const DependentSizedArrayType *DepArrayT
14561 = dyn_cast<DependentSizedArrayType>(ArrayT)) {
14562 if (DepArrayT->getSizeExpr()) {
14563 ArraySize = DepArrayT->getSizeExpr();
14564 AllocType = DepArrayT->getElementType();
14565 }
14566 }
14567 }
14568
14569 return getDerived().RebuildCXXNewExpr(
14570 E->getBeginLoc(), E->isGlobalNew(),
14571 /*FIXME:*/ E->getBeginLoc(), PlacementArgs,
14572 /*FIXME:*/ E->getBeginLoc(), E->getTypeIdParens(), AllocType,
14573 AllocTypeInfo, ArraySize, E->getDirectInitRange(), NewInit.get());
14574}
14575
14576template<typename Derived>
14577ExprResult
14578TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
14579 ExprResult Operand = getDerived().TransformExpr(E->getArgument());
14580 if (Operand.isInvalid())
14581 return ExprError();
14582
14583 // Transform the delete operator, if known.
14584 FunctionDecl *OperatorDelete = nullptr;
14585 if (E->getOperatorDelete()) {
14586 OperatorDelete = cast_or_null<FunctionDecl>(
14587 getDerived().TransformDecl(E->getBeginLoc(), E->getOperatorDelete()));
14588 if (!OperatorDelete)
14589 return ExprError();
14590 }
14591
14592 if (!getDerived().AlwaysRebuild() &&
14593 Operand.get() == E->getArgument() &&
14594 OperatorDelete == E->getOperatorDelete()) {
14595 // Mark any declarations we need as referenced.
14596 // FIXME: instantiation-specific.
14597 if (OperatorDelete)
14598 SemaRef.MarkFunctionReferenced(Loc: E->getBeginLoc(), Func: OperatorDelete);
14599
14600 if (!E->getArgument()->isTypeDependent()) {
14601 QualType Destroyed = SemaRef.Context.getBaseElementType(
14602 QT: E->getDestroyedType());
14603 if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
14604 CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
14605 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
14606 SemaRef.LookupDestructor(Class: Record));
14607 }
14608 }
14609
14610 return E;
14611 }
14612
14613 return getDerived().RebuildCXXDeleteExpr(
14614 E->getBeginLoc(), E->isGlobalDelete(), E->isArrayForm(), Operand.get());
14615}
14616
14617template<typename Derived>
14618ExprResult
14619TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
14620 CXXPseudoDestructorExpr *E) {
14621 ExprResult Base = getDerived().TransformExpr(E->getBase());
14622 if (Base.isInvalid())
14623 return ExprError();
14624
14625 ParsedType ObjectTypePtr;
14626 bool MayBePseudoDestructor = false;
14627 Base = SemaRef.ActOnStartCXXMemberReference(S: nullptr, Base: Base.get(),
14628 OpLoc: E->getOperatorLoc(),
14629 OpKind: E->isArrow()? tok::arrow : tok::period,
14630 ObjectType&: ObjectTypePtr,
14631 MayBePseudoDestructor);
14632 if (Base.isInvalid())
14633 return ExprError();
14634
14635 QualType ObjectType = ObjectTypePtr.get();
14636 NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc();
14637 if (QualifierLoc) {
14638 QualifierLoc
14639 = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc, ObjectType);
14640 if (!QualifierLoc)
14641 return ExprError();
14642 }
14643 CXXScopeSpec SS;
14644 SS.Adopt(Other: QualifierLoc);
14645
14646 PseudoDestructorTypeStorage Destroyed;
14647 if (E->getDestroyedTypeInfo()) {
14648 TypeSourceInfo *DestroyedTypeInfo
14649 = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
14650 ObjectType, nullptr, SS);
14651 if (!DestroyedTypeInfo)
14652 return ExprError();
14653 Destroyed = DestroyedTypeInfo;
14654 } else if (!ObjectType.isNull() && ObjectType->isDependentType()) {
14655 // We aren't likely to be able to resolve the identifier down to a type
14656 // now anyway, so just retain the identifier.
14657 Destroyed = PseudoDestructorTypeStorage(E->getDestroyedTypeIdentifier(),
14658 E->getDestroyedTypeLoc());
14659 } else {
14660 // Look for a destructor known with the given name.
14661 ParsedType T = SemaRef.getDestructorName(
14662 II: *E->getDestroyedTypeIdentifier(), NameLoc: E->getDestroyedTypeLoc(),
14663 /*Scope=*/S: nullptr, SS, ObjectType: ObjectTypePtr, EnteringContext: false);
14664 if (!T)
14665 return ExprError();
14666
14667 Destroyed
14668 = SemaRef.Context.getTrivialTypeSourceInfo(T: SemaRef.GetTypeFromParser(Ty: T),
14669 Loc: E->getDestroyedTypeLoc());
14670 }
14671
14672 TypeSourceInfo *ScopeTypeInfo = nullptr;
14673 if (E->getScopeTypeInfo()) {
14674 CXXScopeSpec EmptySS;
14675 ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
14676 E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
14677 if (!ScopeTypeInfo)
14678 return ExprError();
14679 }
14680
14681 return getDerived().RebuildCXXPseudoDestructorExpr(Base.get(),
14682 E->getOperatorLoc(),
14683 E->isArrow(),
14684 SS,
14685 ScopeTypeInfo,
14686 E->getColonColonLoc(),
14687 E->getTildeLoc(),
14688 Destroyed);
14689}
14690
14691template <typename Derived>
14692bool TreeTransform<Derived>::TransformOverloadExprDecls(OverloadExpr *Old,
14693 bool RequiresADL,
14694 LookupResult &R) {
14695 // Transform all the decls.
14696 bool AllEmptyPacks = true;
14697 for (auto *OldD : Old->decls()) {
14698 Decl *InstD = getDerived().TransformDecl(Old->getNameLoc(), OldD);
14699 if (!InstD) {
14700 // Silently ignore these if a UsingShadowDecl instantiated to nothing.
14701 // This can happen because of dependent hiding.
14702 if (isa<UsingShadowDecl>(OldD))
14703 continue;
14704 else {
14705 R.clear();
14706 return true;
14707 }
14708 }
14709
14710 // Expand using pack declarations.
14711 NamedDecl *SingleDecl = cast<NamedDecl>(InstD);
14712 ArrayRef<NamedDecl*> Decls = SingleDecl;
14713 if (auto *UPD = dyn_cast<UsingPackDecl>(InstD))
14714 Decls = UPD->expansions();
14715
14716 // Expand using declarations.
14717 for (auto *D : Decls) {
14718 if (auto *UD = dyn_cast<UsingDecl>(D)) {
14719 for (auto *SD : UD->shadows())
14720 R.addDecl(SD);
14721 } else {
14722 R.addDecl(D);
14723 }
14724 }
14725
14726 AllEmptyPacks &= Decls.empty();
14727 }
14728
14729 // C++ [temp.res]/8.4.2:
14730 // The program is ill-formed, no diagnostic required, if [...] lookup for
14731 // a name in the template definition found a using-declaration, but the
14732 // lookup in the corresponding scope in the instantiation odoes not find
14733 // any declarations because the using-declaration was a pack expansion and
14734 // the corresponding pack is empty
14735 if (AllEmptyPacks && !RequiresADL) {
14736 getSema().Diag(Old->getNameLoc(), diag::err_using_pack_expansion_empty)
14737 << isa<UnresolvedMemberExpr>(Old) << Old->getName();
14738 return true;
14739 }
14740
14741 // Resolve a kind, but don't do any further analysis. If it's
14742 // ambiguous, the callee needs to deal with it.
14743 R.resolveKind();
14744
14745 if (Old->hasTemplateKeyword() && !R.empty()) {
14746 NamedDecl *FoundDecl = R.getRepresentativeDecl()->getUnderlyingDecl();
14747 getSema().FilterAcceptableTemplateNames(R,
14748 /*AllowFunctionTemplates=*/true,
14749 /*AllowDependent=*/true);
14750 if (R.empty()) {
14751 // If a 'template' keyword was used, a lookup that finds only non-template
14752 // names is an error.
14753 getSema().Diag(R.getNameLoc(),
14754 diag::err_template_kw_refers_to_non_template)
14755 << R.getLookupName() << Old->getQualifierLoc().getSourceRange()
14756 << Old->hasTemplateKeyword() << Old->getTemplateKeywordLoc();
14757 getSema().Diag(FoundDecl->getLocation(),
14758 diag::note_template_kw_refers_to_non_template)
14759 << R.getLookupName();
14760 return true;
14761 }
14762 }
14763
14764 return false;
14765}
14766
14767template <typename Derived>
14768ExprResult TreeTransform<Derived>::TransformUnresolvedLookupExpr(
14769 UnresolvedLookupExpr *Old) {
14770 return TransformUnresolvedLookupExpr(E: Old, /*IsAddressOfOperand=*/IsAddressOfOperand: false);
14771}
14772
14773template <typename Derived>
14774ExprResult
14775TreeTransform<Derived>::TransformUnresolvedLookupExpr(UnresolvedLookupExpr *Old,
14776 bool IsAddressOfOperand) {
14777 LookupResult R(SemaRef, Old->getName(), Old->getNameLoc(),
14778 Sema::LookupOrdinaryName);
14779
14780 // Transform the declaration set.
14781 if (TransformOverloadExprDecls(Old, RequiresADL: Old->requiresADL(), R))
14782 return ExprError();
14783
14784 // Rebuild the nested-name qualifier, if present.
14785 CXXScopeSpec SS;
14786 if (Old->getQualifierLoc()) {
14787 NestedNameSpecifierLoc QualifierLoc
14788 = getDerived().TransformNestedNameSpecifierLoc(Old->getQualifierLoc());
14789 if (!QualifierLoc)
14790 return ExprError();
14791
14792 SS.Adopt(Other: QualifierLoc);
14793 }
14794
14795 if (Old->getNamingClass()) {
14796 CXXRecordDecl *NamingClass
14797 = cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
14798 Old->getNameLoc(),
14799 Old->getNamingClass()));
14800 if (!NamingClass) {
14801 R.clear();
14802 return ExprError();
14803 }
14804
14805 R.setNamingClass(NamingClass);
14806 }
14807
14808 // Rebuild the template arguments, if any.
14809 SourceLocation TemplateKWLoc = Old->getTemplateKeywordLoc();
14810 TemplateArgumentListInfo TransArgs(Old->getLAngleLoc(), Old->getRAngleLoc());
14811 if (Old->hasExplicitTemplateArgs() &&
14812 getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14813 Old->getNumTemplateArgs(),
14814 TransArgs)) {
14815 R.clear();
14816 return ExprError();
14817 }
14818
14819 // An UnresolvedLookupExpr can refer to a class member. This occurs e.g. when
14820 // a non-static data member is named in an unevaluated operand, or when
14821 // a member is named in a dependent class scope function template explicit
14822 // specialization that is neither declared static nor with an explicit object
14823 // parameter.
14824 if (SemaRef.isPotentialImplicitMemberAccess(SS, R, IsAddressOfOperand))
14825 return SemaRef.BuildPossibleImplicitMemberExpr(
14826 SS, TemplateKWLoc, R,
14827 TemplateArgs: Old->hasExplicitTemplateArgs() ? &TransArgs : nullptr,
14828 /*S=*/S: nullptr);
14829
14830 // If we have neither explicit template arguments, nor the template keyword,
14831 // it's a normal declaration name or member reference.
14832 if (!Old->hasExplicitTemplateArgs() && !TemplateKWLoc.isValid())
14833 return getDerived().RebuildDeclarationNameExpr(SS, R, Old->requiresADL());
14834
14835 // If we have template arguments, then rebuild the template-id expression.
14836 return getDerived().RebuildTemplateIdExpr(SS, TemplateKWLoc, R,
14837 Old->requiresADL(), &TransArgs);
14838}
14839
14840template<typename Derived>
14841ExprResult
14842TreeTransform<Derived>::TransformTypeTraitExpr(TypeTraitExpr *E) {
14843 bool ArgChanged = false;
14844 SmallVector<TypeSourceInfo *, 4> Args;
14845 for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) {
14846 TypeSourceInfo *From = E->getArg(I);
14847 TypeLoc FromTL = From->getTypeLoc();
14848 if (!FromTL.getAs<PackExpansionTypeLoc>()) {
14849 TypeLocBuilder TLB;
14850 TLB.reserve(Requested: FromTL.getFullDataSize());
14851 QualType To = getDerived().TransformType(TLB, FromTL);
14852 if (To.isNull())
14853 return ExprError();
14854
14855 if (To == From->getType())
14856 Args.push_back(From);
14857 else {
14858 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14859 ArgChanged = true;
14860 }
14861 continue;
14862 }
14863
14864 ArgChanged = true;
14865
14866 // We have a pack expansion. Instantiate it.
14867 PackExpansionTypeLoc ExpansionTL = FromTL.castAs<PackExpansionTypeLoc>();
14868 TypeLoc PatternTL = ExpansionTL.getPatternLoc();
14869 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
14870 SemaRef.collectUnexpandedParameterPacks(PatternTL, Unexpanded);
14871
14872 // Determine whether the set of unexpanded parameter packs can and should
14873 // be expanded.
14874 bool Expand = true;
14875 bool RetainExpansion = false;
14876 UnsignedOrNone OrigNumExpansions =
14877 ExpansionTL.getTypePtr()->getNumExpansions();
14878 UnsignedOrNone NumExpansions = OrigNumExpansions;
14879 if (getDerived().TryExpandParameterPacks(ExpansionTL.getEllipsisLoc(),
14880 PatternTL.getSourceRange(),
14881 Unexpanded,
14882 Expand, RetainExpansion,
14883 NumExpansions))
14884 return ExprError();
14885
14886 if (!Expand) {
14887 // The transform has determined that we should perform a simple
14888 // transformation on the pack expansion, producing another pack
14889 // expansion.
14890 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), std::nullopt);
14891
14892 TypeLocBuilder TLB;
14893 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14894
14895 QualType To = getDerived().TransformType(TLB, PatternTL);
14896 if (To.isNull())
14897 return ExprError();
14898
14899 To = getDerived().RebuildPackExpansionType(To,
14900 PatternTL.getSourceRange(),
14901 ExpansionTL.getEllipsisLoc(),
14902 NumExpansions);
14903 if (To.isNull())
14904 return ExprError();
14905
14906 PackExpansionTypeLoc ToExpansionTL
14907 = TLB.push<PackExpansionTypeLoc>(To);
14908 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14909 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14910 continue;
14911 }
14912
14913 // Expand the pack expansion by substituting for each argument in the
14914 // pack(s).
14915 for (unsigned I = 0; I != *NumExpansions; ++I) {
14916 Sema::ArgPackSubstIndexRAII SubstIndex(SemaRef, I);
14917 TypeLocBuilder TLB;
14918 TLB.reserve(Requested: PatternTL.getFullDataSize());
14919 QualType To = getDerived().TransformType(TLB, PatternTL);
14920 if (To.isNull())
14921 return ExprError();
14922
14923 if (To->containsUnexpandedParameterPack()) {
14924 To = getDerived().RebuildPackExpansionType(To,
14925 PatternTL.getSourceRange(),
14926 ExpansionTL.getEllipsisLoc(),
14927 NumExpansions);
14928 if (To.isNull())
14929 return ExprError();
14930
14931 PackExpansionTypeLoc ToExpansionTL
14932 = TLB.push<PackExpansionTypeLoc>(To);
14933 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14934 }
14935
14936 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14937 }
14938
14939 if (!RetainExpansion)
14940 continue;
14941
14942 // If we're supposed to retain a pack expansion, do so by temporarily
14943 // forgetting the partially-substituted parameter pack.
14944 ForgetPartiallySubstitutedPackRAII Forget(getDerived());
14945
14946 TypeLocBuilder TLB;
14947 TLB.reserve(Requested: From->getTypeLoc().getFullDataSize());
14948
14949 QualType To = getDerived().TransformType(TLB, PatternTL);
14950 if (To.isNull())
14951 return ExprError();
14952
14953 To = getDerived().RebuildPackExpansionType(To,
14954 PatternTL.getSourceRange(),
14955 ExpansionTL.getEllipsisLoc(),
14956 NumExpansions);
14957 if (To.isNull())
14958 return ExprError();
14959
14960 PackExpansionTypeLoc ToExpansionTL
14961 = TLB.push<PackExpansionTypeLoc>(To);
14962 ToExpansionTL.setEllipsisLoc(ExpansionTL.getEllipsisLoc());
14963 Args.push_back(TLB.getTypeSourceInfo(Context&: SemaRef.Context, T: To));
14964 }
14965
14966 if (!getDerived().AlwaysRebuild() && !ArgChanged)
14967 return E;
14968
14969 return getDerived().RebuildTypeTrait(E->getTrait(), E->getBeginLoc(), Args,
14970 E->getEndLoc());
14971}
14972
14973template<typename Derived>
14974ExprResult
14975TreeTransform<Derived>::TransformConceptSpecializationExpr(
14976 ConceptSpecializationExpr *E) {
14977 const ASTTemplateArgumentListInfo *Old = E->getTemplateArgsAsWritten();
14978 TemplateArgumentListInfo TransArgs(Old->LAngleLoc, Old->RAngleLoc);
14979 if (getDerived().TransformTemplateArguments(Old->getTemplateArgs(),
14980 Old->NumTemplateArgs, TransArgs))
14981 return ExprError();
14982
14983 return getDerived().RebuildConceptSpecializationExpr(
14984 E->getNestedNameSpecifierLoc(), E->getTemplateKWLoc(),
14985 E->getConceptNameInfo(), E->getFoundDecl(), E->getNamedConcept(),
14986 &TransArgs);
14987}
14988
14989template<typename Derived>
14990ExprResult
14991TreeTransform<Derived>::TransformRequiresExpr(RequiresExpr *E) {
14992 SmallVector<ParmVarDecl*, 4> TransParams;
14993 SmallVector<QualType, 4> TransParamTypes;
14994 Sema::ExtParameterInfoBuilder ExtParamInfos;
14995
14996 // C++2a [expr.prim.req]p2
14997 // Expressions appearing within a requirement-body are unevaluated operands.
14998 EnterExpressionEvaluationContext Ctx(
14999 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated,
15000 Sema::ReuseLambdaContextDecl);
15001
15002 RequiresExprBodyDecl *Body = RequiresExprBodyDecl::Create(
15003 C&: getSema().Context, DC: getSema().CurContext,
15004 StartLoc: E->getBody()->getBeginLoc());
15005
15006 Sema::ContextRAII SavedContext(getSema(), Body, /*NewThisContext*/false);
15007
15008 ExprResult TypeParamResult = getDerived().TransformRequiresTypeParams(
15009 E->getRequiresKWLoc(), E->getRBraceLoc(), E, Body,
15010 E->getLocalParameters(), TransParamTypes, TransParams, ExtParamInfos);
15011
15012 for (ParmVarDecl *Param : TransParams)
15013 if (Param)
15014 Param->setDeclContext(Body);
15015
15016 // On failure to transform, TransformRequiresTypeParams returns an expression
15017 // in the event that the transformation of the type params failed in some way.
15018 // It is expected that this will result in a 'not satisfied' Requires clause
15019 // when instantiating.
15020 if (!TypeParamResult.isUnset())
15021 return TypeParamResult;
15022
15023 SmallVector<concepts::Requirement *, 4> TransReqs;
15024 if (getDerived().TransformRequiresExprRequirements(E->getRequirements(),
15025 TransReqs))
15026 return ExprError();
15027
15028 for (concepts::Requirement *Req : TransReqs) {
15029 if (auto *ER = dyn_cast<concepts::ExprRequirement>(Req)) {
15030 if (ER->getReturnTypeRequirement().isTypeConstraint()) {
15031 ER->getReturnTypeRequirement()
15032 .getTypeConstraintTemplateParameterList()->getParam(0)
15033 ->setDeclContext(Body);
15034 }
15035 }
15036 }
15037
15038 return getDerived().RebuildRequiresExpr(
15039 E->getRequiresKWLoc(), Body, E->getLParenLoc(), TransParams,
15040 E->getRParenLoc(), TransReqs, E->getRBraceLoc());
15041}
15042
15043template<typename Derived>
15044bool TreeTransform<Derived>::TransformRequiresExprRequirements(
15045 ArrayRef<concepts::Requirement *> Reqs,
15046 SmallVectorImpl<concepts::Requirement *> &Transformed) {
15047 for (concepts::Requirement *Req : Reqs) {
15048 concepts::Requirement *TransReq = nullptr;
15049 if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req))
15050 TransReq = getDerived().TransformTypeRequirement(TypeReq);
15051 else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req))
15052 TransReq = getDerived().TransformExprRequirement(ExprReq);
15053 else
15054 TransReq = getDerived().TransformNestedRequirement(
15055 cast<concepts::NestedRequirement>(Req));
15056 if (!TransReq)
15057 return true;
15058 Transformed.push_back(TransReq);
15059 }
15060 return false;
15061}
15062
15063template<typename Derived>
15064concepts::TypeRequirement *
15065TreeTransform<Derived>::TransformTypeRequirement(
15066 concepts::TypeRequirement *Req) {
15067 if (Req->isSubstitutionFailure()) {
15068 if (getDerived().AlwaysRebuild())
15069 return getDerived().RebuildTypeRequirement(
15070 Req->getSubstitutionDiagnostic());
15071 return Req;
15072 }
15073 TypeSourceInfo *TransType = getDerived().TransformType(Req->getType());
15074 if (!TransType)
15075 return nullptr;
15076 return getDerived().RebuildTypeRequirement(TransType);
15077}
15078
15079template<typename Derived>
15080concepts::ExprRequirement *
15081TreeTransform<Derived>::TransformExprRequirement(concepts::ExprRequirement *Req) {
15082 llvm::PointerUnion<Expr *, concepts::Requirement::SubstitutionDiagnostic *> TransExpr;
15083 if (Req->isExprSubstitutionFailure())
15084 TransExpr = Req->getExprSubstitutionDiagnostic();
15085 else {
15086 ExprResult TransExprRes = getDerived().TransformExpr(Req->getExpr());
15087 if (TransExprRes.isUsable() && TransExprRes.get()->hasPlaceholderType())
15088 TransExprRes = SemaRef.CheckPlaceholderExpr(E: TransExprRes.get());
15089 if (TransExprRes.isInvalid())
15090 return nullptr;
15091 TransExpr = TransExprRes.get();
15092 }
15093
15094 std::optional<concepts::ExprRequirement::ReturnTypeRequirement> TransRetReq;
15095 const auto &RetReq = Req->getReturnTypeRequirement();
15096 if (RetReq.isEmpty())
15097 TransRetReq.emplace();
15098 else if (RetReq.isSubstitutionFailure())
15099 TransRetReq.emplace(RetReq.getSubstitutionDiagnostic());
15100 else if (RetReq.isTypeConstraint()) {
15101 TemplateParameterList *OrigTPL =
15102 RetReq.getTypeConstraintTemplateParameterList();
15103 TemplateParameterList *TPL =
15104 getDerived().TransformTemplateParameterList(OrigTPL);
15105 if (!TPL)
15106 return nullptr;
15107 TransRetReq.emplace(TPL);
15108 }
15109 assert(TransRetReq && "All code paths leading here must set TransRetReq");
15110 if (Expr *E = dyn_cast<Expr *>(TransExpr))
15111 return getDerived().RebuildExprRequirement(E, Req->isSimple(),
15112 Req->getNoexceptLoc(),
15113 std::move(*TransRetReq));
15114 return getDerived().RebuildExprRequirement(
15115 cast<concepts::Requirement::SubstitutionDiagnostic *>(TransExpr),
15116 Req->isSimple(), Req->getNoexceptLoc(), std::move(*TransRetReq));
15117}
15118
15119template<typename Derived>
15120concepts::NestedRequirement *
15121TreeTransform<Derived>::TransformNestedRequirement(
15122 concepts::NestedRequirement *Req) {
15123 if (Req->hasInvalidConstraint()) {
15124 if (getDerived().AlwaysRebuild())
15125 return getDerived().RebuildNestedRequirement(
15126 Req->getInvalidConstraintEntity(), Req->getConstraintSatisfaction());
15127 return Req;
15128 }
15129 ExprResult TransConstraint =
15130 getDerived().TransformExpr(Req->getConstraintExpr());
15131 if (TransConstraint.isInvalid())
15132 return nullptr;
15133 return getDerived().RebuildNestedRequirement(TransConstraint.get());
15134}
15135
15136template<typename Derived>
15137ExprResult
15138TreeTransform<Derived>::TransformArrayTypeTraitExpr(ArrayTypeTraitExpr *E) {
15139 TypeSourceInfo *T = getDerived().TransformType(E->getQueriedTypeSourceInfo());
15140 if (!T)
15141 return ExprError();
15142
15143 if (!getDerived().AlwaysRebuild() &&
15144 T == E->getQueriedTypeSourceInfo())
15145 return E;
15146
15147 ExprResult SubExpr;
15148 {
15149 EnterExpressionEvaluationContext Unevaluated(
15150 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15151 SubExpr = getDerived().TransformExpr(E->getDimensionExpression());
15152 if (SubExpr.isInvalid())
15153 return ExprError();
15154 }
15155
15156 return getDerived().RebuildArrayTypeTrait(E->getTrait(), E->getBeginLoc(), T,
15157 SubExpr.get(), E->getEndLoc());
15158}
15159
15160template<typename Derived>
15161ExprResult
15162TreeTransform<Derived>::TransformExpressionTraitExpr(ExpressionTraitExpr *E) {
15163 ExprResult SubExpr;
15164 {
15165 EnterExpressionEvaluationContext Unevaluated(
15166 SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
15167 SubExpr = getDerived().TransformExpr(E->getQueriedExpression());
15168 if (SubExpr.isInvalid())
15169 return ExprError();
15170
15171 if (!getDerived().AlwaysRebuild() && SubExpr.get() == E->getQueriedExpression())
15172 return E;
15173 }
15174
15175 return getDerived().RebuildExpressionTrait(E->getTrait(), E->getBeginLoc(),
15176 SubExpr.get(), E->getEndLoc());
15177}
15178
15179template <typename Derived>
15180ExprResult TreeTransform<Derived>::TransformParenDependentScopeDeclRefExpr(
15181 ParenExpr *PE, DependentScopeDeclRefExpr *DRE, bool AddrTaken,
15182 TypeSourceInfo **RecoveryTSI) {
15183 ExprResult NewDRE = getDerived().TransformDependentScopeDeclRefExpr(
15184 DRE, AddrTaken, RecoveryTSI);
15185
15186 // Propagate both errors and recovered types, which return ExprEmpty.
15187 if (!NewDRE.isUsable())
15188 return NewDRE;
15189
15190 // We got an expr, wrap it up in parens.
15191 if (!getDerived().AlwaysRebuild() && NewDRE.get() == DRE)
15192 return PE;
15193 return getDerived().RebuildParenExpr(NewDRE.get(), PE->getLParen(),
15194 PE->getRParen());
15195}
15196
15197template <typename Derived>
15198ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15199 DependentScopeDeclRefExpr *E) {
15200 return TransformDependentScopeDeclRefExpr(E, /*IsAddressOfOperand=*/IsAddressOfOperand: false,
15201 RecoveryTSI: nullptr);
15202}
15203
15204template <typename Derived>
15205ExprResult TreeTransform<Derived>::TransformDependentScopeDeclRefExpr(
15206 DependentScopeDeclRefExpr *E, bool IsAddressOfOperand,
15207 TypeSourceInfo **RecoveryTSI) {
15208 assert(E->getQualifierLoc());
15209 NestedNameSpecifierLoc QualifierLoc =
15210 getDerived().TransformNestedNameSpecifierLoc(E->getQualifierLoc());
15211 if (!QualifierLoc)
15212 return ExprError();
15213 SourceLocation TemplateKWLoc = E->getTemplateKeywordLoc();
15214
15215 // TODO: If this is a conversion-function-id, verify that the
15216 // destination type name (if present) resolves the same way after
15217 // instantiation as it did in the local scope.
15218
15219 DeclarationNameInfo NameInfo =
15220 getDerived().TransformDeclarationNameInfo(E->getNameInfo());
15221 if (!NameInfo.getName())
15222 return ExprError();
15223
15224 if (!E->hasExplicitTemplateArgs()) {
15225 if (!getDerived().AlwaysRebuild() && QualifierLoc == E->getQualifierLoc() &&
15226 // Note: it is sufficient to compare the Name component of NameInfo:
15227 // if name has not changed, DNLoc has not changed either.
15228 NameInfo.getName() == E->getDeclName())
15229 return E;
15230
15231 return getDerived().RebuildDependentScopeDeclRefExpr(
15232 QualifierLoc, TemplateKWLoc, NameInfo, /*TemplateArgs=*/nullptr,
15233 IsAddressOfOperand, RecoveryTSI);
15234 }
15235
15236 TemplateArgumentListInfo TransArgs(E->getLAngleLoc(), E->getRAngleLoc());
15237 if (getDerived().TransformTemplateArguments(
15238 E->getTemplateArgs(), E->getNumTemplateArgs(), TransArgs))
15239 return ExprError();
15240
15241 return getDerived().RebuildDependentScopeDeclRefExpr(
15242 QualifierLoc, TemplateKWLoc, NameInfo, &TransArgs, IsAddressOfOperand,
15243 RecoveryTSI);
15244}
15245
15246template<typename Derived>
15247ExprResult
15248TreeTransform<Derived>::TransformCXXConstructExpr(CXXConstructExpr *E) {
15249 // CXXConstructExprs other than for list-initialization and
15250 // CXXTemporaryObjectExpr are always implicit, so when we have
15251 // a 1-argument construction we just transform that argument.
15252 if (getDerived().AllowSkippingCXXConstructExpr() &&
15253 ((E->getNumArgs() == 1 ||
15254 (E->getNumArgs() > 1 && getDerived().DropCallArgument(E->getArg(Arg: 1)))) &&
15255 (!getDerived().DropCallArgument(E->getArg(Arg: 0))) &&
15256 !E->isListInitialization()))
15257 return getDerived().TransformInitializer(E->getArg(Arg: 0),
15258 /*DirectInit*/ false);
15259
15260 TemporaryBase Rebase(*this, /*FIXME*/ E->getBeginLoc(), DeclarationName());
15261
15262 QualType T = getDerived().TransformType(E->getType());
15263 if (T.isNull())
15264 return ExprError();
15265
15266 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15267 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15268 if (!Constructor)
15269 return ExprError();
15270
15271 bool ArgumentChanged = false;
15272 SmallVector<Expr*, 8> Args;
15273 {
15274 EnterExpressionEvaluationContext Context(
15275 getSema(), EnterExpressionEvaluationContext::InitList,
15276 E->isListInitialization());
15277 if (getDerived().TransformExprs(E->getArgs(), E->getNumArgs(), true, Args,
15278 &ArgumentChanged))
15279 return ExprError();
15280 }
15281
15282 if (!getDerived().AlwaysRebuild() &&
15283 T == E->getType() &&
15284 Constructor == E->getConstructor() &&
15285 !ArgumentChanged) {
15286 // Mark the constructor as referenced.
15287 // FIXME: Instantiation-specific
15288 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15289 return E;
15290 }
15291
15292 return getDerived().RebuildCXXConstructExpr(
15293 T, /*FIXME:*/ E->getBeginLoc(), Constructor, E->isElidable(), Args,
15294 E->hadMultipleCandidates(), E->isListInitialization(),
15295 E->isStdInitListInitialization(), E->requiresZeroInitialization(),
15296 E->getConstructionKind(), E->getParenOrBraceRange());
15297}
15298
15299template<typename Derived>
15300ExprResult TreeTransform<Derived>::TransformCXXInheritedCtorInitExpr(
15301 CXXInheritedCtorInitExpr *E) {
15302 QualType T = getDerived().TransformType(E->getType());
15303 if (T.isNull())
15304 return ExprError();
15305
15306 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15307 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15308 if (!Constructor)
15309 return ExprError();
15310
15311 if (!getDerived().AlwaysRebuild() &&
15312 T == E->getType() &&
15313 Constructor == E->getConstructor()) {
15314 // Mark the constructor as referenced.
15315 // FIXME: Instantiation-specific
15316 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15317 return E;
15318 }
15319
15320 return getDerived().RebuildCXXInheritedCtorInitExpr(
15321 T, E->getLocation(), Constructor,
15322 E->constructsVBase(), E->inheritedFromVBase());
15323}
15324
15325/// Transform a C++ temporary-binding expression.
15326///
15327/// Since CXXBindTemporaryExpr nodes are implicitly generated, we just
15328/// transform the subexpression and return that.
15329template<typename Derived>
15330ExprResult
15331TreeTransform<Derived>::TransformCXXBindTemporaryExpr(CXXBindTemporaryExpr *E) {
15332 if (auto *Dtor = E->getTemporary()->getDestructor())
15333 SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
15334 const_cast<CXXDestructorDecl *>(Dtor));
15335 return getDerived().TransformExpr(E->getSubExpr());
15336}
15337
15338/// Transform a C++ expression that contains cleanups that should
15339/// be run after the expression is evaluated.
15340///
15341/// Since ExprWithCleanups nodes are implicitly generated, we
15342/// just transform the subexpression and return that.
15343template<typename Derived>
15344ExprResult
15345TreeTransform<Derived>::TransformExprWithCleanups(ExprWithCleanups *E) {
15346 return getDerived().TransformExpr(E->getSubExpr());
15347}
15348
15349template<typename Derived>
15350ExprResult
15351TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
15352 CXXTemporaryObjectExpr *E) {
15353 TypeSourceInfo *T =
15354 getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
15355 if (!T)
15356 return ExprError();
15357
15358 CXXConstructorDecl *Constructor = cast_or_null<CXXConstructorDecl>(
15359 getDerived().TransformDecl(E->getBeginLoc(), E->getConstructor()));
15360 if (!Constructor)
15361 return ExprError();
15362
15363 bool ArgumentChanged = false;
15364 SmallVector<Expr*, 8> Args;
15365 Args.reserve(E->getNumArgs());
15366 {
15367 EnterExpressionEvaluationContext Context(
15368 getSema(), EnterExpressionEvaluationContext::InitList,
15369 E->isListInitialization());
15370 if (TransformExprs(Inputs: E->getArgs(), NumInputs: E->getNumArgs(), IsCall: true, Outputs&: Args,
15371 ArgChanged: &ArgumentChanged))
15372 return ExprError();
15373
15374 if (E->isListInitialization() && !E->isStdInitListInitialization()) {
15375 ExprResult Res = RebuildInitList(LBraceLoc: E->getBeginLoc(), Inits: Args, RBraceLoc: E->getEndLoc());
15376 if (Res.isInvalid())
15377 return ExprError();
15378 Args = {Res.get()};
15379 }
15380 }
15381
15382 if (!getDerived().AlwaysRebuild() &&
15383 T == E->getTypeSourceInfo() &&
15384 Constructor == E->getConstructor() &&
15385 !ArgumentChanged) {
15386 // FIXME: Instantiation-specific
15387 SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Constructor);
15388 return SemaRef.MaybeBindToTemporary(E);
15389 }
15390
15391 SourceLocation LParenLoc = T->getTypeLoc().getEndLoc();
15392 return getDerived().RebuildCXXTemporaryObjectExpr(
15393 T, LParenLoc, Args, E->getEndLoc(), E->isListInitialization());
15394}
15395
15396template<typename Derived>
15397ExprResult
15398TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
15399 // Transform any init-capture expressions before entering the scope of the
15400 // lambda body, because they are not semantically within that scope.
15401 typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
15402 struct TransformedInitCapture {
15403 // The location of the ... if the result is retaining a pack expansion.
15404 SourceLocation EllipsisLoc;
15405 // Zero or more expansions of the init-capture.
15406 SmallVector<InitCaptureInfoTy, 4> Expansions;
15407 };
15408 SmallVector<TransformedInitCapture, 4> InitCaptures;
15409 InitCaptures.resize(E->explicit_capture_end() - E->explicit_capture_begin());
15410 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15411 CEnd = E->capture_end();
15412 C != CEnd; ++C) {
15413 if (!E->isInitCapture(Capture: C))
15414 continue;
15415
15416 TransformedInitCapture &Result = InitCaptures[C - E->capture_begin()];
15417 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15418
15419 auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
15420 UnsignedOrNone NumExpansions) {
15421 ExprResult NewExprInitResult = getDerived().TransformInitializer(
15422 OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
15423
15424 if (NewExprInitResult.isInvalid()) {
15425 Result.Expansions.push_back(InitCaptureInfoTy(ExprError(), QualType()));
15426 return;
15427 }
15428 Expr *NewExprInit = NewExprInitResult.get();
15429
15430 QualType NewInitCaptureType =
15431 getSema().buildLambdaInitCaptureInitialization(
15432 C->getLocation(), C->getCaptureKind() == LCK_ByRef,
15433 EllipsisLoc, NumExpansions, OldVD->getIdentifier(),
15434 cast<VarDecl>(C->getCapturedVar())->getInitStyle() !=
15435 VarDecl::CInit,
15436 NewExprInit);
15437 Result.Expansions.push_back(
15438 InitCaptureInfoTy(NewExprInit, NewInitCaptureType));
15439 };
15440
15441 // If this is an init-capture pack, consider expanding the pack now.
15442 if (OldVD->isParameterPack()) {
15443 PackExpansionTypeLoc ExpansionTL = OldVD->getTypeSourceInfo()
15444 ->getTypeLoc()
15445 .castAs<PackExpansionTypeLoc>();
15446 SmallVector<UnexpandedParameterPack, 2> Unexpanded;
15447 SemaRef.collectUnexpandedParameterPacks(OldVD->getInit(), Unexpanded);
15448
15449 // Determine whether the set of unexpanded parameter packs can and should
15450 // be expanded.
15451 bool Expand = true;
15452 bool RetainExpansion = false;
15453 UnsignedOrNone OrigNumExpansions =
15454 ExpansionTL.getTypePtr()->getNumExpansions();
15455 UnsignedOrNone NumExpansions = OrigNumExpansions;
15456 if (getDerived().TryExpandParameterPacks(
15457 ExpansionTL.getEllipsisLoc(),
15458 OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
15459 RetainExpansion, NumExpansions))
15460 return ExprError();
15461 assert(!RetainExpansion && "Should not need to retain expansion after a "
15462 "capture since it cannot be extended");
15463 if (Expand) {
15464 for (unsigned I = 0; I != *NumExpansions; ++I) {
15465 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15466 SubstInitCapture(SourceLocation(), std::nullopt);
15467 }
15468 } else {
15469 SubstInitCapture(ExpansionTL.getEllipsisLoc(), NumExpansions);
15470 Result.EllipsisLoc = ExpansionTL.getEllipsisLoc();
15471 }
15472 } else {
15473 SubstInitCapture(SourceLocation(), std::nullopt);
15474 }
15475 }
15476
15477 LambdaScopeInfo *LSI = getSema().PushLambdaScope();
15478 Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
15479
15480 // Create the local class that will describe the lambda.
15481
15482 // FIXME: DependencyKind below is wrong when substituting inside a templated
15483 // context that isn't a DeclContext (such as a variable template), or when
15484 // substituting an unevaluated lambda inside of a function's parameter's type
15485 // - as parameter types are not instantiated from within a function's DC. We
15486 // use evaluation contexts to distinguish the function parameter case.
15487 CXXRecordDecl::LambdaDependencyKind DependencyKind =
15488 CXXRecordDecl::LDK_Unknown;
15489 DeclContext *DC = getSema().CurContext;
15490 // A RequiresExprBodyDecl is not interesting for dependencies.
15491 // For the following case,
15492 //
15493 // template <typename>
15494 // concept C = requires { [] {}; };
15495 //
15496 // template <class F>
15497 // struct Widget;
15498 //
15499 // template <C F>
15500 // struct Widget<F> {};
15501 //
15502 // While we are substituting Widget<F>, the parent of DC would be
15503 // the template specialization itself. Thus, the lambda expression
15504 // will be deemed as dependent even if there are no dependent template
15505 // arguments.
15506 // (A ClassTemplateSpecializationDecl is always a dependent context.)
15507 while (DC->isRequiresExprBody())
15508 DC = DC->getParent();
15509 if ((getSema().isUnevaluatedContext() ||
15510 getSema().isConstantEvaluatedContext()) &&
15511 (DC->isFileContext() || !DC->getParent()->isDependentContext()))
15512 DependencyKind = CXXRecordDecl::LDK_NeverDependent;
15513
15514 CXXRecordDecl *OldClass = E->getLambdaClass();
15515 CXXRecordDecl *Class = getSema().createLambdaClosureType(
15516 E->getIntroducerRange(), /*Info=*/nullptr, DependencyKind,
15517 E->getCaptureDefault());
15518 getDerived().transformedLocalDecl(OldClass, {Class});
15519
15520 CXXMethodDecl *NewCallOperator =
15521 getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
15522
15523 // Enter the scope of the lambda.
15524 getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
15525 E->getCaptureDefault(), E->getCaptureDefaultLoc(),
15526 E->hasExplicitParameters(), E->isMutable());
15527
15528 // Introduce the context of the call operator.
15529 Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
15530 /*NewThisContext*/false);
15531
15532 bool Invalid = false;
15533
15534 // Transform captures.
15535 for (LambdaExpr::capture_iterator C = E->capture_begin(),
15536 CEnd = E->capture_end();
15537 C != CEnd; ++C) {
15538 // When we hit the first implicit capture, tell Sema that we've finished
15539 // the list of explicit captures.
15540 if (C->isImplicit())
15541 break;
15542
15543 // Capturing 'this' is trivial.
15544 if (C->capturesThis()) {
15545 // If this is a lambda that is part of a default member initialiser
15546 // and which we're instantiating outside the class that 'this' is
15547 // supposed to refer to, adjust the type of 'this' accordingly.
15548 //
15549 // Otherwise, leave the type of 'this' as-is.
15550 Sema::CXXThisScopeRAII ThisScope(
15551 getSema(),
15552 dyn_cast_if_present<CXXRecordDecl>(
15553 getSema().getFunctionLevelDeclContext()),
15554 Qualifiers());
15555 getSema().CheckCXXThisCapture(C->getLocation(), C->isExplicit(),
15556 /*BuildAndDiagnose*/ true, nullptr,
15557 C->getCaptureKind() == LCK_StarThis);
15558 continue;
15559 }
15560 // Captured expression will be recaptured during captured variables
15561 // rebuilding.
15562 if (C->capturesVLAType())
15563 continue;
15564
15565 // Rebuild init-captures, including the implied field declaration.
15566 if (E->isInitCapture(Capture: C)) {
15567 TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
15568
15569 auto *OldVD = cast<VarDecl>(C->getCapturedVar());
15570 llvm::SmallVector<Decl*, 4> NewVDs;
15571
15572 for (InitCaptureInfoTy &Info : NewC.Expansions) {
15573 ExprResult Init = Info.first;
15574 QualType InitQualType = Info.second;
15575 if (Init.isInvalid() || InitQualType.isNull()) {
15576 Invalid = true;
15577 break;
15578 }
15579 VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
15580 OldVD->getLocation(), InitQualType, NewC.EllipsisLoc,
15581 OldVD->getIdentifier(), OldVD->getInitStyle(), Init.get(),
15582 getSema().CurContext);
15583 if (!NewVD) {
15584 Invalid = true;
15585 break;
15586 }
15587 NewVDs.push_back(NewVD);
15588 getSema().addInitCapture(LSI, NewVD, C->getCaptureKind() == LCK_ByRef);
15589 // Cases we want to tackle:
15590 // ([C(Pack)] {}, ...)
15591 // But rule out cases e.g.
15592 // [...C = Pack()] {}
15593 if (NewC.EllipsisLoc.isInvalid())
15594 LSI->ContainsUnexpandedParameterPack |=
15595 Init.get()->containsUnexpandedParameterPack();
15596 }
15597
15598 if (Invalid)
15599 break;
15600
15601 getDerived().transformedLocalDecl(OldVD, NewVDs);
15602 continue;
15603 }
15604
15605 assert(C->capturesVariable() && "unexpected kind of lambda capture");
15606
15607 // Determine the capture kind for Sema.
15608 TryCaptureKind Kind = C->isImplicit() ? TryCaptureKind::Implicit
15609 : C->getCaptureKind() == LCK_ByCopy
15610 ? TryCaptureKind::ExplicitByVal
15611 : TryCaptureKind::ExplicitByRef;
15612 SourceLocation EllipsisLoc;
15613 if (C->isPackExpansion()) {
15614 UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
15615 bool ShouldExpand = false;
15616 bool RetainExpansion = false;
15617 UnsignedOrNone NumExpansions = std::nullopt;
15618 if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
15619 C->getLocation(),
15620 Unexpanded,
15621 ShouldExpand, RetainExpansion,
15622 NumExpansions)) {
15623 Invalid = true;
15624 continue;
15625 }
15626
15627 if (ShouldExpand) {
15628 // The transform has determined that we should perform an expansion;
15629 // transform and capture each of the arguments.
15630 // expansion of the pattern. Do so.
15631 auto *Pack = cast<ValueDecl>(C->getCapturedVar());
15632 for (unsigned I = 0; I != *NumExpansions; ++I) {
15633 Sema::ArgPackSubstIndexRAII SubstIndex(getSema(), I);
15634 ValueDecl *CapturedVar = cast_if_present<ValueDecl>(
15635 getDerived().TransformDecl(C->getLocation(), Pack));
15636 if (!CapturedVar) {
15637 Invalid = true;
15638 continue;
15639 }
15640
15641 // Capture the transformed variable.
15642 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind);
15643 }
15644
15645 // FIXME: Retain a pack expansion if RetainExpansion is true.
15646
15647 continue;
15648 }
15649
15650 EllipsisLoc = C->getEllipsisLoc();
15651 }
15652
15653 // Transform the captured variable.
15654 auto *CapturedVar = cast_or_null<ValueDecl>(
15655 getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
15656 if (!CapturedVar || CapturedVar->isInvalidDecl()) {
15657 Invalid = true;
15658 continue;
15659 }
15660
15661 // This is not an init-capture; however it contains an unexpanded pack e.g.
15662 // ([Pack] {}(), ...)
15663 if (auto *VD = dyn_cast<VarDecl>(CapturedVar); VD && !C->isPackExpansion())
15664 LSI->ContainsUnexpandedParameterPack |= VD->isParameterPack();
15665
15666 // Capture the transformed variable.
15667 getSema().tryCaptureVariable(CapturedVar, C->getLocation(), Kind,
15668 EllipsisLoc);
15669 }
15670 getSema().finishLambdaExplicitCaptures(LSI);
15671
15672 // Transform the template parameters, and add them to the current
15673 // instantiation scope. The null case is handled correctly.
15674 auto TPL = getDerived().TransformTemplateParameterList(
15675 E->getTemplateParameterList());
15676 LSI->GLTemplateParameterList = TPL;
15677 if (TPL) {
15678 getSema().AddTemplateParametersToLambdaCallOperator(NewCallOperator, Class,
15679 TPL);
15680 LSI->ContainsUnexpandedParameterPack |=
15681 TPL->containsUnexpandedParameterPack();
15682 }
15683
15684 TypeLocBuilder NewCallOpTLBuilder;
15685 TypeLoc OldCallOpTypeLoc =
15686 E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
15687 QualType NewCallOpType =
15688 getDerived().TransformType(NewCallOpTLBuilder, OldCallOpTypeLoc);
15689 if (NewCallOpType.isNull())
15690 return ExprError();
15691 LSI->ContainsUnexpandedParameterPack |=
15692 NewCallOpType->containsUnexpandedParameterPack();
15693 TypeSourceInfo *NewCallOpTSI =
15694 NewCallOpTLBuilder.getTypeSourceInfo(Context&: getSema().Context, T: NewCallOpType);
15695
15696 // The type may be an AttributedType or some other kind of sugar;
15697 // get the actual underlying FunctionProtoType.
15698 auto FPTL = NewCallOpTSI->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>();
15699 assert(FPTL && "Not a FunctionProtoType?");
15700
15701 AssociatedConstraint TRC = E->getCallOperator()->getTrailingRequiresClause();
15702 if (!TRC.ArgPackSubstIndex)
15703 TRC.ArgPackSubstIndex = SemaRef.ArgPackSubstIndex;
15704
15705 getSema().CompleteLambdaCallOperator(
15706 NewCallOperator, E->getCallOperator()->getLocation(),
15707 E->getCallOperator()->getInnerLocStart(), TRC, NewCallOpTSI,
15708 E->getCallOperator()->getConstexprKind(),
15709 E->getCallOperator()->getStorageClass(), FPTL.getParams(),
15710 E->hasExplicitResultType());
15711
15712 getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
15713 getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
15714
15715 {
15716 // Number the lambda for linkage purposes if necessary.
15717 Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
15718
15719 std::optional<CXXRecordDecl::LambdaNumbering> Numbering;
15720 if (getDerived().ReplacingOriginal()) {
15721 Numbering = OldClass->getLambdaNumbering();
15722 }
15723
15724 getSema().handleLambdaNumbering(Class, NewCallOperator, Numbering);
15725 }
15726
15727 // FIXME: Sema's lambda-building mechanism expects us to push an expression
15728 // evaluation context even if we're not transforming the function body.
15729 getSema().PushExpressionEvaluationContext(
15730 E->getCallOperator()->isConsteval() ?
15731 Sema::ExpressionEvaluationContext::ImmediateFunctionContext :
15732 Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
15733 getSema().currentEvaluationContext().InImmediateEscalatingFunctionContext =
15734 getSema().getLangOpts().CPlusPlus20 &&
15735 E->getCallOperator()->isImmediateEscalating();
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(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>(Pack)) {
16158 ArgStorage = getSema().Context.getPackExpansionType(
16159 getSema().Context.getTypeDeclType(TTPD), std::nullopt);
16160 } else if (auto *TTPD = dyn_cast<TemplateTemplateParmDecl>(Pack)) {
16161 ArgStorage = TemplateArgument(TemplateName(TTPD), std::nullopt);
16162 } else {
16163 auto *VD = cast<ValueDecl>(Pack);
16164 ExprResult DRE = getSema().BuildDeclRefExpr(
16165 VD, VD->getType().getNonLValueExprType(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(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=*/std::nullopt);
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(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(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>(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(E->getEllipsisLoc(),
16409 clang::diag::err_fold_expression_limit_exceeded)
16410 << *NumExpansions << SemaRef.getLangOpts().BracketDepth
16411 << E->getSourceRange();
16412 SemaRef.Diag(E->getEllipsisLoc(), 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(Callee->decls_begin(), 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>(Result.get());
16471 BO && BO->isComparisonOp()) {
16472 WarnedOnComparison = true;
16473 SemaRef.Diag(BO->getBeginLoc(),
16474 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>(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(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(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(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(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&: 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&: 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&: 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(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(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: 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: TypeArgs, TypeArgsRAngleLoc,
17158 ProtocolLAngleLoc, Protocols: 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(SemaRef.Context, numElements, SemaRef.Context.IntTy,
17265 AttributeLoc);
17266 return SemaRef.BuildExtVectorType(ElementType, VectorSize, 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: 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>(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, 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>(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>(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>(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(SemaRef.Context, NumBitsAP,
17425 SemaRef.Context.IntTy, Loc);
17426 return SemaRef.BuildBitIntType(IsUnsigned, 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 std::make_pair(
17627 CD->getParam(i: I)->getName(),
17628 getDerived().TransformType(CD->getParam(i: I)->getType())));
17629 } else {
17630 Params.push_back(std::make_pair(StringRef(), 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

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

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